#
# Makefile.am for psqlodbc (PostgreSQL ODBC driver)
#
-# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.24 2005/09/16 23:05:00 dpage Exp $
+# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.25 2005/09/19 13:31:58 anoop Exp $
#
#-------------------------------------------------------------------------
psqlodbc_la_SOURCES = \
info.c bind.c columninfo.c connection.c convert.c drvconn.c \
- environ.c execute.c lobj.c win_md5.c misc.c options.c \
- pgtypes.c psqlodbc.c qresult.c results.c socket.c parse.c \
+ environ.c execute.c win_md5.c misc.c options.c \
+ pgtypes.c psqlodbc.c qresult.c results.c parse.c \
statement.c tuple.c tuplelist.c dlg_specific.c odbcapi.c \
multibyte.c \
odbcapi30.c pgapi30.c info30.c descriptor.c
psqlodbc_la_SOURCES += \
bind.h columninfo.h connection.h convert.h descriptor.h \
dlg_specific.h environ.h \
- lobj.h libpqconnection.h md5.h misc.h multibyte.h pgapifunc.h pgtypes.h \
- psqlodbc.h qresult.h resource.h socket.h statement.h tuple.h \
+ connection.h md5.h misc.h multibyte.h pgapifunc.h pgtypes.h \
+ psqlodbc.h qresult.h resource.h statement.h tuple.h \
tuplelist.h version.h
if enable_unicode
-psqlodbc_la_SOURCES += \
- odbcapi30w.c odbcapiw.c win_unicode.c
+psqlodbc_la_SOURCES += \
+odbcapi30w.c odbcapiw.c win_unicode.c
endif
EXTRA_psqlodbc_la_SOURCES = md5.c
#define __BIND_H__
#include "psqlodbc.h"
-#ifdef USE_LIBPQ
#include <libpq-fe.h>
-#endif /* USE_LIBPQ */
+
/*
* BindInfoClass -- stores information about a bound column
*/
#include "pgtypes.h"
#include "columninfo.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#include "socket.h"
-#endif /* USE_LIBPQ*/
-
#include <stdlib.h>
#include <string.h>
#include "pgapifunc.h"
free(self);
}
-
-#ifdef USE_LIBPQ
-
-/* Reading Fields part is already done in the mapping part, skipping it while using Libpq */
-char
-CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
-{
- return 'T';
-}
-
-#else
-
-/*
- * Read in field descriptions.
- * If self is not null, then also store the information.
- * If self is null, then just read, don't store.
- */
-char
-CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
-{
- Int2 lf;
- int new_num_fields;
- Oid new_adtid;
- Int2 new_adtsize;
- Int4 new_atttypmod = -1;
-
- /* COLUMN_NAME_STORAGE_LEN may be sufficient but for safety */
- char new_field_name[2 * COLUMN_NAME_STORAGE_LEN + 1];
- SocketClass *sock;
- ConnInfo *ci;
-
- sock = CC_get_socket(conn);
- ci = &conn->connInfo;
-
- /* at first read in the number of fields that are in the query */
- new_num_fields = (Int2) SOCK_get_int(sock, sizeof(Int2));
-
- mylog("num_fields = %d\n", new_num_fields);
-
- if (self)
- /* according to that allocate memory */
- CI_set_num_fields(self, new_num_fields);
-
- /* now read in the descriptions */
- for (lf = 0; lf < new_num_fields; lf++)
- {
- SOCK_get_string(sock, new_field_name, 2 * COLUMN_NAME_STORAGE_LEN);
- new_adtid = (Oid) SOCK_get_int(sock, 4);
- new_adtsize = (Int2) SOCK_get_int(sock, 2);
-
- /* If 6.4 protocol, then read the atttypmod field */
- if (PG_VERSION_GE(conn, 6.4))
- {
- mylog("READING ATTTYPMOD\n");
- new_atttypmod = (Int4) SOCK_get_int(sock, 4);
-
- /* Subtract the header length */
- switch (new_adtid)
- {
- case PG_TYPE_DATETIME:
- case PG_TYPE_TIMESTAMP_NO_TMZONE:
- case PG_TYPE_TIME:
- case PG_TYPE_TIME_WITH_TMZONE:
- break;
- default:
- new_atttypmod -= 4;
- }
- if (new_atttypmod < 0)
- new_atttypmod = -1;
-
- }
-
- mylog("CI_read_fields: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d\n", new_field_name, new_adtid, new_adtsize, new_atttypmod);
-
- if (self)
- CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod);
- }
-
- return (SOCK_get_errcode(sock) == 0);
-}
-
-#endif /* USE_LIBPQ */
-
void
CI_free_memory(ColumnInfoClass *self)
{
#define __COLUMNINFO_H__
#include "psqlodbc.h"
-#ifdef USE_LIBPQ
#include <libpq-fe.h>
-#endif /* USE_LIBPQ */
+
struct ColumnInfoClass_
{
Int2 num_fields;
ColumnInfoClass *CI_Constructor(void);
void CI_Destructor(ColumnInfoClass *self);
void CI_free_memory(ColumnInfoClass *self);
-char CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn);
/* functions for setting up the fields from within the program, */
/* without reading from a socket */
AC_TYPE_SIZE_T\r
AC_STRUCT_TM\r
\r
-#Decide whether libpq or socket based driver to be built \r
-PGAC_ARG_BOOL(with, libpq, yes,\r
- [ --with-libpq build libpq enabled odbc driver(default)],[use_libpq=yes],[use_libpq=no])\r
-\r
+
#\r
#Options for pgsql headers and libraries\r
#\r
-if test "$use_libpq" = "yes"; then\r
- AC_MSG_CHECKING(for pgsql include files)\r
- AC_ARG_WITH(pgsql-include,\r
- [ --with-pgsql-include=DIR Look for postgreSQL include files in DIR],\r
- [if test "$withval" != no; then\r
- AC_MSG_RESULT(yes)\r
- pgsql_include="$withval"\r
- else\r
- AC_MSG_RESULT(no)\r
- AC_MSG_ERROR([you must specify a directory when using --with-pgsql-include=DIR])\r
- fi])\r
-fi\r
+
+AC_MSG_CHECKING(for pgsql include files)\r
+AC_ARG_WITH(pgsql-include,\r
+[ --with-pgsql-include=DIR Look for postgreSQL include files in DIR],\r
+[if test "$withval" != no; then\r
+ AC_MSG_RESULT(yes)\r
+ pgsql_include="$withval"\r
+else\r
+ AC_MSG_RESULT(no)\r
+ AC_MSG_ERROR([you must specify a directory when using --with-pgsql-include=DIR])\r
+fi])\r
\r
#\r
# Library directories\r
#\r
-if test "$use_libpq" = "yes"; then\r
- AC_MSG_CHECKING(for pgsql)\r
- AC_ARG_WITH(pgsql,\r
- [ --with-pgsql=DIR look for PostgreSQL libraries and headers in DIR],\r
- [if test "$withval" != no\r
- then\r
- AC_MSG_RESULT(yes)\r
- LIBPQ_HOME="$withval"\r
- else\r
- AC_MSG_RESULT(no)\r
- fi], [\r
- AC_MSG_RESULT(yes)\r
- LIBPQ_HOME="/usr/local/pgsql"\r
- if test "$pgsql_include" = ""\r
- then\r
- if test ! -f "${LIBPQ_HOME}/include/libpq-fe.h"\r
- then\r
- LIBPQ_HOME=/usr/local\r
- if test ! -f "${LIBPQ_HOME}/include/libpq-fe.h"\r
- then\r
- LIBPQ_HOME=/usr\r
- fi\r
- fi\r
- if test -f "/usr/include/libpq-fe.h"\r
- then\r
- pgsql_include="/usr/include"\r
- else\r
- if test -f "/usr/include/pgsql/libpq-fe.h"\r
- then\r
- pgsql_include="/usr/include/pgsql"\r
- fi\r
- fi\r
- fi\r
+AC_MSG_CHECKING(for pgsql)\r
+AC_ARG_WITH(pgsql,\r
+[ --with-pgsql=DIR look for PostgreSQL libraries and headers in DIR],\r
+[if test "$withval" != no\r
+then\r
+ AC_MSG_RESULT(yes)\r
+ LIBPQ_HOME="$withval"\r
+else\r
+ AC_MSG_RESULT(no)\r
+fi], [\r
+AC_MSG_RESULT(yes)\r
+LIBPQ_HOME="/usr/local/pgsql"\r
+if test "$pgsql_include" = ""\r
+then\r
+ if test ! -f "${LIBPQ_HOME}/include/libpq-fe.h"\r
+ then\r
+ LIBPQ_HOME=/usr/local\r
+ if test ! -f "${LIBPQ_HOME}/include/libpq-fe.h"\r
+ then\r
+ LIBPQ_HOME=/usr\r
+ fi\r
+ fi\r
+ if test -f "/usr/include/libpq-fe.h"\r
+ then\r
+ pgsql_include="/usr/include"\r
+ else\r
+ if test -f "/usr/include/pgsql/libpq-fe.h"\r
+ then\r
+ pgsql_include="/usr/include/pgsql"\r
+ fi\r
+ fi\r
+fi\r
])\r
#\r
# Check for libpq libraries and headers\r
#\r
- if test -n "${LIBPQ_HOME}"\r
- then\r
- OLD_LDFLAGS="$LDFLAGS"\r
- OLD_CPPFLAGS="$CPPFLAGS"\r
- LDFLAGS="$LDFLAGS -L${LIBPQ_HOME}/lib"\r
- AC_CHECK_LIB(pq, PQexec, [pgsql_cv_libpq=yes], [pgsql_cv_libpq=no])\r
-\r
- if test "$pgsql_include" != ""\r
- then\r
- CPPFLAGS="$CPPFLAGS -I${pgsql_include}"\r
- else\r
- CPPFLAGS="$CPPFLAGS -I${LIBPQ_HOME}/include"\r
- fi\r
- AC_CHECK_HEADER(libpq-fe.h, [pgsql_cv_libpqfe_h=yes], [pgsql_cv_libpqfe_h=no])\r
-\r
- if test "$pgsql_cv_libpq" = "yes" -a "$pgsql_cv_libpqfe_h" = "yes"\r
- then\r
- AC_MSG_CHECKING(pgsql in ${LIBPQ_HOME})\r
- AC_MSG_RESULT(ok)\r
- else\r
- AC_MSG_CHECKING(pgsql in ${LIBPQ_HOME})\r
- AC_MSG_RESULT(failed)\r
- LDFLAGS="$OLD_LDFLAGS"\r
- CPPFLAGS="$OLD_CPPFLAGS"\r
- AC_MSG_ERROR([you must specify a valid pgsql installation with --with-pgsql=DIR])\r
- fi\r
- LIBS="$LIBS -lpq"\r
- CPPFLAGS="$CPPFLAGS -DUSE_LIBPQ"\r
+if test -n "${LIBPQ_HOME}"\r
+then\r
+ OLD_LDFLAGS="$LDFLAGS"\r
+ OLD_CPPFLAGS="$CPPFLAGS"\r
+ LDFLAGS="$LDFLAGS -L${LIBPQ_HOME}/lib"\r
+ AC_CHECK_LIB(pq, PQexec, [pgsql_cv_libpq=yes], [pgsql_cv_libpq=no])\r
+\r
+ if test "$pgsql_include" != ""\r
+ then\r
+ CPPFLAGS="$CPPFLAGS -I${pgsql_include}"\r
+ else\r
+ CPPFLAGS="$CPPFLAGS -I${LIBPQ_HOME}/include"\r
+ fi\r
+ AC_CHECK_HEADER(libpq-fe.h, [pgsql_cv_libpqfe_h=yes], [pgsql_cv_libpqfe_h=no])\r
+\r
+ if test "$pgsql_cv_libpq" = "yes" -a "$pgsql_cv_libpqfe_h" = "yes"\r
+ then\r
+ AC_MSG_CHECKING(pgsql in ${LIBPQ_HOME})\r
+ AC_MSG_RESULT(ok)\r
+ else\r
+ AC_MSG_CHECKING(pgsql in ${LIBPQ_HOME})\r
+ AC_MSG_RESULT(failed)\r
+ LDFLAGS="$OLD_LDFLAGS"\r
+ CPPFLAGS="$OLD_CPPFLAGS"\r
+ AC_MSG_ERROR([you must specify a valid pgsql installation with --with-pgsql=DIR])\r
+ fi\r
+ LIBS="$LIBS -lpq"\r
+ CPPFLAGS="$CPPFLAGS "\r
\r
- fi\r
-else\r
- AC_CHECK_LIB(socket, socket)\r
fi\r
\r
AC_CONFIG_FILES([Makefile])\r
#include "environ.h"
#include "statement.h"
#include "qresult.h"
-#include "lobj.h"
#include "dlg_specific.h"
#include "multibyte.h"
extern GLOBAL_VALUES globals;
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
+#include "connection.h"
#include "pgtypes.h"
#include <libpq-fe.h>
-#else
-#include "connection.h"
-#include "socket.h"
-#endif /* USE_LIBPQ */
-
RETCODE SQL_API
PGAPI_AllocConnect(
}
-#ifndef USE_LIBPQ
+static void
+CC_handle_notice(void *arg, const char *msg)
+{
+ QResultClass *qres;
+
+ qres = (QResultClass*)(arg);
+
+ if (qres == NULL)
+ {
+ /* Log the notice to stderr and any logs 'cos */
+ /* there's not much else we can do with it. */
+ fprintf(stderr, "NOTICE from backend outside of a query: '%s'\n", msg);
+ mylog("~~~ NOTICE: '%s'\n", msg);
+ qlog("NOTICE from backend outside of a query: '%s'\n", msg);
+ return;
+ }
+
+ if (QR_command_successful(qres))
+ {
+ QR_set_status(qres, PGRES_NONFATAL_ERROR);
+ QR_set_notice(qres, msg); /* will dup this string */
+ mylog("~~~ NOTICE: '%s'\n", msg);
+ qlog("NOTICE from backend during send_query: '%s'\n", msg);
+ }
+}
+
/*
- * IMPLEMENTATION CONNECTION CLASS
+ * Connection class implementation using libpq.
+ * Memory Allocation for PGconn is handled by libpq.
*/
ConnectionClass *
CC_Constructor()
rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */
CC_conninfo_init(&(rv->connInfo));
- rv->sock = SOCK_Constructor(rv);
- if (!rv->sock)
- return NULL;
-
rv->stmts = (StatementClass **) malloc(sizeof(StatementClass *) * STMT_INCREMENT);
if (!rv->stmts)
+ {
+ free(rv);
return NULL;
+ }
memset(rv->stmts, 0, sizeof(StatementClass *) * STMT_INCREMENT);
rv->num_stmts = STMT_INCREMENT;
rv->descs = (DescriptorClass **) malloc(sizeof(DescriptorClass *) * STMT_INCREMENT);
if (!rv->descs)
+ {
+ free(rv->stmts);
+ free(rv);
return NULL;
+ }
memset(rv->descs, 0, sizeof(DescriptorClass *) * STMT_INCREMENT);
rv->num_descs = STMT_INCREMENT;
if (self->status == CONN_EXECUTING)
return 0;
- CC_cleanup(self); /* cleanup socket and statements */
+ CC_cleanup(self); /* cleanup libpq connection class and statements */
mylog("after CC_Cleanup\n");
return 1;
}
-
/* This is called by SQLDisconnect also */
char
CC_cleanup(ConnectionClass *self)
/* Cancel an ongoing transaction */
/* We are always in the middle of a transaction, */
/* even if we are in auto commit. */
- if (self->sock)
+ if (self->pgconn)
{
CC_abort(self);
mylog("after CC_abort\n");
- /* This actually closes the connection to the dbase */
- SOCK_Destructor(self->sock);
- self->sock = NULL;
+ /* This closes the connection to the database */
+ LIBPQ_Destructor(self->pgconn);
+ self->pgconn = NULL;
}
- mylog("after SOCK destructor\n");
+ mylog("after LIBPQ destructor\n");
/* Free all the stmts on this connection */
for (i = 0; i < self->num_stmts; i++)
return TRUE;
}
-static int
-md5_auth_send(ConnectionClass *self, const char *salt)
-{
- char *pwd1 = NULL, *pwd2 = NULL;
- ConnInfo *ci = &(self->connInfo);
- SocketClass *sock = self->sock;
-
- if (!(pwd1 = malloc(MD5_PASSWD_LEN + 1)))
- return 1;
- if (!EncryptMD5(ci->password, ci->username, strlen(ci->username), pwd1))
- {
- free(pwd1);
- return 1;
- }
- if (!(pwd2 = malloc(MD5_PASSWD_LEN + 1)))
- {
- free(pwd1);
- return 1;
- }
- if (!EncryptMD5(pwd1 + strlen("md5"), salt, 4, pwd2))
- {
- free(pwd2);
- free(pwd1);
- return 1;
- }
- free(pwd1);
- SOCK_put_int(sock, 4 + strlen(pwd2) + 1, 4);
- SOCK_put_n_char(sock, pwd2, strlen(pwd2) + 1);
- SOCK_flush_output(sock);
- free(pwd2);
- return 0;
-}
-
char
CC_connect(ConnectionClass *self, char password_req, char *salt_para)
{
- StartupPacket sp;
- StartupPacket6_2 sp62;
- QResultClass *res;
- SocketClass *sock;
+ /* ignore salt_para for now */
+ /* QResultClass *res; */
+ PGconn *pgconn;
ConnInfo *ci = &(self->connInfo);
- int areq = -1;
- int beresp;
- char msgbuffer[ERROR_MSG_LENGTH];
- char salt[5], notice[512];
- CSTR func = "CC_connect";
+ int areq = -1,connect_return;
char *encoding;
+ /* char *conninfo; */
+ CSTR func = "CC_connect";
mylog("%s: entering...\n", func);
if (password_req != AUTH_REQ_OK)
- sock = self->sock; /* already connected, just authenticate */
+ /* already connected, just authenticate */
+ pgconn = self->pgconn;
else
{
qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d\n",
POSTGRESDRIVERVERSION,
ci->drivers.fetch_max,
- ci->drivers.socket_buffersize,
ci->drivers.unknown_sizes,
ci->drivers.max_varchar_size,
ci->drivers.max_longvarchar_size);
return 0;
}
- mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', sslmode = '%s'"
-#ifdef HAVE_UNIX_SOCKETS
- " uds = '%s',"
-#endif
+ mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', sslmode = '%s',"
" database = '%s', username = '%s',"
" password='%s'\n", ci->dsn, ci->server, ci->port, ci->sslmode,
-#ifdef HAVE_UNIX_SOCKETS
- ci->uds,
-#endif
ci->database, ci->username, ci->password ? "xxxxx" : "");
-another_version_retry:
-
- /*
- * If the socket was closed for some reason (like a SQLDisconnect,
- * but no SQLFreeConnect then create a socket now.
- */
- if (!self->sock)
- {
- self->sock = SOCK_Constructor(self);
- if (!self->sock)
- {
- CC_set_error(self, CONNECTION_SERVER_NOT_REACHED, "Could not open a socket to the server");
- return 0;
- }
- }
-
- sock = self->sock;
-
- mylog("connecting to the server socket...\n");
-
- SOCK_connect_to(sock, (short) atoi(ci->port), ci->server
-#ifdef HAVE_UNIX_SOCKETS
- , ci->uds
-#endif
- );
- if (SOCK_get_errcode(sock) != 0)
- {
- mylog("connection to the server socket failed.\n");
- CC_set_error(self, CONNECTION_SERVER_NOT_REACHED, "Could not connect to the server");
- return 0;
- }
- mylog("connection to the server socket succeeded.\n");
-
- if (PROTOCOL_62(ci))
- {
- sock->reverse = TRUE; /* make put_int and get_int work
- * for 6.2 */
-
- memset(&sp62, 0, sizeof(StartupPacket6_2));
- SOCK_put_int(sock, htonl(4 + sizeof(StartupPacket6_2)), 4);
- sp62.authtype = htonl(NO_AUTHENTICATION);
- strncpy(sp62.database, ci->database, PATH_SIZE);
- strncpy(sp62.user, ci->username, USRNAMEDATALEN);
- SOCK_put_n_char(sock, (char *) &sp62, sizeof(StartupPacket6_2));
- SOCK_flush_output(sock);
- }
- else
- {
- memset(&sp, 0, sizeof(StartupPacket));
-
- mylog("sizeof startup packet = %d\n", sizeof(StartupPacket));
-
- /* Send length of Authentication Block */
- SOCK_put_int(sock, 4 + sizeof(StartupPacket), 4);
-
- if (PROTOCOL_63(ci))
- sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_63);
- else
- sp.protoVersion = (ProtocolVersion) htonl(PG_PROTOCOL_LATEST);
- strncpy(sp.database, ci->database, SM_DATABASE);
- strncpy(sp.user, ci->username, SM_USER);
-
- SOCK_put_n_char(sock, (char *) &sp, sizeof(StartupPacket));
- SOCK_flush_output(sock);
- }
-
- mylog("sent the authentication block.\n");
+ mylog("connecting to the server \n");
- if (sock->errornumber != 0)
+ connect_return = LIBPQ_connect(self);
+ if(0 == connect_return)
{
- mylog("couldn't send the authentication block properly.\n");
- CC_set_error(self, CONN_INVALID_AUTHENTICATION, "Sending the authentication packet failed");
+ CC_set_error(self, CONNECTION_COULD_NOT_ESTABLISH, "Could not connect to the server");
return 0;
}
- mylog("sent the authentication block successfully.\n");
- }
+ mylog("connection to the database succeeded.\n");
- mylog("gonna do authentication\n");
-
-
- /*
- * Now get the authentication request from backend
- */
-
- if (!PROTOCOL_62(ci))
- {
- BOOL before_64 = PG_VERSION_LT(self, 6.4),
- ReadyForQuery = FALSE;
-
- do
- {
- if (password_req != AUTH_REQ_OK)
- beresp = 'R';
- else
- {
- beresp = SOCK_get_char(sock);
- mylog("auth got '%c'\n", beresp);
- }
-
- switch (beresp)
- {
- case 'E':
-
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- CC_set_error(self, CONN_INVALID_AUTHENTICATION, msgbuffer);
- qlog("ERROR from backend during authentication: '%s'\n", msgbuffer);
- if (strncmp(msgbuffer, "Unsupported frontend protocol", 29) == 0)
- { /* retry older version */
- if (PROTOCOL_63(ci))
- strcpy(ci->protocol, PG62);
- else
- strcpy(ci->protocol, PG63);
- SOCK_Destructor(sock);
- self->sock = (SocketClass *) 0;
- CC_initialize_pg_version(self);
- goto another_version_retry;
- }
-
- return 0;
- case 'R':
-
- if (password_req != AUTH_REQ_OK)
- {
- mylog("in 'R' password_req=%s\n", ci->password);
- areq = password_req;
- if (salt_para)
- memcpy(salt, salt_para, sizeof(salt));
- password_req = AUTH_REQ_OK;
- }
- else
- {
-
- areq = SOCK_get_int(sock, 4);
- if (areq == AUTH_REQ_MD5)
- SOCK_get_n_char(sock, salt, 4);
- else if (areq == AUTH_REQ_CRYPT)
- SOCK_get_n_char(sock, salt, 2);
-
- mylog("areq = %d\n", areq);
- }
- switch (areq)
- {
- case AUTH_REQ_OK:
- break;
-
- case AUTH_REQ_KRB4:
- CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Kerberos 4 authentication not supported");
- return 0;
-
- case AUTH_REQ_KRB5:
- CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Kerberos 5 authentication not supported");
- return 0;
-
- case AUTH_REQ_PASSWORD:
- mylog("in AUTH_REQ_PASSWORD\n");
-
- if (ci->password[0] == '\0')
- {
- CC_set_error(self, CONNECTION_NEED_PASSWORD, "A password is required for this connection.");
- return -areq; /* need password */
- }
-
- mylog("past need password\n");
-
- SOCK_put_int(sock, 4 + strlen(ci->password) + 1, 4);
- SOCK_put_n_char(sock, ci->password, strlen(ci->password) + 1);
- SOCK_flush_output(sock);
-
- mylog("past flush\n");
- break;
-
- case AUTH_REQ_CRYPT:
- CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Password crypt authentication not supported");
- return 0;
- case AUTH_REQ_MD5:
- mylog("in AUTH_REQ_MD5\n");
- if (ci->password[0] == '\0')
- {
- CC_set_error(self, CONNECTION_NEED_PASSWORD, "A password is required for this connection.");
- if (salt_para)
- memcpy(salt_para, salt, sizeof(salt));
- return -areq; /* need password */
- }
- if (md5_auth_send(self, salt))
- {
- CC_set_error(self, CONN_INVALID_AUTHENTICATION, "md5 hashing failed");
- return 0;
- }
- break;
-
- case AUTH_REQ_SCM_CREDS:
- CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Unix socket credential authentication not supported");
- return 0;
-
- default:
- CC_set_error(self, CONN_AUTH_TYPE_UNSUPPORTED, "Unknown authentication type");
- return 0;
- }
- break;
- case 'K': /* Secret key (6.4 protocol) */
- self->be_pid = SOCK_get_int(sock, 4); /* pid */
- self->be_key = SOCK_get_int(sock, 4); /* key */
-
- break;
- case 'Z': /* Backend is ready for new query (6.4) */
- ReadyForQuery = TRUE;
- break;
- case 'N': /* Notices may come */
- while (SOCK_get_string(sock, notice, sizeof(notice) - 1)) ;
- break;
- default:
- CC_set_error(self, CONN_INVALID_AUTHENTICATION, "Unexpected protocol character during authentication");
- return 0;
- }
-
- /*
- * There were no ReadyForQuery responce before 6.4.
- */
- if (before_64 && areq == AUTH_REQ_OK)
- ReadyForQuery = TRUE;
- } while (!ReadyForQuery);
}
-
CC_clear_error(self); /* clear any password error */
- /*
- * send an empty query in order to find out whether the specified
- * database really exists on the server machine
- */
- mylog("sending an empty query...\n");
-
- res = CC_send_query(self, " ", NULL, CLEAR_RESULT_ON_ABORT);
- if (res == NULL ||
- (QR_get_status(res) != PGRES_EMPTY_QUERY &&
- QR_command_nonfatal(res)))
- {
- mylog("got no result from the empty query. (probably database does not exist)\n");
- CC_set_error(self, CONNECTION_NO_SUCH_DATABASE, "The database does not exist on the server\nor user authentication failed.");
- if (res != NULL)
- QR_Destructor(res);
- return 0;
- }
- if (res)
- QR_Destructor(res);
-
- mylog("empty query seems to be OK.\n");
-
CC_set_translation(self);
/*
* Send any initial settings
*/
- /*
+ /*
* Get the version number first so we can check it before sending options
* that are now obsolete. DJP 21/06/2002
*/
if (self->unicode)
{
if (!self->client_encoding ||
- !stricmp(self->client_encoding, "UNICODE"))
+ stricmp(self->client_encoding, "UNICODE"))
{
QResultClass *res;
if (PG_VERSION_LT(self, 7.1))
if (self->client_encoding)
free(self->client_encoding);
self->client_encoding = NULL;
- if (res = CC_send_query(self, "set client_encoding to 'UTF8'", NULL, CLEAR_RESULT_ON_ABORT), res)
+ res = LIBPQ_execute_query(self,"set client_encoding to 'UTF8'");
+ if (res)
{
self->client_encoding = strdup("UNICODE");
self->ccsc = pg_CS_code(self->client_encoding);
QR_Destructor(res);
-
+
}
}
}
/*
* Create a more informative error message by concatenating the connection
- * error message with its socket error message.
+ * error message with its libpq error message.
*/
char *
CC_create_errormsg(ConnectionClass *self)
{
- SocketClass *sock = self->sock;
- int pos;
+ PGconn *pgconn = self->pgconn;
char msg[4096];
mylog("enter CC_create_errormsg\n");
mylog("msg = '%s'\n", msg);
- if (sock && sock->errormsg && sock->errormsg[0] != '\0')
- {
- pos = strlen(msg);
- sprintf(&msg[pos], ";\n%s", sock->errormsg);
- }
-
mylog("exit CC_create_errormsg\n");
return msg ? strdup(msg) : NULL;
}
+
void CC_on_abort(ConnectionClass *conn, UDWORD opt)
{
BOOL set_no_trans = FALSE;
if (0 != (opt & CONN_DEAD))
{
conn->status = CONN_DOWN;
- if (conn->sock)
+ if (conn->pgconn)
{
- SOCK_Destructor(conn->sock);
- conn->sock = NULL;
+ LIBPQ_Destructor(conn->pgconn);
+ conn->pgconn = NULL;
}
}
else if (set_no_trans)
{
QResultClass *cmdres = NULL,
*retres = NULL,
- *res = NULL;
+ *res ;
BOOL clear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0),
create_keyset = ((flag & CREATE_KEYSET) != 0),
issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self));
- char swallow, *wq, *ptr;
- int id;
- SocketClass *sock = self->sock;
+ char *wq;
+ int id=0;
+ PGconn *pgconn = self->pgconn;
int maxlen,
empty_reqs;
- BOOL msg_truncated,
- ReadyToReturn = FALSE,
+ BOOL ReadyToReturn = FALSE,
query_completed = FALSE,
before_64 = PG_VERSION_LT(self, 6.4),
aborted = FALSE,
used_passed_result_object = FALSE;
- UDWORD abort_opt;
int func_cs_count = 0;
- /* ERROR_MSG_LENGTH is suffcient */
- char msgbuffer[ERROR_MSG_LENGTH + 1];
-
- /* QR_set_command() dups this string so doesn't need static */
- char cmdbuffer[ERROR_MSG_LENGTH + 1];
mylog("send_query(): conn=%u, query='%s'\n", self, query);
qlog("conn=%u, query='%s'\n", self, query);
- if (!self->sock)
+ if (!self->pgconn)
{
CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query(connection dead)");
CC_on_abort(self, NO_TRANS);
return NULL;
}
-
/* Indicate that we are sending a query to the backend */
maxlen = CC_get_max_query_len(self);
if (maxlen > 0 && maxlen < (int) strlen(query) + 1)
if ((NULL == query) || (query[0] == '\0'))
return NULL;
- if (SOCK_get_errcode(sock) != 0)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
- return NULL;
- }
-
#define return DONT_CALL_RETURN_FROM_HERE???
ENTER_INNER_CONN_CS(self, func_cs_count);
- SOCK_put_char(sock, 'Q');
- if (SOCK_get_errcode(sock) != 0)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
- goto cleanup;
- }
if (issue_begin)
- SOCK_put_n_char(sock, "BEGIN;", 6);
- SOCK_put_string(sock, query);
- SOCK_flush_output(sock);
+ {
+ res = LIBPQ_execute_query(self,"BEGIN");
+ QR_Destructor(res);
+ }
+
+ res = LIBPQ_execute_query(self,query);
- if (SOCK_get_errcode(sock) != 0)
+ if((!res) || (res->status == PGRES_EMPTY_QUERY) )
{
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
+ QR_Destructor(res);
+ res = NULL;
goto cleanup;
}
-
- mylog("send_query: done sending query\n");
-
- empty_reqs = 0;
- for (wq = query; isspace((UCHAR) *wq); wq++)
- ;
- if (*wq == '\0')
- empty_reqs = 1;
- cmdres = qi ? qi->result_in : NULL;
- if (cmdres)
- used_passed_result_object = TRUE;
else
{
- cmdres = QR_Constructor();
- if (!cmdres)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not create result info in send_query.");
- goto cleanup;
- }
- }
- res = cmdres;
- while (!ReadyToReturn)
- {
- /* what type of message is coming now ? */
- id = SOCK_get_char(sock);
+ mylog("send_query: done sending query\n");
- if ((SOCK_get_errcode(sock) != 0) || (id == EOF))
+ empty_reqs = 0;
+ for (wq = query; isspace((UCHAR) *wq); wq++)
+ ;
+ if (*wq == '\0')
+ empty_reqs = 1;
+ cmdres = qi ? qi->result_in : NULL;
+ if (cmdres)
+ used_passed_result_object = TRUE;
+ if (!used_passed_result_object)
{
- CC_set_error(self, CONNECTION_NO_RESPONSE, "No response from the backend");
-
- mylog("send_query: 'id' - %s\n", CC_get_errormsg(self));
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
- ReadyToReturn = TRUE;
- retres = NULL;
- break;
+ if (create_keyset)
+ QR_set_haskeyset(res->next);
+ if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL))
+ {
+ CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res));
+ if (PGRES_FATAL_ERROR == QR_get_status(res))
+ retres = cmdres;
+ else
+ retres = NULL;
+ }
}
+ else
+ { /* next fetch, so reuse an existing result */
+ /*
+ * called from QR_next_tuple and must return
+ * immediately.
+ */
+ if (!QR_fetch_tuples(res, NULL, NULL))
+ {
+ CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res));
+ retres = NULL;
+ }
+ retres = cmdres;
+ }
+ }
- mylog("send_query: got id = '%c'\n", id);
-
- switch (id)
+cleanup:
+ CLEANUP_FUNC_CONN_CS(func_cs_count, self);
+ /*
+ * Cleanup garbage results before returning.
+ */
+ if (cmdres && retres != cmdres && !used_passed_result_object)
+ {
+ QR_Destructor(cmdres);
+ }
+ /*
+ * Cleanup the aborted result if specified
+ */
+ if (retres)
+ {
+ if (aborted)
{
- case 'A': /* Asynchronous Messages are ignored */
- (void) SOCK_get_int(sock, 4); /* id of notification */
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- /* name of the relation the message comes from */
- break;
- case 'C': /* portal query command, no tuples
- * returned */
- /* read in the return message from the backend */
- SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- if (SOCK_get_errcode(sock) != 0)
+ if (clear_result_on_abort)
+ {
+ if (!used_passed_result_object)
{
- CC_set_error(self, CONNECTION_NO_RESPONSE, "No response from backend while receiving a portal query command");
- mylog("send_query: 'C' - %s\n", CC_get_errormsg(self));
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
- ReadyToReturn = TRUE;
+ QR_Destructor(retres);
retres = NULL;
}
- else
+ }
+ if (retres)
+ {
+ /*
+ * discard results other than errors.
+ */
+ QResultClass *qres;
+ for (qres = retres; qres->next; qres = retres)
{
- mylog("send_query: ok - 'C' - %s\n", cmdbuffer);
-
- if (query_completed) /* allow for "show" style notices */
- {
- res->next = QR_Constructor();
- res = res->next;
- }
-
- mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer);
-
- if (strnicmp(cmdbuffer, "BEGIN", 5) == 0)
- {
- CC_set_in_trans(self);
- if (issue_begin)
- {
- issue_begin = FALSE;
- continue;
- }
- }
- else if (strnicmp(cmdbuffer, "COMMIT", 6) == 0)
- CC_on_commit(self);
- else if (strnicmp(cmdbuffer, "ROLLBACK", 8) == 0)
- {
- /*
- The method of ROLLBACK an original form ....
- ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name
- */
- if (PG_VERSION_LT(self, 8.0) || !(contains_token(query, " TO ")))
- CC_on_abort(self, NO_TRANS);
- }
- else if (strnicmp(cmdbuffer, "END", 3) == 0)
- CC_on_commit(self);
- else if (strnicmp(cmdbuffer, "ABORT", 5) == 0)
- CC_on_abort(self, NO_TRANS);
- else
- {
- trim(cmdbuffer); /* get rid of trailing space */
- ptr = strrchr(cmdbuffer, ' ');
- if (ptr)
- res->recent_processed_row_count = atoi(ptr + 1);
- else
- res->recent_processed_row_count = -1;
- }
-
- if (QR_command_successful(res))
- QR_set_status(res, PGRES_COMMAND_OK);
- QR_set_command(res, cmdbuffer);
- query_completed = TRUE;
- mylog("send_query: returning res = %u\n", res);
- if (!before_64)
+ if (QR_get_aborted(qres))
break;
-
- /*
- * (Quotation from the original comments) since
- * backend may produce more than one result for some
- * commands we need to poll until clear so we send an
- * empty query, and keep reading out of the pipe until
- * an 'I' is received
- */
-
- if (empty_reqs == 0)
- {
- SOCK_put_string(sock, "Q ");
- SOCK_flush_output(sock);
- empty_reqs++;
- }
- }
- break;
- case 'Z': /* Backend is ready for new query (6.4) */
- if (empty_reqs == 0)
- {
- ReadyToReturn = TRUE;
- if (aborted || query_completed)
- retres = cmdres;
- else
- ReadyToReturn = FALSE;
- }
- break;
- case 'N': /* NOTICE: */
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- if (QR_command_successful(res))
- QR_set_status(res, PGRES_NONFATAL_ERROR);
- QR_set_notice(res, cmdbuffer); /* will dup this string */
- mylog("~~~ NOTICE: '%s'\n", cmdbuffer);
- qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer);
- while (msg_truncated)
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
-
- continue; /* dont return a result -- continue
- * reading */
-
- case 'I': /* The server sends an empty query */
- /* There is a closing '\0' following the 'I', so we eat it */
- swallow = SOCK_get_char(sock);
- if ((swallow != '\0') || SOCK_get_errcode(sock) != 0)
- {
- CC_set_errornumber(self, CONNECTION_BACKEND_CRAZY);
- QR_set_message(res, "Unexpected protocol character from backend (send_query - I)");
- QR_set_status(res, PGRES_FATAL_ERROR);
- ReadyToReturn = TRUE;
- retres = cmdres;
- break;
- }
- else
- {
- /* We return the empty query */
- QR_set_status(res, PGRES_EMPTY_QUERY);
- }
- if (empty_reqs > 0)
- {
- if (--empty_reqs == 0)
- query_completed = TRUE;
- }
- break;
- case 'E':
- msg_truncated = SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
-
- /* Remove a newline */
- if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n')
- msgbuffer[strlen(msgbuffer) - 1] = '\0';
-
-
- mylog("send_query: 'E' - %s\n", msgbuffer);
- qlog("ERROR from backend during send_query: '%s'\n", msgbuffer);
-
- /* We should report that an error occured. Zoltan */
- abort_opt = 0;
- if (!strncmp(msgbuffer, "FATAL", 5))
- {
- CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_ERROR);
- abort_opt = NO_TRANS | CONN_DEAD;
- ReadyToReturn = TRUE;
- retres = NULL;
- }
- else
- {
- CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_WARNING);
- if (CC_is_in_trans(self))
- CC_set_in_error_trans(self);
- }
- CC_on_abort(self, abort_opt);
- QR_set_status(res, PGRES_FATAL_ERROR);
- QR_set_message(res, msgbuffer);
- QR_set_aborted(res, TRUE);
- aborted = TRUE;
- while (msg_truncated)
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
-
- query_completed = TRUE;
- break;
-
- case 'P': /* get the Portal name */
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- break;
- case 'T': /* Tuple results start here */
- if (query_completed)
- {
- res->next = QR_Constructor();
- if (!res->next)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not create result info in send_query.");
- ReadyToReturn = TRUE;
- retres = NULL;
- break;
- }
- if (create_keyset)
- QR_set_haskeyset(res->next);
- mylog("send_query: 'T' no result_in: res = %u\n", res->next);
- res = res->next;
-
- if (qi)
- QR_set_cache_size(res, qi->row_size);
- }
- if (!used_passed_result_object)
- {
- if (create_keyset)
- QR_set_haskeyset(res);
- if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL))
- {
- CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res));
- ReadyToReturn = TRUE;
- if (PGRES_FATAL_ERROR == QR_get_status(res))
- retres = cmdres;
- else
- retres = NULL;
- break;
- }
- query_completed = TRUE;
- }
- else
- { /* next fetch, so reuse an existing result */
-
- /*
- * called from QR_next_tuple and must return
- * immediately.
- */
- ReadyToReturn = TRUE;
- if (!QR_fetch_tuples(res, NULL, NULL))
- {
- CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res));
- retres = NULL;
- break;
- }
- retres = cmdres;
- }
- break;
- case 'D': /* Copy in command began successfully */
- if (query_completed)
- {
- res->next = QR_Constructor();
- res = res->next;
- }
- QR_set_status(res, PGRES_COPY_IN);
- ReadyToReturn = TRUE;
- retres = cmdres;
- break;
- case 'B': /* Copy out command began successfully */
- if (query_completed)
- {
- res->next = QR_Constructor();
- res = res->next;
- }
- QR_set_status(res, PGRES_COPY_OUT);
- ReadyToReturn = TRUE;
- retres = cmdres;
- break;
- default:
- CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_query)");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
-
- mylog("send_query: error - %s\n", CC_get_errormsg(self));
- ReadyToReturn = TRUE;
- retres = NULL;
- break;
- }
-
- /*
- * There were no ReadyForQuery response before 6.4.
- */
- if (before_64)
- {
- if (empty_reqs == 0 && query_completed)
- break;
- }
- }
-
-cleanup:
- CLEANUP_FUNC_CONN_CS(func_cs_count, self);
- /*
- * Break before being ready to return.
- */
- if (!ReadyToReturn)
- retres = cmdres;
-
- /*
- * Cleanup garbage results before returning.
- */
- if (cmdres && retres != cmdres && !used_passed_result_object)
- QR_Destructor(cmdres);
- /*
- * Cleanup the aborted result if specified
- */
- if (retres)
- {
- if (aborted)
- {
- if (clear_result_on_abort)
- {
- if (!used_passed_result_object)
- {
- QR_Destructor(retres);
- retres = NULL;
- }
- }
- if (retres)
- {
- /*
- * discard results other than errors.
- */
- QResultClass *qres;
- for (qres = retres; qres->next; qres = retres)
- {
- if (QR_get_aborted(qres))
- break;
- retres = qres->next;
- qres->next = NULL;
- QR_Destructor(qres);
- }
- /*
- * If error message isn't set
- */
- if (retres && (!CC_get_errormsg(self) || !CC_get_errormsg(self)[0]))
- CC_set_errormsg(self, QR_get_message(retres));
- }
- }
- }
-#undef return
- return retres;
-}
-
-
-int
-CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *args, int nargs)
-{
- char id,
- c,
- done;
- SocketClass *sock = self->sock;
-
- /* ERROR_MSG_LENGTH is sufficient */
- char msgbuffer[ERROR_MSG_LENGTH + 1];
- int i;
-
- mylog("send_function(): conn=%u, fnid=%d, result_is_int=%d, nargs=%d\n", self, fnid, result_is_int, nargs);
-
- if (!self->sock)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send function(connection dead)");
- CC_on_abort(self, NO_TRANS);
- return FALSE;
- }
-
- if (SOCK_get_errcode(sock) != 0)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send function to backend");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
- return FALSE;
- }
-
- SOCK_put_string(sock, "F ");
- if (SOCK_get_errcode(sock) != 0)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send function to backend");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
- return FALSE;
- }
-
- SOCK_put_int(sock, fnid, 4);
- SOCK_put_int(sock, nargs, 4);
-
-
- mylog("send_function: done sending function\n");
-
- for (i = 0; i < nargs; ++i)
- {
- mylog(" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u\n", i, args[i].len, args[i].isint, args[i].u.integer, args[i].u.ptr);
-
- SOCK_put_int(sock, args[i].len, 4);
- if (args[i].isint)
- SOCK_put_int(sock, args[i].u.integer, 4);
- else
- SOCK_put_n_char(sock, (char *) args[i].u.ptr, args[i].len);
-
-
- }
-
- mylog(" done sending args\n");
-
- SOCK_flush_output(sock);
- mylog(" after flush output\n");
-
- done = FALSE;
- while (!done)
- {
- id = SOCK_get_char(sock);
- mylog(" got id = %c\n", id);
-
- switch (id)
- {
- case 'V':
- done = TRUE;
- break; /* ok */
-
- case 'N':
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- mylog("send_function(V): 'N' - %s\n", msgbuffer);
- /* continue reading */
- break;
-
- case 'E':
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- CC_set_errormsg(self, msgbuffer);
- if (CC_is_in_trans(self))
- CC_set_in_error_trans(self);
- CC_on_abort(self, 0);
-
- mylog("send_function(V): 'E' - %s\n", CC_get_errormsg(self));
- qlog("ERROR from backend during send_function: '%s'\n", CC_get_errormsg(self));
-
- return FALSE;
-
- case 'Z':
- break;
-
- default:
- CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_function, args)");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
-
- mylog("send_function: error - %s\n", CC_get_errormsg(self));
- return FALSE;
- }
- }
-
- id = SOCK_get_char(sock);
- for (;;)
- {
- switch (id)
- {
- case 'G': /* function returned properly */
- mylog(" got G!\n");
-
- *actual_result_len = SOCK_get_int(sock, 4);
- mylog(" actual_result_len = %d\n", *actual_result_len);
-
- if (result_is_int)
- *((int *) result_buf) = SOCK_get_int(sock, 4);
- else
- SOCK_get_n_char(sock, (char *) result_buf, *actual_result_len);
-
- mylog(" after get result\n");
-
- c = SOCK_get_char(sock); /* get the last '0' */
-
- mylog(" after get 0\n");
-
- return TRUE;
-
- case 'E':
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- CC_set_errormsg(self, msgbuffer);
- CC_on_abort(self, 0);
- mylog("send_function(G): 'E' - %s\n", CC_get_errormsg(self));
- qlog("ERROR from backend during send_function: '%s'\n", CC_get_errormsg(self));
-
- return FALSE;
-
- case 'N':
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
-
- mylog("send_function(G): 'N' - %s\n", msgbuffer);
- qlog("NOTICE from backend during send_function: '%s'\n", msgbuffer);
-
- continue; /* dont return a result -- continue
- * reading */
-
- case '0': /* empty result */
- return TRUE;
-
- default:
- CC_set_error(self, CONNECTION_BACKEND_CRAZY, "Unexpected protocol character from backend (send_function, result)");
- CC_on_abort(self, NO_TRANS | CONN_DEAD);
-
- mylog("send_function: error - %s\n", CC_get_errormsg(self));
- return FALSE;
- }
- }
-}
-
-void
-CC_log_error(const char *func, const char *desc, const ConnectionClass *self)
-{
-#ifdef PRN_NULLCHECK
-#define nullcheck(a) (a ? a : "(NULL)")
-#endif
-
- if (self)
- {
- qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message));
- mylog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message));
- qlog(" ------------------------------------------------------------\n");
- qlog(" henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts);
- qlog(" sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type);
-
- qlog(" ---------------- Socket Info -------------------------------\n");
- if (self->sock)
- {
- SocketClass *sock = self->sock;
-
- qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, nullcheck(sock->errormsg));
- qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out);
- qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in);
- }
- }
- else
-{
- qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
- mylog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
-}
-#undef PRN_NULLCHECK
-}
-
-
-int
-CC_send_cancel_request(const ConnectionClass *conn)
-{
- int save_errno = SOCK_ERRNO;
- int tmpsock = -1;
- struct
- {
- uint32 packetlen;
- CancelRequestPacket cp;
- } crp;
- BOOL ret = TRUE;
-
- /* Check we have an open connection */
- if (!conn || !conn->sock)
- return FALSE;
-
- /*
- * We need to open a temporary connection to the postmaster. Use the
- * information saved by connectDB to do this with only kernel calls.
- */
- if ((tmpsock = socket(conn->sock->sadr->sa_family, SOCK_STREAM, 0)) < 0)
- {
- return FALSE;
- }
- if (connect(tmpsock, conn->sock->sadr, conn->sock->sadr_len) < 0)
- {
- closesocket(tmpsock);
- return FALSE;
- }
-
- /*
- * We needn't set nonblocking I/O or NODELAY options here.
- */
- crp.packetlen = htonl((uint32) sizeof(crp));
- crp.cp.cancelRequestCode = (MsgType) htonl(CANCEL_REQUEST_CODE);
- crp.cp.backendPID = htonl(conn->be_pid);
- crp.cp.cancelAuthCode = htonl(conn->be_key);
-
- if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
- {
- save_errno = SOCK_ERRNO;
- ret = FALSE;
- }
-
- /* Sent it, done */
- closesocket(tmpsock);
- SOCK_ERRNO_SET(save_errno);
-
- return ret;
-}
-
-#else
-
-static void
-CC_handle_notice(void *arg, const char *msg)
-{
- QResultClass *qres;
-
- qres = (QResultClass*)(arg);
-
- if (qres == NULL)
- {
- /* Log the notice to stderr and any logs 'cos */
- /* there's not much else we can do with it. */
- fprintf(stderr, "NOTICE from backend outside of a query: '%s'\n", msg);
- mylog("~~~ NOTICE: '%s'\n", msg);
- qlog("NOTICE from backend outside of a query: '%s'\n", msg);
- return;
- }
-
- if (QR_command_successful(qres))
- {
- QR_set_status(qres, PGRES_NONFATAL_ERROR);
- QR_set_notice(qres, msg); /* will dup this string */
- mylog("~~~ NOTICE: '%s'\n", msg);
- qlog("NOTICE from backend during send_query: '%s'\n", msg);
- }
-}
-
-/*
- * Connection class implementation using libpq.
- * Memory Allocation for PGconn is handled by libpq.
- */
-ConnectionClass *
-CC_Constructor()
-{
- ConnectionClass *rv;
-
- rv = (ConnectionClass *) malloc(sizeof(ConnectionClass));
-
- if (rv != NULL)
- {
- rv->henv = NULL; /* not yet associated with an environment */
-
- rv->__error_message = NULL;
- rv->__error_number = 0;
- rv->errormsg_created = FALSE;
-
- rv->status = CONN_NOT_CONNECTED;
- rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */
-
- CC_conninfo_init(&(rv->connInfo));
- rv->stmts = (StatementClass **) malloc(sizeof(StatementClass *) * STMT_INCREMENT);
- if (!rv->stmts)
- {
- free(rv);
- return NULL;
- }
- memset(rv->stmts, 0, sizeof(StatementClass *) * STMT_INCREMENT);
-
- rv->num_stmts = STMT_INCREMENT;
- rv->descs = (DescriptorClass **) malloc(sizeof(DescriptorClass *) * STMT_INCREMENT);
- if (!rv->descs)
- {
- free(rv->stmts);
- free(rv);
- return NULL;
- }
- memset(rv->descs, 0, sizeof(DescriptorClass *) * STMT_INCREMENT);
-
- rv->num_descs = STMT_INCREMENT;
-
- rv->lobj_type = PG_TYPE_LO_UNDEFINED;
-
- rv->ntables = 0;
- rv->col_info = NULL;
-
- rv->translation_option = 0;
- rv->translation_handle = NULL;
- rv->DataSourceToDriver = NULL;
- rv->DriverToDataSource = NULL;
- rv->driver_version = ODBCVER;
- memset(rv->pg_version, 0, sizeof(rv->pg_version));
- rv->pg_version_number = .0;
- rv->pg_version_major = 0;
- rv->pg_version_minor = 0;
- rv->ms_jet = 0;
- rv->unicode = 0;
- rv->result_uncommitted = 0;
- rv->schema_support = 0;
- rv->isolation = SQL_TXN_READ_COMMITTED;
- rv->client_encoding = NULL;
- rv->server_encoding = NULL;
- rv->current_schema = NULL;
- rv->num_discardp = 0;
- rv->discardp = NULL;
-
- /* Initialize statement options to defaults */
- /* Statements under this conn will inherit these options */
-
- InitializeStatementOptions(&rv->stmtOptions);
- InitializeARDFields(&rv->ardOptions);
- InitializeAPDFields(&rv->apdOptions);
- INIT_CONN_CS(rv);
- }
- return rv;
-}
-
-
-char
-CC_Destructor(ConnectionClass *self)
-{
- mylog("enter CC_Destructor, self=%u\n", self);
-
- if (self->status == CONN_EXECUTING)
- return 0;
-
- CC_cleanup(self); /* cleanup libpq connection class and statements */
-
- mylog("after CC_Cleanup\n");
-
- /* Free up statement holders */
- if (self->stmts)
- {
- free(self->stmts);
- self->stmts = NULL;
- }
-
- if (self->descs)
- {
- free(self->descs);
- self->descs = NULL;
- }
-
- mylog("after free statement holders\n");
-
- if (self->__error_message)
- free(self->__error_message);
- DELETE_CONN_CS(self);
- free(self);
-
- mylog("exit CC_Destructor\n");
-
- return 1;
-}
-
-/* This is called by SQLDisconnect also */
-char
-CC_cleanup(ConnectionClass *self)
-{
- int i;
- StatementClass *stmt;
- DescriptorClass *desc;
-
- if (self->status == CONN_EXECUTING)
- return FALSE;
-
- mylog("in CC_Cleanup, self=%u\n", self);
-
- /* Cancel an ongoing transaction */
- /* We are always in the middle of a transaction, */
- /* even if we are in auto commit. */
- if (self->pgconn)
- {
- CC_abort(self);
-
- mylog("after CC_abort\n");
-
- /* This closes the connection to the database */
- LIBPQ_Destructor(self->pgconn);
- self->pgconn = NULL;
- }
-
- mylog("after LIBPQ destructor\n");
-
- /* Free all the stmts on this connection */
- for (i = 0; i < self->num_stmts; i++)
- {
- stmt = self->stmts[i];
- if (stmt)
- {
- stmt->hdbc = NULL; /* prevent any more dbase interactions */
-
- SC_Destructor(stmt);
-
- self->stmts[i] = NULL;
- }
- }
-
- /* Free all the descs on this connection */
- for (i = 0; i < self->num_descs; i++)
- {
- desc = self->descs[i];
- if (desc)
- {
- DC_get_conn(desc) = NULL; /* prevent any more dbase interactions */
- DC_Destructor(desc);
- free(desc);
- self->descs[i] = NULL;
- }
- }
-
- /* Check for translation dll */
-#ifdef WIN32
- if (self->translation_handle)
- {
- FreeLibrary(self->translation_handle);
- self->translation_handle = NULL;
- }
-#endif
-
- self->status = CONN_NOT_CONNECTED;
- self->transact_status = CONN_IN_AUTOCOMMIT;
- CC_conninfo_init(&(self->connInfo));
- if (self->client_encoding)
- {
- free(self->client_encoding);
- self->client_encoding = NULL;
- }
- if (self->server_encoding)
- {
- free(self->server_encoding);
- self->server_encoding = NULL;
- }
- if (self->current_schema)
- {
- free(self->current_schema);
- self->current_schema = NULL;
- }
- /* Free cached table info */
- if (self->col_info)
- {
- for (i = 0; i < self->ntables; i++)
- {
- if (self->col_info[i]->result) /* Free the SQLColumns result structure */
- QR_Destructor(self->col_info[i]->result);
-
- if (self->col_info[i]->schema)
- free(self->col_info[i]->schema);
- free(self->col_info[i]);
- }
- free(self->col_info);
- self->col_info = NULL;
- }
- self->ntables = 0;
- if (self->num_discardp > 0 && self->discardp)
- {
- for (i = 0; i < self->num_discardp; i++)
- free(self->discardp[i]);
- self->num_discardp = 0;
- }
- if (self->discardp)
- {
- free(self->discardp);
- self->discardp = NULL;
- }
-
- mylog("exit CC_Cleanup\n");
- return TRUE;
-}
-
-
-char
-CC_connect(ConnectionClass *self, char password_req, char *salt_para)
-{
- /* ignore salt_para for now */
- /* QResultClass *res; */
- PGconn *pgconn;
- ConnInfo *ci = &(self->connInfo);
- int areq = -1,connect_return;
- char *encoding;
- /* char *conninfo; */
- CSTR func = "CC_connect";
-
- mylog("%s: entering...\n", func);
-
- if (password_req != AUTH_REQ_OK)
-
- /* already connected, just authenticate */
- pgconn = self->pgconn;
-
- else
- {
- qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d\n",
- POSTGRESDRIVERVERSION,
- ci->drivers.fetch_max,
- ci->drivers.socket_buffersize,
- ci->drivers.unknown_sizes,
- ci->drivers.max_varchar_size,
- ci->drivers.max_longvarchar_size);
- qlog(" disable_optimizer=%d, ksqo=%d, unique_index=%d, use_declarefetch=%d\n",
- ci->drivers.disable_optimizer,
- ci->drivers.ksqo,
- ci->drivers.unique_index,
- ci->drivers.use_declarefetch);
- qlog(" text_as_longvarchar=%d, unknowns_as_longvarchar=%d, bools_as_char=%d NAMEDATALEN=%d\n",
- ci->drivers.text_as_longvarchar,
- ci->drivers.unknowns_as_longvarchar,
- ci->drivers.bools_as_char,
- TABLE_NAME_STORAGE_LEN);
-
- encoding = check_client_encoding(ci->conn_settings);
- if (encoding && strcmp(encoding, "OTHER"))
- self->client_encoding = strdup(encoding);
- else
- {
- encoding = check_client_encoding(ci->drivers.conn_settings);
- if (encoding && strcmp(encoding, "OTHER"))
- self->client_encoding = strdup(encoding);
- }
- if (self->client_encoding)
- self->ccsc = pg_CS_code(self->client_encoding);
- qlog(" extra_systable_prefixes='%s', conn_settings='%s' conn_encoding='%s'\n",
- ci->drivers.extra_systable_prefixes,
- ci->drivers.conn_settings,
- encoding ? encoding : "");
-
- if (self->status != CONN_NOT_CONNECTED)
- {
- CC_set_error(self, CONN_OPENDB_ERROR, "Already connected.");
- return 0;
- }
-
- if (ci->port[0] == '\0' ||
-#ifdef WIN32
- ci->server[0] == '\0' ||
-#endif /* WIN32 */
- ci->database[0] == '\0')
- {
- CC_set_error(self, CONN_INIREAD_ERROR, "Missing server name, port, or database name in call to CC_connect.");
- return 0;
- }
-
- mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', sslmode = '%s',"
- " database = '%s', username = '%s',"
- " password='%s'\n", ci->dsn, ci->server, ci->port, ci->sslmode,
- ci->database, ci->username, ci->password ? "xxxxx" : "");
-
-
- mylog("connecting to the server \n");
-
- connect_return = LIBPQ_connect(self);
- if(0 == connect_return)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_ESTABLISH, "Could not connect to the server");
- return 0;
- }
-
- mylog("connection to the database succeeded.\n");
-
- }
-
- CC_clear_error(self); /* clear any password error */
-
- CC_set_translation(self);
-
- /*
- * Send any initial settings
- */
-
- /*
- * Get the version number first so we can check it before sending options
- * that are now obsolete. DJP 21/06/2002
- */
-
- CC_lookup_pg_version(self); /* Get PostgreSQL version for
- SQLGetInfo use */
- /*
- * Since these functions allocate statements, and since the connection
- * is not established yet, it would violate odbc state transition
- * rules. Therefore, these functions call the corresponding local
- * function instead.
- */
- CC_send_settings(self);
- CC_clear_error(self); /* clear any error */
- CC_lookup_lo(self); /* a hack to get the oid of
- our large object oid type */
-
- /*
- * Multibyte handling is available ?
- */
- if (PG_VERSION_GE(self, 6.4))
- {
- CC_lookup_characterset(self);
- if (CC_get_errornumber(self) != 0)
- return 0;
-#ifdef UNICODE_SUPPORT
- if (self->unicode)
- {
- if (!self->client_encoding ||
- stricmp(self->client_encoding, "UNICODE"))
- {
- QResultClass *res;
- if (PG_VERSION_LT(self, 7.1))
- {
- CC_set_error(self, CONN_NOT_IMPLEMENTED_ERROR, "UTF-8 conversion isn't implemented before 7.1");
- return 0;
- }
- if (self->client_encoding)
- free(self->client_encoding);
- self->client_encoding = NULL;
- res = LIBPQ_execute_query(self,"set client_encoding to 'UTF8'");
- if (res)
- {
- self->client_encoding = strdup("UNICODE");
- self->ccsc = pg_CS_code(self->client_encoding);
- QR_Destructor(res);
-
- }
- }
- }
-#else
- {
- }
-#endif /* UNICODE_SUPPORT */
- }
-#ifdef UNICODE_SUPPORT
- else if (self->unicode)
- {
- CC_set_error(self, CONN_NOT_IMPLEMENTED_ERROR, "Unicode isn't supported before 6.4");
- return 0;
- }
-#endif /* UNICODE_SUPPORT */
- ci->updatable_cursors = 0;
-#ifdef DRIVER_CURSOR_IMPLEMENT
- if (!ci->drivers.use_declarefetch &&
- PG_VERSION_GE(self, 7.0)) /* Tid scan since 7.0 */
- ci->updatable_cursors = ci->allow_keyset;
-#endif /* DRIVER_CURSOR_IMPLEMENT */
-
- CC_clear_error(self); /* clear any initial command errors */
- self->status = CONN_CONNECTED;
-
- mylog("%s: returning...\n", func);
-
- return 1;
-
-}
-
-
-/*
- * Create a more informative error message by concatenating the connection
- * error message with its libpq error message.
- */
-char *
-CC_create_errormsg(ConnectionClass *self)
-{
- PGconn *pgconn = self->pgconn;
- char msg[4096];
-
- mylog("enter CC_create_errormsg\n");
-
- msg[0] = '\0';
-
- if (CC_get_errormsg(self))
- strncpy(msg, CC_get_errormsg(self), sizeof(msg));
-
- mylog("msg = '%s'\n", msg);
-
- mylog("exit CC_create_errormsg\n");
- return msg ? strdup(msg) : NULL;
-}
-
-
-void CC_on_abort(ConnectionClass *conn, UDWORD opt)
-{
- BOOL set_no_trans = FALSE;
-
- if (0 != (opt & CONN_DEAD))
- opt |= NO_TRANS;
- if (CC_is_in_trans(conn))
- {
-#ifdef DRIVER_CURSOR_IMPLEMENT
- if (conn->result_uncommitted)
- ProcessRollback(conn, TRUE);
-#endif /* DRIVER_CURSOR_IMPLEMENT */
- if (0 != (opt & NO_TRANS))
- {
- CC_set_no_trans(conn);
- CC_set_no_manual_trans(conn);
- set_no_trans = TRUE;
- }
- }
- CC_clear_cursors(conn, TRUE);
- if (0 != (opt & CONN_DEAD))
- {
- conn->status = CONN_DOWN;
- if (conn->pgconn)
- {
- LIBPQ_Destructor(conn->pgconn);
- conn->pgconn = NULL;
- }
- }
- else if (set_no_trans)
- CC_discard_marked_plans(conn);
- conn->result_uncommitted = 0;
-}
-
-/*
- * The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
- * the same existing QResultClass (this occurs when the tuple cache is depleted and
- * needs to be re-filled).
- *
- * The "cursor" is used by SQLExecute to associate a statement handle as the cursor name
- * (i.e., C3326857) for SQL select statements. This cursor is then used in future
- * 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
- */
-QResultClass *
-CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag)
-{
- QResultClass *cmdres = NULL,
- *retres = NULL,
- *res ;
- BOOL clear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0),
- create_keyset = ((flag & CREATE_KEYSET) != 0),
- issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self));
- char *wq;
- int id=0;
- PGconn *pgconn = self->pgconn;
- int maxlen,
- empty_reqs;
- BOOL ReadyToReturn = FALSE,
- query_completed = FALSE,
- before_64 = PG_VERSION_LT(self, 6.4),
- aborted = FALSE,
- used_passed_result_object = FALSE;
- int func_cs_count = 0;
-
-
- mylog("send_query(): conn=%u, query='%s'\n", self, query);
- qlog("conn=%u, query='%s'\n", self, query);
-
- if (!self->pgconn)
- {
- CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query(connection dead)");
- CC_on_abort(self, NO_TRANS);
- return NULL;
- }
- /* Indicate that we are sending a query to the backend */
- maxlen = CC_get_max_query_len(self);
- if (maxlen > 0 && maxlen < (int) strlen(query) + 1)
- {
- CC_set_error(self, CONNECTION_MSG_TOO_LONG, "Query string is too long");
- return NULL;
- }
-
- if ((NULL == query) || (query[0] == '\0'))
- return NULL;
-
-#define return DONT_CALL_RETURN_FROM_HERE???
- ENTER_INNER_CONN_CS(self, func_cs_count);
-
- if (issue_begin)
- {
- res = LIBPQ_execute_query(self,"BEGIN");
- QR_Destructor(res);
- }
-
- res = LIBPQ_execute_query(self,query);
-
- if((!res) || (res->status == PGRES_EMPTY_QUERY) )
- {
- QR_Destructor(res);
- res = NULL;
- goto cleanup;
- }
- else
- {
- mylog("send_query: done sending query\n");
-
- empty_reqs = 0;
- for (wq = query; isspace((UCHAR) *wq); wq++)
- ;
- if (*wq == '\0')
- empty_reqs = 1;
- cmdres = qi ? qi->result_in : NULL;
- if (cmdres)
- used_passed_result_object = TRUE;
- if (!used_passed_result_object)
- {
- if (create_keyset)
- QR_set_haskeyset(res->next);
- if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL))
- {
- CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res));
- if (PGRES_FATAL_ERROR == QR_get_status(res))
- retres = cmdres;
- else
- retres = NULL;
- }
- }
- else
- { /* next fetch, so reuse an existing result */
- /*
- * called from QR_next_tuple and must return
- * immediately.
- */
- if (!QR_fetch_tuples(res, NULL, NULL))
- {
- CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res));
- retres = NULL;
- }
- retres = cmdres;
- }
- }
-
-cleanup:
- CLEANUP_FUNC_CONN_CS(func_cs_count, self);
- /*
- * Cleanup garbage results before returning.
- */
- if (cmdres && retres != cmdres && !used_passed_result_object)
- {
- QR_Destructor(cmdres);
- }
- /*
- * Cleanup the aborted result if specified
- */
- if (retres)
- {
- if (aborted)
- {
- if (clear_result_on_abort)
- {
- if (!used_passed_result_object)
- {
- QR_Destructor(retres);
- retres = NULL;
- }
- }
- if (retres)
- {
- /*
- * discard results other than errors.
- */
- QResultClass *qres;
- for (qres = retres; qres->next; qres = retres)
- {
- if (QR_get_aborted(qres))
- break;
- retres = qres->next;
- qres->next = NULL;
- QR_Destructor(qres);
+ retres = qres->next;
+ qres->next = NULL;
+ QR_Destructor(qres);
}
/*
* If error message isn't set
}
-#endif /* USE_LIBPQ */
-
-
/* File: connection.h
*
- * Description: See "connection.c"
+ * Description: See "CONNECTION.c"
*
* Comments: See "notice.txt" for copyright and license information.
*
*/
-#ifndef USE_LIBPQ
-
#ifndef __CONNECTION_H__
#define __CONNECTION_H__
#include "psqlodbc.h"
-
+#include <libpq-fe.h>
#include <stdlib.h>
#include <string.h>
#include "descriptor.h"
#define HAVE_UNIX_SOCKETS
#endif
-typedef enum
-{
- CONN_NOT_CONNECTED, /* Connection has not been established */
- CONN_CONNECTED, /* Connection is up and has been
- * established */
- CONN_DOWN, /* Connection is broken */
- CONN_EXECUTING /* the connection is currently executing a
- * statement */
-} CONN_Status;
-
/* These errors have general sql error state */
-#define CONNECTION_SERVER_NOT_REACHED 101
-#define CONNECTION_MSG_TOO_LONG 103
-#define CONNECTION_COULD_NOT_SEND 104
-#define CONNECTION_NO_SUCH_DATABASE 105
-#define CONNECTION_BACKEND_CRAZY 106
-#define CONNECTION_NO_RESPONSE 107
-#define CONNECTION_SERVER_REPORTED_ERROR 108
-#define CONNECTION_COULD_NOT_RECEIVE 109
-#define CONNECTION_SERVER_REPORTED_WARNING 110
-#define CONNECTION_NEED_PASSWORD 112
+#define CONNECTION_SERVER_NOT_REACHED 101
+#define CONNECTION_MSG_TOO_LONG 103
+#define CONNECTION_COULD_NOT_SEND 104
+#define CONNECTION_NO_SUCH_DATABASE 105
+#define CONNECTION_BACKEND_CRAZY 106
+#define CONNECTION_NO_RESPONSE 107
+#define CONNECTION_SERVER_REPORTED_ERROR 108
+#define CONNECTION_COULD_NOT_RECEIVE 109
+#define CONNECTION_SERVER_REPORTED_WARNING 110
+#define CONNECTION_NEED_PASSWORD 112
+#define CONNECTION_COULD_NOT_ESTABLISH 113
/* These errors correspond to specific SQL states */
-#define CONN_INIREAD_ERROR 201
-#define CONN_OPENDB_ERROR 202
-#define CONN_STMT_ALLOC_ERROR 203
-#define CONN_IN_USE 204
-#define CONN_UNSUPPORTED_OPTION 205
+#define CONN_INIREAD_ERROR 201
+#define CONN_OPENDB_ERROR 202
+#define CONN_STMT_ALLOC_ERROR 203
+#define CONN_IN_USE 204
+#define CONN_UNSUPPORTED_OPTION 205
/* Used by SetConnectoption to indicate unsupported options */
-#define CONN_INVALID_ARGUMENT_NO 206
+#define CONN_INVALID_ARGUMENT_NO 206
/* SetConnectOption: corresponds to ODBC--"S1009" */
-#define CONN_TRANSACT_IN_PROGRES 207
-#define CONN_NO_MEMORY_ERROR 208
-#define CONN_NOT_IMPLEMENTED_ERROR 209
-#define CONN_INVALID_AUTHENTICATION 210
-#define CONN_AUTH_TYPE_UNSUPPORTED 211
-#define CONN_UNABLE_TO_LOAD_DLL 212
+#define CONN_TRANSACT_IN_PROGRES 207
+#define CONN_NO_MEMORY_ERROR 208
+#define CONN_NOT_IMPLEMENTED_ERROR 209
+#define CONN_INVALID_AUTHENTICATION 210
+#define CONN_AUTH_TYPE_UNSUPPORTED 211
+#define CONN_UNABLE_TO_LOAD_DLL 212
+
+#define CONN_OPTION_VALUE_CHANGED 213
+#define CONN_VALUE_OUT_OF_RANGE 214
+
+#define CONN_TRUNCATED 215
-#define CONN_OPTION_VALUE_CHANGED 213
-#define CONN_VALUE_OUT_OF_RANGE 214
-#define CONN_TRUNCATED 215
+#define CONN_MEMORY_ALLOCATION_FAILED 301
+#define COULD_NOT_GET_RESULT_BACK 302
/* Conn_status defines */
-#define CONN_IN_AUTOCOMMIT 1L
+#define CONN_IN_AUTOCOMMIT 1L
#define CONN_IN_TRANSACTION (1L<<1)
#define CONN_IN_MANUAL_TRANSACTION (1L<<2)
#define CONN_IN_ERROR_BEFORE_IDLE (1L<<3)
#define LEAVE_CONN_CS(x) pthread_mutex_unlock(&((x)->cs))
#define DELETE_CONN_CS(x) pthread_mutex_destroy(&((x)->cs))
#else
-#define INIT_CONN_CS(x)
+#define INIT_CONN_CS(x)
#define ENTER_CONN_CS(x)
#define ENTER_INNER_CONN_CS(x, entered) (0)
#define LEAVE_CONN_CS(x)
entered--; \
}
-/* Authentication types */
-#define AUTH_REQ_OK 0
-#define AUTH_REQ_KRB4 1
-#define AUTH_REQ_KRB5 2
-#define AUTH_REQ_PASSWORD 3
-#define AUTH_REQ_CRYPT 4
-#define AUTH_REQ_MD5 5
-#define AUTH_REQ_SCM_CREDS 6
-
-/* Startup Packet sizes */
-#define SM_DATABASE 64
-#define SM_USER 32
-#define SM_OPTIONS 64
-#define SM_UNUSED 64
-#define SM_TTY 64
+
+#define AUTH_REQ_OK 0
+#define AUTH_REQ_KRB4 1
+#define AUTH_REQ_KRB5 2
+#define AUTH_REQ_PASSWORD 3
+#define AUTH_REQ_CRYPT 4
+#define AUTH_REQ_MD5 5
+#define AUTH_REQ_SCM_CREDS 6
/* Old 6.2 protocol defines */
-#define NO_AUTHENTICATION 7
-#define PATH_SIZE 64
-#define ARGV_SIZE 64
-#define USRNAMEDATALEN 16
+#define NO_AUTHENTICATION 7
+#define PATH_SIZE 64
+#define ARGV_SIZE 64
+#define USRNAMEDATALEN 16
typedef unsigned int ProtocolVersion;
#define PG_PROTOCOL_63 PG_PROTOCOL(1, 0)
#define PG_PROTOCOL_62 PG_PROTOCOL(0, 0)
-/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */
-typedef struct _StartupPacket
-{
- ProtocolVersion protoVersion;
- char database[SM_DATABASE];
- char user[SM_USER];
- char options[SM_OPTIONS];
- char unused[SM_UNUSED];
- char tty[SM_TTY];
-} StartupPacket;
-
-/* This startup packet is to support pre-Postgres 6.3 protocol */
-typedef struct _StartupPacket6_2
+typedef enum
{
- unsigned int authtype;
- char database[PATH_SIZE];
- char user[USRNAMEDATALEN];
- char options[ARGV_SIZE];
- char execfile[ARGV_SIZE];
- char tty[PATH_SIZE];
-} StartupPacket6_2;
+ CONN_NOT_CONNECTED, /* Connection has not been established */
+ CONN_CONNECTED, /* Connection is up and has been
+ * established */
+ CONN_DOWN, /* Connection is broken */
+ CONN_EXECUTING /* the connection is currently executing a
+ * statement */
+} CONN_Status;
/* Transferred from pqcomm.h: */
typedef ProtocolVersion MsgType;
-#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678)
-
-typedef struct CancelRequestPacket
-{
- /* Note that each field is stored in network byte order! */
- MsgType cancelRequestCode; /* code to identify a cancel request */
- unsigned int backendPID; /* PID of client's backend */
- unsigned int cancelAuthCode; /* secret key to authorize cancel */
-} CancelRequestPacket;
-
/* Structure to hold all the connection attributes for a specific
- connection (used for both registry and file, DSN and DRIVER)
-*/
+ connection (used for both registry and file, DSN and DRIVER) */
+
typedef struct
{
char dsn[MEDIUM_REGISTRY_LEN];
char protocol[SMALL_REGISTRY_LEN];
char port[SMALL_REGISTRY_LEN];
char sslmode[MEDIUM_REGISTRY_LEN];
-#ifdef HAVE_UNIX_SOCKETS
- char uds[LARGE_REGISTRY_LEN];
-#endif
char onlyread[SMALL_REGISTRY_LEN];
char fake_oid_index[SMALL_REGISTRY_LEN];
char show_oid_column[SMALL_REGISTRY_LEN];
GLOBAL_VALUES drivers; /* moved from driver's option */
} ConnInfo;
+
/* Macro to determine is the connection using 6.2 protocol? */
#define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0)
#define HINSTANCE void *
#endif
-typedef BOOL (FAR WINAPI * DataSourceToDriverProc) (UDWORD,
- SWORD,
- PTR,
- SDWORD,
- PTR,
- SDWORD,
- SDWORD FAR *,
- UCHAR FAR *,
- SWORD,
- SWORD FAR *);
-
-typedef BOOL (FAR WINAPI * DriverToDataSourceProc) (UDWORD,
- SWORD,
- PTR,
- SDWORD,
- PTR,
- SDWORD,
- SDWORD FAR *,
- UCHAR FAR *,
- SWORD,
- SWORD FAR *);
-
-/******* The Connection handle ************/
+typedef BOOL (FAR WINAPI * DataSourceToDriverProc)
+ (UDWORD,SWORD,PTR,SDWORD,PTR,SDWORD,SDWORD FAR *,UCHAR FAR *,SWORD,SWORD FAR *);
+
+typedef BOOL (FAR WINAPI * DriverToDataSourceProc)
+ (UDWORD,SWORD,PTR,SDWORD,PTR,SDWORD,SDWORD FAR *,UCHAR FAR *,SWORD,SWORD FAR *);
+
+ /******* The Connection handle ************/
struct ConnectionClass_
{
HENV henv; /* environment this connection was created
ConnInfo connInfo;
StatementClass **stmts;
int num_stmts;
- SocketClass *sock;
+ PGconn *pgconn;
int lobj_type;
int ntables;
COL_INFO **col_info;
/* Accessor functions */
-#define CC_get_socket(x) (x->sock)
#define CC_get_database(x) (x->connInfo.database)
#define CC_get_server(x) (x->connInfo.server)
#define CC_get_DSN(x) (x->connInfo.dsn)
#define CC_get_username(x) (x->connInfo.username)
#define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1')
-
+
/* for CC_DSN_info */
#define CONN_DONT_OVERWRITE 0
#define CONN_OVERWRITE 1
void CC_set_error(ConnectionClass *self, int number, const char *message);
void CC_set_errormsg(ConnectionClass *self, const char *message);
char CC_get_error(ConnectionClass *self, int *number, char **message);
-QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag);
+QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag);
void CC_clear_error(ConnectionClass *self);
char *CC_create_errormsg(ConnectionClass *self);
-int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
+int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
char CC_send_settings(ConnectionClass *self);
void CC_lookup_lo(ConnectionClass *conn);
void CC_lookup_pg_version(ConnectionClass *conn);
int CC_mark_a_plan_to_discard(ConnectionClass *conn, const char *plannm);
int CC_discard_marked_plans(ConnectionClass *conn);
+/* Accessor functions*/
+PGconn *LIBPQ_Constructor();
+void LIBPQ_Destructor(PGconn *pgconn);
+int LIBPQ_connect(ConnectionClass *self);
+QResultClass *LIBPQ_execute_query(ConnectionClass *self,char *query);
+QResultClass *CC_mapping(ConnectionClass *self,PGresult *pgres,QResultClass *qres);
+void CC_is_server_alive(ConnectionClass *conn);
/* CC_send_query options */
#define CLEAR_RESULT_ON_ABORT 1L
#define CREATE_KEYSET (1L << 1) /* create keyset for updatable curosrs */
#define CONN_DEAD (1L << 1) /* connection is no longer valid */
#endif /* __CONNECTION_H__ */
-
-#endif /* USE_LIBPQ */
#endif
#include <math.h>
#include <stdlib.h>
+#include <libpq/libpq-fs.h>
#include "statement.h"
#include "qresult.h"
#include "bind.h"
#include "pgtypes.h"
-#include "lobj.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "pgapifunc.h"
#if defined(UNICODE_SUPPORT) && defined(WIN32)
}
/* store the oid */
-#ifdef USE_LIBPQ
lobj_oid = lo_creat(conn->pgconn, INV_READ | INV_WRITE);
-#else
- lobj_oid = lo_creat(conn, INV_READ | INV_WRITE);
-#endif /* USE_LIBPQ */
-
if (lobj_oid == 0)
{
qb->errornumber = STMT_EXEC_ERROR;
}
/* store the fd */
-#ifdef USE_LIBPQ
lobj_fd = lo_open(conn->pgconn, lobj_oid, INV_WRITE);
-#else
- lobj_fd = lo_open(conn, lobj_oid, INV_WRITE);
-#endif /* USE_LIBPQ */
if (lobj_fd < 0)
{
qb->errormsg = "Couldnt open (in-line) large object for writing.";
return SQL_ERROR;
}
-#ifdef USE_LIBPQ
- retval = lo_write(conn->pgconn, lobj_fd, buffer, used);
- lo_close(conn->pgconn, lobj_fd);
-
-#else
- retval = lo_write(conn, lobj_fd, buffer, used);
-
- lo_close(conn, lobj_fd);
-#endif /* USE_LIBPQ */
+
+ retval = lo_write(conn->pgconn, lobj_fd, buffer, used);
+ lo_close(conn->pgconn, lobj_fd);
/* commit transaction if needed */
if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn))
}
oid = ATOI32U(value);
-#ifdef USE_LIBPQ
- stmt->lobj_fd = lo_open(conn->pgconn, oid, INV_READ);
-#else
- stmt->lobj_fd = lo_open(conn, oid, INV_READ);
-#endif /* USE_LIBPQ*/
+ stmt->lobj_fd = lo_open(conn->pgconn, oid, INV_READ);
if (stmt->lobj_fd < 0)
{
}
/* Get the size */
-#ifdef USE_LIBPQ
- retval = lo_lseek(conn->pgconn, stmt->lobj_fd, 0L, SEEK_END);
-#else
- retval = lo_lseek(conn, stmt->lobj_fd, 0L, SEEK_END);
-#endif /* USE_LIBPQ*/
+ retval = lo_lseek(conn->pgconn, stmt->lobj_fd, 0L, SEEK_END);
if (retval >= 0)
{
-#ifdef USE_LIBPQ
left = lo_tell(conn->pgconn, stmt->lobj_fd);
-#else
- left = lo_tell(conn, stmt->lobj_fd);
-#endif /* USE_LIBPQ*/
if (gdata)
gdata->data_left = left;
/* return to beginning */
-#ifdef USE_LIBPQ
lo_lseek(conn->pgconn, stmt->lobj_fd, 0L, SEEK_SET);
-#else
- lo_lseek(conn, stmt->lobj_fd, 0L, SEEK_SET);
-#endif /* USE_LIBPQ*/
-
}
}
mylog("lo data left = %d\n", left);
return COPY_GENERAL_ERROR;
}
-#ifdef USE_LIBPQ
retval = lo_read(conn->pgconn, stmt->lobj_fd, (char *) rgbValue, factor > 1 ? (cbValueMax - 1) / factor : cbValueMax);
-#else
- retval = lo_read(conn, stmt->lobj_fd, (char *) rgbValue, factor > 1 ? (cbValueMax - 1) / factor : cbValueMax);
-#endif /* USE_LIBPQ */
if (retval < 0)
{
-#ifdef USE_LIBPQ
lo_close(conn->pgconn, stmt->lobj_fd);
-#else
- lo_close(conn, stmt->lobj_fd);
-#endif /* USE_LIBPQ */
-
/* commit transaction if needed */
if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn))
if (!gdata || gdata->data_left == 0)
{
-#ifdef USE_LIBPQ
lo_close(conn->pgconn, stmt->lobj_fd);
-#else
- lo_close(conn, stmt->lobj_fd);
-#endif /* USE_LIBPQ */
/* commit transaction if needed */
if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn))
*/
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "descriptor.h"
#include "statement.h"
else if (stricmp(attribute, INI_SSLMODE) == 0 || stricmp(attribute, "sslmode") == 0)
strcpy(ci->sslmode, value);
-#ifndef USE_LIBPQ
-#ifdef HAVE_UNIX_SOCKETS
- else if (stricmp(attribute, INI_UDS) == 0)
- strcpy(ci->uds, value);
-#endif
-#endif /*USE_LIBPQ*/
-
else if (stricmp(attribute, INI_READONLY) == 0 || stricmp(attribute, "A0") == 0)
strcpy(ci->onlyread, value);
if (ci->sslmode[0] == '\0' || overwrite)
SQLGetPrivateProfileString(DSN, INI_SSLMODE, "", ci->sslmode, sizeof(ci->sslmode), ODBC_INI);
-#ifndef USE_LIBPQ
-#ifdef HAVE_UNIX_SOCKETS
- if (ci->uds[0] == '\0' || overwrite)
- SQLGetPrivateProfileString(DSN, INI_UDS, "", ci->uds, sizeof(ci->uds), ODBC_INI);
-#endif
-#endif /* USE_LIBPQ */
-
if (ci->onlyread[0] == '\0' || overwrite)
SQLGetPrivateProfileString(DSN, INI_READONLY, "", ci->onlyread, sizeof(ci->onlyread), ODBC_INI);
ci->sslmode,
ODBC_INI);
-#ifndef USE_LIBPQ
-#ifdef HAVE_UNIX_SOCKETS
- SQLWritePrivateProfileString(DSN,
- INI_UDS,
- ci->uds,
- ODBC_INI);
-#endif
-#endif /* USE_LIBPQ */
-
SQLWritePrivateProfileString(DSN,
INI_USER,
ci->username,
#define __DLG_SPECIFIC_H__
#include "psqlodbc.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
#ifdef WIN32
#include <windowsx.h>
#include <stdio.h>
#include <stdlib.h>
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
#ifndef WIN32
#include <sys/types.h>
-#include <sys/socket.h>
#define NEAR
-#else
-#include <winsock.h>
#endif
#include <string.h>
*/
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "dlg_specific.h"
#include "statement.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <libpq/libpq-fs.h>
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include "qresult.h"
#include "convert.h"
#include "bind.h"
#include "pgtypes.h"
-#include "lobj.h"
#include "pgapifunc.h"
/*extern GLOBAL_VALUES globals;*/
{
EnvironmentClass *env = (EnvironmentClass *) (conn->henv);
-#ifdef USE_LIBPQ
if (!res->recent_processed_row_count && res->status == PGRES_COMMAND_OK && EN_is_odbc3(env))
{
if ((strnicmp(stmt->statement, "UPDATE", 6) == 0) ||
(strnicmp(stmt->statement, "DELETE", 6) == 0))
retval = SQL_NO_DATA_FOUND;
}
-
-#else
- const char *cmd = QR_get_command(res);
-
- if (retval == SQL_SUCCESS && cmd && EN_is_odbc3(env))
- {
- int count;
-
- if (sscanf(cmd , "UPDATE %d", &count) == 1)
- ;
- else if (sscanf(cmd , "DELETE %d", &count) == 1)
- ;
- else
- count = -1;
- if (0 == count)
- retval = SQL_NO_DATA;
- }
-#endif /* USE_LIBPQ */
-
stmt->diag_row_count = res->recent_processed_row_count;
}
/*
StatementClass *stmt = (StatementClass *) hstmt;
APDFields *apdopts;
IPDFields *ipdopts;
- int i,
- retval, start_row, end_row;
+ int i, retval, start_row, end_row;
BOOL exec_end, recycled = FALSE, recycle = TRUE;
mylog("%s: entering...\n", func);
/* close the large object */
if (estmt->lobj_fd >= 0)
{
-#ifdef USE_LIBPQ
lo_close(estmt->hdbc->pgconn, estmt->lobj_fd);
-#else
- lo_close(estmt->hdbc, estmt->lobj_fd);
-#endif /* USE_LIBPQ */
/* commit transaction if needed */
if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(estmt->hdbc))
}
/* store the oid */
-#ifdef USE_LIBPQ
current_pdata->lobj_oid = lo_creat(conn->pgconn, INV_READ | INV_WRITE);
-#else
- current_pdata->lobj_oid = lo_creat(conn, INV_READ | INV_WRITE);
-#endif /* USE_LIBPQ */
+
if (current_pdata->lobj_oid == 0)
{
SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt create large object.");
/***current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid;***/
/* store the fd */
-#ifdef USE_LIBPQ
estmt->lobj_fd = lo_open(conn->pgconn, current_pdata->lobj_oid, INV_WRITE);
-#else
- estmt->lobj_fd = lo_open(conn, current_pdata->lobj_oid, INV_WRITE);
-#endif /* USE_LIBPQ */
if (estmt->lobj_fd < 0)
{
SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt open large object for writing.");
return SQL_ERROR;
}
-#ifdef USE_LIBPQ
retval = lo_write(conn->pgconn, estmt->lobj_fd, putbuf, putlen);
-#else
- retval = lo_write(conn, estmt->lobj_fd, putbuf, putlen);
-#endif /* USE_LIBPQ */
mylog("lo_write: cbValue=%d, wrote %d bytes\n", putlen, retval);
}
else
if (current_iparam->PGType == conn->lobj_type)
{
/* the large object fd is in EXEC_buffer */
-#ifdef USE_LIBPQ
retval = lo_write(conn->pgconn, estmt->lobj_fd, putbuf, putlen);
-#else
- retval = lo_write(conn, estmt->lobj_fd, putbuf, putlen);
-#endif /* USE_LIBPQ */
mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", putlen, retval);
*current_pdata->EXEC_used += putlen;
#include "tuple.h"
#include "pgtypes.h"
#include "dlg_specific.h"
-
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include "qresult.h"
#include "bind.h"
*/
#include "psqlodbc.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "pgapifunc.h"
RETCODE SQL_API
* of getpid ? */
#endif
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "multibyte.h"
extern GLOBAL_VALUES globals;
*/
#include "multibyte.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "pgapifunc.h"
#include "qresult.h"
#include <string.h>
#include "pgapifunc.h"
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include "qresult.h"
#include <string.h>
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include "pgapifunc.h"
#include <string.h>
#include "pgapifunc.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include <string.h>
#include "pgapifunc.h"
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
#include "statement.h"
RETCODE SQL_API SQLColumnsW(HSTMT StatementHandle,
#include <string.h>
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include "qresult.h"
#include "pgapifunc.h"
#include <ctype.h>
#include "statement.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "qresult.h"
#include "pgtypes.h"
#include "pgapifunc.h"
#include <string.h>
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "statement.h"
#include "descriptor.h"
#include "qresult.h"
*((SQLUINTEGER *) Value) = SQL_FALSE;
break;
case SQL_ATTR_CONNECTION_DEAD:
-#ifdef USE_LIBPQ
CC_is_server_alive(conn);
-#endif /* USE_LIBPQ */
*((SQLUINTEGER *) Value) = (conn->status == CONN_NOT_CONNECTED || conn->status == CONN_DOWN);
break;
case SQL_ATTR_CONNECTION_TIMEOUT:
#include "dlg_specific.h"
#include "statement.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include "environ.h"
#include "qresult.h"
#include "dlg_specific.h"
#include "environ.h"
-#ifdef WIN32
-#include <winsock.h>
-#endif
-
GLOBAL_VALUES globals;
RETCODE SQL_API SQLDummyOrdinal(void);
BOOL WINAPI
DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
-#ifndef USE_LIBPQ
- WORD wVersionRequested;
- WSADATA wsaData;
-#endif /* USE_LIBPQ */
-
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
s_hModule = hInst; /* Save for dialog boxes */
-#ifndef USE_LIBPQ
- /* Load the WinSock Library */
- wVersionRequested = MAKEWORD(1, 1);
-
- if (WSAStartup(wVersionRequested, &wsaData))
- return FALSE;
-
- /* Verify that this is the minimum version of WinSock */
- if (LOBYTE(wsaData.wVersion) != 1 ||
- HIBYTE(wsaData.wVersion) != 1)
- {
- WSACleanup();
- return FALSE;
- }
-#endif /* USE_LIBPQ */
initialize_global_cs();
getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
break;
case DLL_PROCESS_DETACH:
finalize_global_cs();
-#ifndef USE_LIBPQ
- WSACleanup();
-#endif /* USE_LIBPQ*/
return TRUE;
case DLL_THREAD_DETACH:
*
* Comments: See "notice.txt" for copyright and license information.
*
- * $Id: psqlodbc.h,v 1.90 2005/09/06 07:47:26 dpage Exp $
+ * $Id: psqlodbc.h,v 1.91 2005/09/19 13:31:59 anoop Exp $
*
*/
#endif
-#ifndef USE_LIBPQ
-typedef UInt4 Oid;
-#endif /* USE_LIBPQ */
-
#ifndef FALSE
#define FALSE (BOOL)0
#endif
typedef struct ConnectionClass_ ConnectionClass;
typedef struct StatementClass_ StatementClass;
typedef struct QResultClass_ QResultClass;
-typedef struct SocketClass_ SocketClass;
typedef struct BindInfoClass_ BindInfoClass;
typedef struct ParameterInfoClass_ ParameterInfoClass;
typedef struct ParameterImplClass_ ParameterImplClass;
* If conn is defined, then we may have used "backend_tuples", so in
* case we need to, free it up. Also, close the cursor.
*/
-#ifdef USE_LIBPQ
-
/*
* FIXME!!!
* This is *very wrong*, however, without it we get crashes when
self->backend_tuples = NULL;
}
if (conn && conn->pgconn && CC_is_in_trans(conn))
-#else
- if (conn && conn->sock && CC_is_in_trans(conn))
-#endif /* USE_LIBPQ */
{
if (!QR_close(self)) /* close the cursor if there is one */
{
free(self->keyset);
self->keyset = NULL;
self->count_keyset_allocated = 0;
-#ifdef USE_LIBPQ
+
if (self->reload_count > 0 && conn && conn->pgconn)
-#else
- if (self->reload_count > 0 && conn && conn->sock)
-#endif /* USE_LIBPQ */
{
char plannm[32];
{
if (!cursor || cursor[0] == '\0')
{
-#ifndef USE_LIBPQ
- self->status = PGRES_INTERNAL_ERROR;
-#endif /* USE_LIBPQ*/
QR_set_message(self, "Internal Error -- no cursor for fetch");
return FALSE;
}
*
* $$$$ Should do some error control HERE! $$$$
*/
- if (CI_read_fields(self->fields, self->conn))
- {
-#ifndef USE_LIBPQ
- self->status = PGRES_FIELDS_OK;
-#endif /* USE_LIBPQ*/
self->num_fields = CI_get_num_fields(self->fields);
if (self->haskeyset)
self->num_fields -= 2;
- }
- else
- {
- self->status = PGRES_BAD_RESPONSE;
- QR_set_message(self, "Error reading field information");
- return FALSE;
- }
mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields);
self->num_backend_rows = tuple_size + 1;
self->fetch_count = tuple_size + 1;
self->base = 0;
-#ifdef USE_LIBPQ
return TRUE;
-#else
- return QR_next_tuple(self);
-#endif /* USE_LIBPQ */
}
else
{
- /*
- * Always have to read the field attributes. But we dont have to
- * reallocate memory for them!
- */
-
- if (!CI_read_fields(NULL, self->conn))
- {
- self->status = PGRES_BAD_RESPONSE;
- QR_set_message(self, "Error reading field information");
- return FALSE;
- }
return TRUE;
}
}
/* This function is called by fetch_tuples() AND SQLFetch() */
-#ifdef USE_LIBPQ
-
int
QR_next_tuple(QResultClass *self)
{
self->currTuple++;
return TRUE;
}
-
-#else
-
-int
-QR_next_tuple(QResultClass *self)
-{
- int id;
- QResultClass *res;
- SocketClass *sock;
-
- /* Speed up access */
- int fetch_count = self->fetch_count;
- int num_backend_rows = self->num_backend_rows;
- int fetch_size,
- offset = 0;
- int end_tuple = self->rowset_size + self->base;
- char corrected = FALSE;
- TupleField *the_tuples = self->backend_tuples;
-
- /* ERROR_MSG_LENGTH is sufficient */
- char msgbuffer[ERROR_MSG_LENGTH + 1];
-
- /* QR_set_command() dups this string so doesn't need static */
- char cmdbuffer[ERROR_MSG_LENGTH + 1];
- char fetch[128];
- QueryInfo qi;
- ConnInfo *ci = NULL;
- BOOL msg_truncated;
- UDWORD abort_opt;
-
- if (fetch_count < num_backend_rows)
- {
- /* return a row from cache */
- mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, num_backend_rows);
- self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
- self->fetch_count++;
- return TRUE;
- }
- else if (self->num_backend_rows < self->cache_size)
- {
- /* last row from cache */
- /* We are done because we didn't even get CACHE_SIZE tuples */
- mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", num_backend_rows, fetch_count);
- self->tupleField = NULL;
- self->status = PGRES_END_TUPLES;
- /* end of tuples */
- return -1;
- }
- else
- {
- /*
- * See if we need to fetch another group of rows. We may be being
- * called from send_query(), and if so, don't send another fetch,
- * just fall through and read the tuples.
- */
- self->tupleField = NULL;
-
- if (!self->inTuples)
- {
- ci = &(self->conn->connInfo);
- if (!self->cursor || !ci->drivers.use_declarefetch)
- {
- mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", self->num_total_rows, fetch_count);
- self->tupleField = NULL;
- self->status = PGRES_END_TUPLES;
- return -1; /* end of tuples */
- }
-
- if (self->base == num_backend_rows)
- {
- int row, lf;
- TupleField *tuple = self->backend_tuples;
-
- /* not a correction */
- /* Determine the optimum cache size. */
- if (ci->drivers.fetch_max % self->rowset_size == 0)
- fetch_size = ci->drivers.fetch_max;
- else if (self->rowset_size < ci->drivers.fetch_max)
- fetch_size = (ci->drivers.fetch_max / self->rowset_size) * self->rowset_size;
- else
- fetch_size = self->rowset_size;
-
- self->cache_size = fetch_size;
- /* clear obsolete tuples */
-inolog("clear obsolete %d tuples\n", num_backend_rows);
- for (row = 0; row < num_backend_rows; row++)
- {
- for (lf = 0; lf < self->num_fields; lf++)
- {
- if (tuple[lf].value != NULL)
- {
- free(tuple[lf].value);
- tuple[lf].value = NULL;
- }
- }
- tuple += self->num_fields;
- }
- self->fetch_count = 1;
- }
- else
- {
- /* need to correct */
- corrected = TRUE;
-
- fetch_size = end_tuple - num_backend_rows;
-
- self->cache_size += fetch_size;
-
- offset = self->fetch_count;
- self->fetch_count++;
- }
-
- if (!self->backend_tuples || self->cache_size > self->count_backend_allocated)
- {
- self->count_backend_allocated = 0;
- if (self->num_fields > 0)
- {
- QR_REALLOC_return_with_error(self->backend_tuples, TupleField,
- (self->num_fields * sizeof(TupleField) * self->cache_size),
- self, "Out of memory while reading tuples.", FALSE)
- self->count_backend_allocated = self->cache_size;
- }
- }
- if (self->haskeyset && (!self->keyset || self->cache_size > self->count_keyset_allocated))
- {
- self->count_keyset_allocated = 0;
- QR_REALLOC_return_with_error(self->keyset, KeySet,
- (sizeof(KeySet) * self->cache_size),
- self, "Out of memory while reading tuples.", FALSE)
- self->count_keyset_allocated = self->cache_size;
- }
- sprintf(fetch, "fetch %d in %s", fetch_size, self->cursor);
-
- mylog("next_tuple: sending actual fetch (%d) query '%s'\n", fetch_size, fetch);
-
- /* don't read ahead for the next tuple (self) ! */
- qi.row_size = self->cache_size;
- qi.result_in = self;
- qi.cursor = NULL;
- res = CC_send_query(self->conn, fetch, &qi, CLEAR_RESULT_ON_ABORT);
- if (res == NULL)
- {
- self->status = PGRES_FATAL_ERROR;
- QR_set_message(self, "Error fetching next group.");
- return FALSE;
- }
- self->inTuples = TRUE;
- }
- else
- {
- mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->num_backend_rows, self->fetch_count);
-
- /*
- * This is a pre-fetch (fetching rows right after query but
- * before any real SQLFetch() calls. This is done so the
- * field attributes are available.
- */
- self->fetch_count = 0;
- }
- }
-
- if (!corrected)
- {
- self->base = 0;
- self->num_backend_rows = 0;
- }
-
- sock = CC_get_socket(self->conn);
- self->tupleField = NULL;
- ci = &(self->conn->connInfo);
-
- for (;;)
- {
- id = SOCK_get_char(sock);
-
- switch (id)
- {
-
- case 'P':
- mylog("Portal name within tuples ?? just ignore\n");
- SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- break;
- case 'T':
- mylog("Tuples within tuples ?? OK try to handle them\n");
- self->inTuples = FALSE;
- if (self->num_total_rows > 0)
- {
- mylog("fetched %d rows\n", self->num_total_rows);
- /* set to first row */
- self->tupleField = self->backend_tuples + (offset * self->num_fields);
- }
- else
- {
- mylog(" [ fetched 0 rows ]\n");
- }
- /* add new Result class */
- self->next = QR_Constructor();
- if (!self->next)
- {
- CC_set_error(self->conn, CONNECTION_COULD_NOT_RECEIVE, "Could not create result info in send_query.");
- CC_on_abort(self->conn, NO_TRANS | CONN_DEAD);
- return FALSE;
- }
- QR_set_cache_size(self->next, self->cache_size);
- self = self->next;
- if (!QR_fetch_tuples(self, self->conn, NULL))
- {
- CC_set_error(self->conn, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(self));
- return FALSE;
- }
-
- return TRUE;
- case 'B': /* Tuples in binary format */
- case 'D': /* Tuples in ASCII format */
-
- if (!self->cursor || !ci->drivers.use_declarefetch)
- {
- if (self->num_fields > 0 &&
- self->num_total_rows >= self->count_backend_allocated)
- {
- int tuple_size = self->count_backend_allocated;
-
- mylog("REALLOC: old_count = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
- tuple_size *= 2;
- QR_REALLOC_return_with_error(self->backend_tuples, TupleField,
- (tuple_size * self->num_fields * sizeof(TupleField)),
- self, "Out of memory while reading tuples.", FALSE)
- self->count_backend_allocated = tuple_size;
- }
- if (self->haskeyset &&
- self->num_total_rows >= self->count_keyset_allocated)
- {
- int tuple_size = self->count_keyset_allocated;
- tuple_size *= 2;
- QR_REALLOC_return_with_error(self->keyset, KeySet,
- (sizeof(KeySet) * tuple_size),
- self, "Out of memory while reading tuples.", FALSE)
- self->count_keyset_allocated = tuple_size;
- }
- }
-
- if (!QR_read_tuple(self, (char) (id == 0)))
- {
- self->status = PGRES_BAD_RESPONSE;
- QR_set_message(self, "Error reading the tuple");
- return FALSE;
- }
- self->num_total_rows++;
- if (self->num_fields > 0)
- self->num_backend_rows++;
- break; /* continue reading */
-
- case 'C': /* End of tuple list */
- SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- QR_set_command(self, cmdbuffer);
-
- mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
-
- self->inTuples = FALSE;
- qlog(" [ fetched %d rows ]\n", self->num_total_rows);
- mylog("_next_tuple: 'C' fetch_total = %d & this_fetch = %d\n", self->num_total_rows, self->num_backend_rows);
- if (self->num_backend_rows > 0)
- {
- /* set to first row */
- self->tupleField = self->backend_tuples + (offset * self->num_fields);
- return TRUE;
- }
- else
- {
- /* We are surely done here (we read 0 tuples) */
- mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
- return -1; /* end of tuples */
- }
-
- case 'E': /* Error */
- msg_truncated = SOCK_get_string(sock, msgbuffer,
- ERROR_MSG_LENGTH);
-
- /* Remove a newline */
- if (msgbuffer[0] != '\0' && msgbuffer[strlen(msgbuffer) - 1] == '\n')
- msgbuffer[strlen(msgbuffer) - 1] = '\0';
-
- abort_opt = 0;
- if (!strncmp(msgbuffer, "FATAL", 5))
- abort_opt = NO_TRANS | CONN_DEAD;
- CC_on_abort(self->conn, abort_opt);
- QR_set_status(self, PGRES_FATAL_ERROR);
- QR_set_message(self, msgbuffer);
- QR_set_aborted(self, TRUE);
-
- mylog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
- qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
- while (msg_truncated)
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
-
- return FALSE;
-
- case 'N': /* Notice */
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- QR_set_notice(self, cmdbuffer);
- if (QR_command_successful(self))
- QR_set_status(self, PGRES_NONFATAL_ERROR);
- qlog("NOTICE from backend in next_tuple: '%s'\n", msgbuffer);
- while (msg_truncated)
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- continue;
-
- default: /* this should only happen if the backend
- * dumped core */
- mylog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
- qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
- QR_set_message(self, "Unexpected result from backend. It probably crashed");
- self->status = PGRES_FATAL_ERROR;
- CC_on_abort(self->conn, NO_TRANS | CONN_DEAD);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
-char
-QR_read_tuple(QResultClass *self, char binary)
-{
- Int2 field_lf;
- TupleField *this_tuplefield;
- KeySet *this_keyset = NULL;
- char bmp,
- bitmap[MAX_FIELDS]; /* Max. len of the bitmap */
- Int2 bitmaplen; /* len of the bitmap in bytes */
- Int2 bitmap_pos;
- Int2 bitcnt;
- Int4 len;
- char *buffer;
- int ci_num_fields = QR_NumResultCols(self); /* speed up access */
- int num_fields = self->num_fields; /* speed up access */
- SocketClass *sock = CC_get_socket(self->conn);
- ColumnInfoClass *flds;
- int effective_cols;
- char tidoidbuf[32];
-
- /* set the current row to read the fields into */
- effective_cols = QR_NumPublicResultCols(self);
- this_tuplefield = self->backend_tuples + (self->num_backend_rows * num_fields);
- if (self->haskeyset)
- {
- this_keyset = self->keyset + self->num_total_rows;
- this_keyset->status = 0;
- }
-
- bitmaplen = (Int2) ci_num_fields / BYTELEN;
- if ((ci_num_fields % BYTELEN) > 0)
- bitmaplen++;
-
- /*
- * At first the server sends a bitmap that indicates which database
- * fields are null
- */
- SOCK_get_n_char(sock, bitmap, bitmaplen);
-
- bitmap_pos = 0;
- bitcnt = 0;
- bmp = bitmap[bitmap_pos];
- flds = self->fields;
-
- for (field_lf = 0; field_lf < ci_num_fields; field_lf++)
- {
- /* Check if the current field is NULL */
- if (!(bmp & 0200))
- {
- /* YES, it is NULL ! */
- this_tuplefield[field_lf].len = 0;
- this_tuplefield[field_lf].value = 0;
- }
- else
- {
- /*
- * NO, the field is not null. so get at first the length of
- * the field (four bytes)
- */
- len = SOCK_get_int(sock, VARHDRSZ);
- if (!binary)
- len -= VARHDRSZ;
-
- if (field_lf >= effective_cols)
- buffer = tidoidbuf;
- else
- QR_MALLOC_return_with_error(buffer, char,
- (len + 1), self,
- PGRES_FATAL_ERROR,
- "Couldn't allocate buffer",
- FALSE);
- SOCK_get_n_char(sock, buffer, len);
- buffer[len] = '\0';
-
- mylog("qresult: len=%d, buffer='%s'\n", len, buffer);
-
- if (field_lf >= effective_cols)
- {
- if (field_lf == effective_cols)
- sscanf(buffer, "(%lu,%hu)",
- &this_keyset->blocknum, &this_keyset->offset);
- else
- this_keyset->oid = strtoul(buffer, NULL, 10);
- }
- else
- {
- this_tuplefield[field_lf].len = len;
- this_tuplefield[field_lf].value = buffer;
-
- /*
- * This can be used to set the longest length of the column
- * for any row in the tuple cache. It would not be accurate
- * for varchar and text fields to use this since a tuple cache
- * is only 100 rows. Bpchar can be handled since the strlen of
- * all rows is fixed, assuming there are not 100 nulls in a
- * row!
- */
-
- if (flds && flds->display_size && flds->display_size[field_lf] < len)
- flds->display_size[field_lf] = len;
- }
- }
-
- /*
- * Now adjust for the next bit to be scanned in the next loop.
- */
- bitcnt++;
- if (BYTELEN == bitcnt)
- {
- bitmap_pos++;
- bmp = bitmap[bitmap_pos];
- bitcnt = 0;
- }
- else
- bmp <<= 1;
- }
- self->currTuple++;
- return TRUE;
-}
-
-
-#endif /* USE_LIBPQ */
#define __QRESULT_H__
#include "psqlodbc.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#include "socket.h"
-#endif /* USE_LIBPQ */
-
#include "columninfo.h"
#include "tuplelist.h"
#include "tuple.h"
-#ifndef USE_LIBPQ
-enum QueryResultCode_
-{
- PGRES_EMPTY_QUERY = 0,
- PGRES_COMMAND_OK, /* a query command that doesn't return */
- /* anything was executed properly by the backend */
- PGRES_TUPLES_OK, /* a query command that returns tuples */
- /* was executed properly by the backend, PGresult */
- /* contains the resulttuples */
- PGRES_COPY_OUT,
- PGRES_COPY_IN,
- PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from
- * the backend */
- PGRES_NONFATAL_ERROR,
- PGRES_FATAL_ERROR,
- PGRES_FIELDS_OK, /* field information from a query was
- * successful */
- PGRES_END_TUPLES,
- PGRES_INTERNAL_ERROR
-};
-typedef enum QueryResultCode_ QueryResultCode;
-#endif /*USE _LIBPQ */
struct QResultClass_
{
int rowset_size;
Int4 recent_processed_row_count;
-#ifdef USE_LIBPQ
ExecStatusType status;
-#else
- QueryResultCode status;
-#endif /* USE_LIBPQ*/
char *message;
char *cursor; /* The name of the cursor for select
/* These functions are for retrieving data from the qresult */
-#ifdef USE_LIBPQ
/* Retrieve results from manual_tuples since it has the results */
#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
#define QR_get_value_backend(self,fieldno) (TL_get_fieldval(self->manual_tuples,self->currTuple, fieldno))
#define QR_get_value_backend_row(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
-#else
-#define QR_get_value_manual(self, tupleno, fieldno) (TL_get_fieldval(self->manual_tuples, tupleno, fieldno))
-#define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value)
-#define QR_get_value_backend_row(self, tupleno, fieldno) ((self->backend_tuples + (tupleno * self->num_fields))[fieldno].value)
-#endif /* USE_LIBPQ */
/* These functions are used by both manual and backend results */
#define QR_NumResultCols(self) (CI_get_num_fields(self->fields))
#include <string.h>
#include "dlg_specific.h"
#include "environ.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
#include "statement.h"
#include "bind.h"
#include "qresult.h"
return SQL_INVALID_HANDLE;
}
ci = &(SC_get_conn(stmt)->connInfo);
-#ifndef USE_LIBPQ
- if (stmt->manual_result)
- {
- if (pcrow)
- *pcrow = -1;
- return SQL_SUCCESS;
- }
-#endif /* USE_LIBPQ */
res = SC_get_Curres(stmt);
if (res && pcrow)
{
*/
if (SC_is_fetchcursor(stmt) && !stmt->manual_result)
{
-#ifndef USE_LIBPQ
- if (QR_end_tuples(res))
-#endif /* USE_LIBPQ */
return SQL_NO_DATA_FOUND;
}
else
*/
#include "psqlodbc.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
-
#include <windowsx.h>
#include <string.h>
#include <stdlib.h>
*/
#include "statement.h"
-
#include "bind.h"
-
-#ifdef USE_LIBPQ
-#include "libpqconnection.h"
-#else
#include "connection.h"
-#endif /* USE_LIBPQ */
#include "qresult.h"
#include "convert.h"
#include "environ.h"
rv->phstmt = NULL;
rv->result = NULL;
rv->curres = NULL;
-#ifdef USE_LIBPQ
rv->manual_result = TRUE;
-#else
- rv->manual_result = FALSE;
-#endif /* USE_LIBPQ */
rv->prepare = FALSE;
rv->prepared = FALSE;
rv->status = STMT_ALLOCATED;
* Reset only parameters that have anything to do with results
*/
self->status = STMT_READY;
-#ifdef USE_LIBPQ
- self->manual_result = TRUE; /* very important */
-#else
- self->manual_result = FALSE;
-#endif /* USE_LIBPQ */
-
-
+ self->manual_result = TRUE; /* very important */
self->currTuple = -1;
self->rowset_start = -1;
SC_set_current_col(self, -1);
else
return strdup(notice);
}
-#ifdef USE_LIBPQ
if (conn)
{
PGconn *pgconn = conn->pgconn;
}
}
-#else
- if (conn)
- {
- SocketClass *sock = conn->sock;
-
- if (!detailmsg && CC_get_errormsg(conn) && (CC_get_errormsg(conn))[0] != '\0')
- {
- pos = strlen(msg);
- sprintf(&msg[pos], ";\n%s", CC_get_errormsg(conn));
- }
- if (sock && sock->errormsg && sock->errormsg[0] != '\0')
- {
- pos = strlen(msg);
- sprintf(&msg[pos], ";\n%s", sock->errormsg);
- }
- }
-#endif /* USE_LIBPQ */
return msg[0] ? strdup(msg) : NULL;
}
else
SC_set_errornumber(self, was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND);
-#ifdef USE_LIBPQ
if (QR_command_fatal(res) && PQstatus(conn->pgconn) == CONNECTION_BAD)
{
SC_set_errornumber(self, STMT_BAD_ERROR);
}
-#endif /* USE_LIBPQ */
/* set cursor before the first tuple in the list */
self->currTuple = -1;
else
{
/* Bad Error -- The error message will be in the Connection */
-#ifdef USE_LIBPQ
if (!conn->pgconn)
-#else
- if (!conn->sock)
-#endif /* USE_LIBPQ */
- SC_set_error(self, STMT_BAD_ERROR, CC_get_errormsg(conn));
+ SC_set_error(self, STMT_BAD_ERROR, CC_get_errormsg(conn));
else if (self->statement_type == STMT_TYPE_CREATE)
{
SC_set_error(self, STMT_CREATE_TABLE_ERROR, "Error creating the table");
# Build Types: ALL, CLEAN
# Usage: NMAKE /f win32.mak [CFG=[Release | Debug]]
# [ENCODING=[ANSI | UNICODE]]
-# [MODE=[USE_LIBPQ | USE_SOCK] PG_INC=<PostgreSQL include folder>]
+# [PG_INC=<PG include folder> PG_LIB=<PG lib folder>]
# [ALL | CLEAN]
# Comments: Created by Dave Page, 2001-02-12
-# Modified by Anoop Kumar, 2005-06-27
+# Modified by Siva Kumar , 2005-09-15
+# Modified by Anoop Kumar, 2005-09-19
#
-!MESSAGE Building the PostgreSQL ODBC Driver for Win32...
+!MESSAGE Building the PostgreSQL ODBC Driver for Win32 (Libpq Version)...
!MESSAGE
!IF "$(CFG)" == ""
CFG=Release
!MESSAGE No configuration specified. Defaulting to Release.
!ENDIF
-!IF "$(MODE)" == ""
-MODE=USE_LIBPQ
-!MESSAGE Using Libpq.
-!ENDIF
-
-!IF "$(MODE)" == "USE_LIBPQ"
!IF "$(PG_INC)" == ""
PG_INC=C:\Program Files\PostgreSQL\8.0\include
!MESSAGE Using default PostgreSQL Include directory: $(PG_INC)
PG_LIB=C:\Program Files\PostgreSQL\8.0\lib\ms
!MESSAGE Using default PostgreSQL Library directory: $(PG_LIB)
!ENDIF
-!ENDIF
!IF "$(ENCODING)" == "ANSI"
DLLNAME=psqlodbca
!MESSAGE Building an ANSI driver.
!ENDIF
+
!IF "$(ENCODING)" == "UNICODE"
DLLNAME=psqlodbcw
!MESSAGE Building a Unicode driver.
!ENDIF
+
!IF "$(ENCODING)" == ""
DLLNAME=psqlodbca
ENCODING=ANSI
!MESSAGE
!MESSAGE NMAKE /f win32.mak [CFG=[Release | Debug]]
!MESSAGE [ENCODING=[ANSI | UNICODE]]
-!MESSAGE [MODE=[USE_LIBPQ | USE_SOCK] PG_INC=<PG include folder> PG_LIB=<PG lib folder>]
+!MESSAGE [PG_INC=<PG include folder> PG_LIB=<PG lib folder>]
!MESSAGE [ALL | CLEAN]
!MESSAGE
!MESSAGE Possible choices for configuration are:
!ERROR An invalid configuration was specified.
!ENDIF
-!IF "$(MODE)" != "USE_LIBPQ" && "$(MODE)" != "USE_SOCK"
-!MESSAGE Invalid mode "$(MODE)" specified.
-!MESSAGE You can specify the connection mode and PostgreSQL include folder
-!MESSAGE by defining the macros MODE and PG_INC on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f win32.mak [CFG=[Release | Debug]]
-!MESSAGE [ENCODING=[ANSI | UNICODE]]
-!MESSAGE [MODE=[USE_LIBPQ | USE_SOCK] PG_INC=<PG include folder> PG_LIB=<PG lib folder>]
-!MESSAGE [ALL | CLEAN]
-!MESSAGE
-!MESSAGE Possible choices for mode are:
-!MESSAGE
-!MESSAGE "USE_LIBPQ" (Using Libpq Interface)
-!MESSAGE "USE_SOCK" (Using Socket)
-!MESSAGE
-!ERROR An invalid mode was specified.
-!ENDIF
-
!IF "$(ENCODING)" != "ANSI" && "$(ENCODING)" != "UNICODE"
!MESSAGE Invalid encoding "$(ENCODING)" specified.
!MESSAGE You can specify the connection mode and PostgreSQL include folder
!MESSAGE
!MESSAGE NMAKE /f win32.mak [CFG=[Release | Debug]]
!MESSAGE [ENCODING=[ANSI | UNICODE]]
-!MESSAGE [MODE=[USE_LIBPQ | USE_SOCK] PG_INC=<PG include folder> PG_LIB=<PG lib folder>]
+!MESSAGE [PG_INC=<PG include folder> PG_LIB=<PG lib folder>]
!MESSAGE [ALL | CLEAN]
!MESSAGE
!MESSAGE Possible choices for mode are:
-@erase "$(INTDIR)\execute.obj"
-@erase "$(INTDIR)\info.obj"
-@erase "$(INTDIR)\info30.obj"
- -@erase "$(INTDIR)\lobj.obj"
-@erase "$(INTDIR)\win_md5.obj"
-@erase "$(INTDIR)\misc.obj"
-@erase "$(INTDIR)\pgapi30.obj"
-@erase "$(INTDIR)\qresult.obj"
-@erase "$(INTDIR)\results.obj"
-@erase "$(INTDIR)\setup.obj"
- -@erase "$(INTDIR)\socket.obj"
-@erase "$(INTDIR)\statement.obj"
-@erase "$(INTDIR)\tuple.obj"
-@erase "$(INTDIR)\tuplelist.obj"
CPP=cl.exe
!IF "$(ENCODING)"=="UNICODE"
-
-!IF "$(MODE)"=="USE_LIBPQ"
-CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "$(PG_INC)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "UNICODE_SUPPORT" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "$(PG_INC)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "UNICODE_SUPPORT" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
!ELSE
-CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "UNICODE_SUPPORT" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "$(PG_INC)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
!ENDIF
-!ELSE
-
-!IF "$(MODE)"=="USE_LIBPQ"
-CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "$(PG_INC)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
-!ELSE
-CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
-!ENDIF
-
-!ENDIF
+#!ENDIF
.c{$(INTDIR)}.obj::
$(CPP) @<<
LINK32=link.exe
-!IF "$(MODE)"=="USE_LIBPQ"
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpq.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(DLLNAME).pdb" /machine:I386 /def:"$(DLLNAME).def" /out:"$(OUTDIRBIN)\$(DLLNAME).dll" /implib:"$(OUTDIR)\$(DLLNAME).lib" /libpath:"$(PG_LIB)"
-!ELSE
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(DLLNAME).pdb" /machine:I386 /def:"$(DLLNAME).def" /out:"$(OUTDIRBIN)\$(DLLNAME).dll" /implib:"$(OUTDIR)\$(DLLNAME).lib"
-!ENDIF
-
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpq.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(DLLNAME).pdb" /machine:I386 /def:"$(DLLNAME).def" /out:"$(OUTDIRBIN)\$(DLLNAME).dll" /implib:"$(OUTDIR)\$(DLLNAME).lib" /libpath:"$(PG_LIB)"
DEF_FILE= "$(DLLNAME).def"
LINK32_OBJS= \
"$(INTDIR)\execute.obj" \
"$(INTDIR)\info.obj" \
"$(INTDIR)\info30.obj" \
- "$(INTDIR)\lobj.obj" \
"$(INTDIR)\win_md5.obj" \
"$(INTDIR)\misc.obj" \
"$(INTDIR)\pgapi30.obj" \
"$(INTDIR)\qresult.obj" \
"$(INTDIR)\results.obj" \
"$(INTDIR)\setup.obj" \
- "$(INTDIR)\socket.obj" \
"$(INTDIR)\statement.obj" \
"$(INTDIR)\tuple.obj" \
"$(INTDIR)\tuplelist.obj" \
-@erase "$(INTDIR)\execute.obj"
-@erase "$(INTDIR)\info.obj"
-@erase "$(INTDIR)\info30.obj"
- -@erase "$(INTDIR)\lobj.obj"
-@erase "$(INTDIR)\win_md5.obj"
-@erase "$(INTDIR)\misc.obj"
-@erase "$(INTDIR)\pgapi30.obj"
-@erase "$(INTDIR)\qresult.obj"
-@erase "$(INTDIR)\results.obj"
-@erase "$(INTDIR)\setup.obj"
- -@erase "$(INTDIR)\socket.obj"
-@erase "$(INTDIR)\statement.obj"
-@erase "$(INTDIR)\tuple.obj"
-@erase "$(INTDIR)\tuplelist.obj"
CPP=cl.exe
!IF "$(ENCODING)"=="UNICODE"
-
-!IF "$(MODE)"=="USE_LIBPQ"
-CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PG_INC)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "UNICODE_SUPPORT" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
-!ELSE
-CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "UNICODE_SUPPORT" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
-!ENDIF
-
-!ELSE
-
-!IF "$(MODE)"=="USE_LIBPQ"
-CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PG_INC)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PG_INC)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "UNICODE_SUPPORT" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
!ELSE
-CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "$(MODE)" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
-!ENDIF
-
+CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PG_INC)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "DRIVER_CURSOR_IMPLEMENT" /D "WIN_MULTITHREAD_SUPPORT" $(ADD_DEFINES) /Fp"$(INTDIR)\$(DLLNAME).pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
!ENDIF
LINK32=link.exe
-!IF "$(MODE)"=="USE_LIBPQ"
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpq.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbclibpq.pdb" /debug /machine:I386 /def:"$(DLLNAME).def" /out:"$(OUTDIR)\$(DLLNAME).dll" /implib:"$(OUTDIR)\$(DLLNAME).lib" /pdbtype:sept /libpath:"$(PG_LIB)"
-!ELSE
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\$(DLLNAME).pdb" /debug /machine:I386 /def:"$(DLLNAME).def" /out:"$(OUTDIR)\$(DLLNAME).dll" /implib:"$(OUTDIR)\$(DLLNAME).lib" /pdbtype:sept
-!ENDIF
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpq.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbclibpq.pdb" /debug /machine:I386 /def:"$(DLLNAME).def" /out:"$(OUTDIR)\$(DLLNAME).dll" /implib:"$(OUTDIR)\$(DLLNAME).lib" /pdbtype:sept /libpath:"$(PG_LIB)"
DEF_FILE= "$(DLLNAME).def"
LINK32_OBJS= \
"$(INTDIR)\execute.obj" \
"$(INTDIR)\info.obj" \
"$(INTDIR)\info30.obj" \
- "$(INTDIR)\lobj.obj" \
"$(INTDIR)\win_md5.obj" \
"$(INTDIR)\misc.obj" \
"$(INTDIR)\pgapi30.obj" \
"$(INTDIR)\qresult.obj" \
"$(INTDIR)\results.obj" \
"$(INTDIR)\setup.obj" \
- "$(INTDIR)\socket.obj" \
"$(INTDIR)\statement.obj" \
"$(INTDIR)\tuple.obj" \
"$(INTDIR)\tuplelist.obj" \
$(CPP) $(CPP_PROJ) $(SOURCE)
-SOURCE=lobj.c
-
-"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
SOURCE=misc.c
!IF "$(ENCODING)"=="UNICODE"
-!IF "$(MODE)" == "USE_LIBPQ"
-
!IF "$(CFG)" == "Release"
"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "NDEBUG" /d "MULTIBYTE" /d "USE_LIBPQ" /d "UNICODE_SUPPORT" $(SOURCE)
+ $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "NDEBUG" /d "MULTIBYTE" /d "UNICODE_SUPPORT" $(SOURCE)
!ENDIF
!IF "$(CFG)" == "Debug"
"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "_DEBUG" /d "MULTIBYTE" /d "USE_LIBPQ" /d "UNICODE_SUPPORT" $(SOURCE)
+ $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "_DEBUG" /d "MULTIBYTE" /d "UNICODE_SUPPORT" $(SOURCE)
!ENDIF
!ELSE
-!IF "$(CFG)" == "Release"
-"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "NDEBUG" /d "MULTIBYTE" /d "UNICODE_SUPPORT" $(SOURCE)
-!ENDIF
-
-!IF "$(CFG)" == "Debug"
-"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "_DEBUG" /d "MULTIBYTE" /d "UNICODE_SUPPORT" $(SOURCE)
-!ENDIF
-
-!ENDIF
-
-!ELSE
-
-!IF "$(MODE)" == "USE_LIBPQ"
!IF "$(CFG)" == "Release"
"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "NDEBUG" /d "MULTIBYTE" /d "USE_LIBPQ" $(SOURCE)
+ $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE)
!ENDIF
!IF "$(CFG)" == "Debug"
"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "_DEBUG" /d "MULTIBYTE" /d "USE_LIBPQ" $(SOURCE)
-!ENDIF
-
-!ELSE
-
-!IF "$(CFG)" == "Release"
-"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE)
-!ENDIF
-
-!IF "$(CFG)" == "Debug"
-"$(INTDIR)\$(DLLNAME).res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "_DEBUG" /d "MULTIBYTE" $(SOURCE)
-!ENDIF
-
+ $(RSC) /l 0x809 /fo"$(INTDIR)\$(DLLNAME).res" /d "_DEBUG" /d "MULTIBYTE" $(SOURCE)
!ENDIF
!ENDIF
$(CPP) $(CPP_PROJ) $(SOURCE)
-SOURCE=socket.c
-
-"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
SOURCE=statement.c
"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)"