]> granicus.if.org Git - postgresql/commitdiff
1) Most driver options could be set per DSN.
authorHiroshi Inoue <inoue@tpf.co.jp>
Fri, 7 Sep 2001 06:02:24 +0000 (06:02 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Fri, 7 Sep 2001 06:02:24 +0000 (06:02 +0000)
2) Keep FE/BE protocol more precisely.
3) Improve procedure calls.
4) A trial to avoid PREMATURE execution(#ifdef'd now).

Hiroshi Inoue

30 files changed:
src/interfaces/odbc/bind.c
src/interfaces/odbc/connection.c
src/interfaces/odbc/connection.h
src/interfaces/odbc/convert.c
src/interfaces/odbc/convert.h
src/interfaces/odbc/dlg_specific.c
src/interfaces/odbc/dlg_specific.h
src/interfaces/odbc/drvconn.c
src/interfaces/odbc/environ.c
src/interfaces/odbc/execute.c
src/interfaces/odbc/info.c
src/interfaces/odbc/misc.c
src/interfaces/odbc/misc.h
src/interfaces/odbc/multibyte.c
src/interfaces/odbc/odbcapi.c
src/interfaces/odbc/odbcapi30.c
src/interfaces/odbc/options.c
src/interfaces/odbc/pgtypes.c
src/interfaces/odbc/pgtypes.h
src/interfaces/odbc/psqlodbc.c
src/interfaces/odbc/psqlodbc.h
src/interfaces/odbc/psqlodbc.rc
src/interfaces/odbc/qresult.c
src/interfaces/odbc/resource.h
src/interfaces/odbc/results.c
src/interfaces/odbc/setup.c
src/interfaces/odbc/socket.c
src/interfaces/odbc/socket.h
src/interfaces/odbc/statement.c
src/interfaces/odbc/statement.h

index 2fc340907a3413abf60cb4d6b6df56f0d3edb160..ce1723654865d07fb70103c69ac7f0d4f22ce64b 100644 (file)
@@ -335,8 +335,14 @@ PGAPI_ParamOptions(
        static char *func = "PGAPI_ParamOptions";
        StatementClass  *stmt = (StatementClass *) hstmt;
 
-       mylog("%s: entering...\n", func);
+       mylog("%s: entering... %d %x\n", func, crow, pirow);
 
+       if (crow == 1) /* temporary solution and must be rewritten later */
+       {
+               if (pirow)
+                       *pirow = 1;
+               return SQL_SUCCESS;
+       }
        stmt->errornumber = CONN_UNSUPPORTED_OPTION;
        stmt->errormsg = "Function not implemented";
        SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
index d0373a11bd698c73bc861693bb1616b34f121ea8..9ae6a223a96b8d7c74b03c90cbbd3bac2c73aa4d 100644 (file)
@@ -110,6 +110,7 @@ PGAPI_Connect(
 
        /* get the values for the DSN from the registry */
        getDSNinfo(ci, CONN_OVERWRITE);
+       logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
        /* initialize pg_version from connInfo.protocol    */
        CC_initialize_pg_version(conn);
 
@@ -182,6 +183,7 @@ PGAPI_Disconnect(
                return SQL_ERROR;
        }
 
+       logs_on_off(-1, conn->connInfo.drivers.debug, conn->connInfo.drivers.commlog);
        mylog("%s: about to CC_cleanup\n", func);
 
        /* Close the connection and free statements */
@@ -249,8 +251,8 @@ CC_Constructor()
                rv->transact_status = CONN_IN_AUTOCOMMIT;               /* autocommit by default */
 
                memset(&rv->connInfo, 0, sizeof(ConnInfo));
-
-               rv->sock = SOCK_Constructor();
+memcpy(&(rv->connInfo.drivers), &globals, sizeof(globals));
+               rv->sock = SOCK_Constructor(rv);
                if (!rv->sock)
                        return NULL;
 
@@ -519,31 +521,31 @@ CC_connect(ConnectionClass *self, char do_password)
        {
                qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d, max_longvarchar_size=%d\n",
                         POSTGRESDRIVERVERSION,
-                        globals.fetch_max,
-                        globals.socket_buffersize,
-                        globals.unknown_sizes,
-                        globals.max_varchar_size,
-                        globals.max_longvarchar_size);
+                        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",
-                        globals.disable_optimizer,
-                        globals.ksqo,
-                        globals.unique_index,
-                        globals.use_declarefetch);
+                        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\n",
-                        globals.text_as_longvarchar,
-                        globals.unknowns_as_longvarchar,
-                        globals.bools_as_char);
+                        ci->drivers.text_as_longvarchar,
+                        ci->drivers.unknowns_as_longvarchar,
+                        ci->drivers.bools_as_char);
 
 #ifdef MULTIBYTE
-               check_client_encoding(globals.conn_settings);
+               check_client_encoding(ci->drivers.conn_settings);
                qlog("                extra_systable_prefixes='%s', conn_settings='%s' conn_encoding='%s'\n",
-                        globals.extra_systable_prefixes,
-                        globals.conn_settings,
-                        check_client_encoding(globals.conn_settings));
+                        ci->drivers.extra_systable_prefixes,
+                        ci->drivers.conn_settings,
+                        check_client_encoding(ci->drivers.conn_settings));
 #else
                qlog("                extra_systable_prefixes='%s', conn_settings='%s'\n",
-                        globals.extra_systable_prefixes,
-                        globals.conn_settings);
+                        ci->drivers.extra_systable_prefixes,
+                        ci->drivers.conn_settings);
 #endif
 
                if (self->status != CONN_NOT_CONNECTED)
@@ -568,7 +570,7 @@ CC_connect(ConnectionClass *self, char do_password)
                 */
                if (!self->sock)
                {
-                       self->sock = SOCK_Constructor();
+                       self->sock = SOCK_Constructor(self);
                        if (!self->sock)
                        {
                                self->errornumber = CONNECTION_SERVER_NOT_REACHED;
@@ -646,17 +648,21 @@ CC_connect(ConnectionClass *self, char do_password)
         */
 
        if (!PROTOCOL_62(ci))
+       {
+               BOOL before_64 = PG_VERSION_LT(self, 6.4), ReadyForQuery = FALSE;
                do
                {
                        if (do_password)
                                beresp = 'R';
                        else
+                       {
                                beresp = SOCK_get_char(sock);
+                               mylog("auth got '%c'\n", beresp);
+                       }
 
                        switch (beresp)
                        {
                                case 'E':
-                                       mylog("auth got 'E'\n");
 
                                        SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
                                        self->errornumber = CONN_INVALID_AUTHENTICATION;
@@ -673,7 +679,6 @@ CC_connect(ConnectionClass *self, char do_password)
                                        }
                                        else
                                        {
-                                               mylog("auth got 'R'\n");
 
                                                areq = SOCK_get_int(sock, 4);
                                                if (areq == AUTH_REQ_MD5)
@@ -734,13 +739,28 @@ CC_connect(ConnectionClass *self, char do_password)
                                                        return 0;
                                        }
                                        break;
+                               case 'K':                       /* Secret key (6.4 protocol) */
+                                       (void) SOCK_get_int(sock, 4);   /* pid */
+                                       (void) SOCK_get_int(sock, 4);   /* key */
+
+                                       break;
+                               case 'Z':                       /* Backend is ready for new query (6.4) */
+                                       ReadyForQuery = TRUE;
+                                       break;
                                default:
                                        self->errormsg = "Unexpected protocol character during authentication";
                                        self->errornumber = CONN_INVALID_AUTHENTICATION;
                                        return 0;
                        }
 
-               } while (areq != AUTH_REQ_OK);
+                       /* 
+                        *      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 */
@@ -917,13 +937,14 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
 QResultClass *
 CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
 {
-       QResultClass *result_in,
-                          *res = NULL;
+       QResultClass *result_in = NULL, *res = NULL, *retres = NULL;
        char            swallow;
        int                     id;
        SocketClass *sock = self->sock;
-       int             maxlen;
-       BOOL            msg_truncated;
+       int             maxlen, empty_reqs;
+       BOOL            msg_truncated, ReadyToReturn,
+                       tuples_return = FALSE, query_completed = FALSE,
+                       before_64 = PG_VERSION_LT(self, 6.4);
 
        /* ERROR_MSG_LENGTH is suffcient */
        static char msgbuffer[ERROR_MSG_LENGTH + 1];
@@ -976,7 +997,11 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
 
        mylog("send_query: done sending query\n");
 
-       while (1)
+       ReadyToReturn = FALSE;
+       empty_reqs = 0;
+       if (strcmp(query, " ") == 0)
+               empty_reqs = 1;
+       while (!ReadyToReturn)
        {
                /* what type of message is coming now ? */
                id = SOCK_get_char(sock);
@@ -985,12 +1010,12 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
                {
                        self->errornumber = CONNECTION_NO_RESPONSE;
                        self->errormsg = "No response from the backend";
-                       if (res)
-                               QR_Destructor(res);
 
                        mylog("send_query: 'id' - %s\n", self->errormsg);
                        CC_set_no_trans(self);
-                       return NULL;
+                       ReadyToReturn = TRUE;
+                       retres = NULL;
+                       break;
                }
 
                mylog("send_query: got id = '%c'\n", id);
@@ -1012,9 +1037,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
                                        self->errormsg = "No response from backend while receiving a portal query command";
                                        mylog("send_query: 'C' - %s\n", self->errormsg);
                                        CC_set_no_trans(self);
-                                       if (res)
-                                               QR_Destructor(res);
-                                       return NULL;
+                                       ReadyToReturn = TRUE;
+                                       retres = NULL;
+                                       break;
                                }
                                else
                                {
@@ -1031,7 +1056,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
                                        if (QR_command_successful(res))
                                                QR_set_status(res, PGRES_COMMAND_OK);
                                        QR_set_command(res, cmdbuffer);
-
+                                       query_completed = TRUE;
+                                       if (!before_64)
+                                               break;
                                        /*
                                         * (Quotation from the original comments) since
                                         * backend may produce more than one result for some
@@ -1041,8 +1068,13 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
                                         */
 
 
-                                       SOCK_put_string(sock, "Q ");
-                                       SOCK_flush_output(sock);
+                                       if (empty_reqs == 0)
+                                       {
+                                               SOCK_put_string(sock, "Q ");
+                                               SOCK_flush_output(sock);
+                                               empty_reqs++;
+                                       }
+                                       break;
 
                                        while (!clear)
                                        {
@@ -1071,7 +1103,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
                                                                break;
                                                        case 'E':
                                                                msg_truncated = SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
-mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
+                                                               mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
                                                                qlog("ERROR from backend during clear: '%s'\n", msgbuffer);
 
                                                                /*
@@ -1098,14 +1130,21 @@ mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
                                        }
 
                                        mylog("send_query: returning res = %u\n", res);
-                                       return res;
+                                       break;
                                }
-                       case 'K':                       /* Secret key (6.4 protocol) */
-                               (void) SOCK_get_int(sock, 4);   /* pid */
-                               (void) SOCK_get_int(sock, 4);   /* key */
-
-                               break;
                        case 'Z':                       /* Backend is ready for new query (6.4) */
+                               if (empty_reqs == 0)
+                               {
+                                       ReadyToReturn = TRUE;
+                                       if (res && QR_get_aborted(res))
+                                               retres = res;
+                                       else if (tuples_return)
+                                               retres = result_in;
+                                       else if (query_completed)
+                                               retres = res;
+                                       else
+                                               ReadyToReturn = FALSE;
+                               }
                                break;
                        case 'N':                       /* NOTICE: */
                                msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
@@ -1126,22 +1165,26 @@ mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
                        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 (!res)
+                                       res = QR_Constructor();
                                if ((swallow != '\0') || SOCK_get_errcode(sock) != 0)
                                {
                                        self->errornumber = CONNECTION_BACKEND_CRAZY;
                                        self->errormsg = "Unexpected protocol character from backend (send_query - I)";
-                                       if (!res)
-                                               res = QR_Constructor();
                                        QR_set_status(res, PGRES_FATAL_ERROR);
-                                       return res;
+                                       ReadyToReturn = TRUE;
+                                       retres = res;
+                                       break;
                                }
                                else
                                {
                                        /* We return the empty query */
-                                       if (!res)
-                                               res = QR_Constructor();
                                        QR_set_status(res, PGRES_EMPTY_QUERY);
-                                       return res;
+                               }
+                               if (empty_reqs > 0)
+                               {
+                                       if (--empty_reqs == 0)
+                                               query_completed = TRUE;
                                }
                                break;
                        case 'E':
@@ -1174,7 +1217,8 @@ mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
                                while (msg_truncated)
                                        msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
 
-                               return res;             /* instead of NULL. Zoltan */
+                               query_completed = TRUE;
+                               break;
 
                        case 'P':                       /* get the Portal name */
                                SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
@@ -1190,7 +1234,9 @@ mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
                                        {
                                                self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
                                                self->errormsg = "Could not create result info in send_query.";
-                                               return NULL;
+                                               ReadyToReturn = TRUE;
+                                               retres = NULL;
+                                               break;
                                        }
 
                                        if (qi)
@@ -1200,43 +1246,87 @@ mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
                                        {
                                                self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
                                                self->errormsg = QR_get_message(result_in);
-                                               return NULL;
+                                               ReadyToReturn = TRUE;
+                                               retres = NULL;
+                                               break;
                                        }
                                }
                                else
                                {                               /* next fetch, so reuse an existing result */
+                                       /*
+                                        *      called from QR_next_tuple
+                                        *      and must return immediately.
+                                        */
+                                       ReadyToReturn = TRUE;
                                        if (!QR_fetch_tuples(result_in, NULL, NULL))
                                        {
                                                self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
                                                self->errormsg = QR_get_message(result_in);
-                                               return NULL;
+                                               retres = NULL;
+                                               break;
                                        }
+                                       retres = result_in;
                                }
 
-                               return result_in;
+                               tuples_return = TRUE;
+                               break;
                        case 'D':                       /* Copy in command began successfully */
                                if (!res)
                                        res = QR_Constructor();
                                if (QR_command_successful(res))
                                        QR_set_status(res, PGRES_COPY_IN);
-                               return res;
+                               ReadyToReturn = TRUE;
+                               retres = res;
+                               break;
                        case 'B':                       /* Copy out command began successfully */
                                if (!res)
                                        res = QR_Constructor();
                                if (QR_command_successful(res))
                                        QR_set_status(res, PGRES_COPY_OUT);
-                               return res;
+                               ReadyToReturn = TRUE;
+                               retres = res;
+                               break;
                        default:
                                self->errornumber = CONNECTION_BACKEND_CRAZY;
                                self->errormsg = "Unexpected protocol character from backend (send_query)";
                                CC_set_no_trans(self);
 
                                mylog("send_query: error - %s\n", self->errormsg);
-                               if (res)
-                                       QR_Destructor(res);
-                               return NULL;
+                               ReadyToReturn = TRUE;
+                               retres = NULL;
+                               break;
+               }
+               /*
+                *      There were no ReadyForQuery response before 6.4.
+                */
+               if (before_64)
+               {
+                       if (empty_reqs == 0 && (query_completed || tuples_return))
+                               break;
                }
        }
+       /*
+        *      set notice message to result_in.
+        */
+       if (result_in && res && retres == result_in)
+       {
+               if (QR_command_successful(result_in))
+                       QR_set_status(result_in, QR_get_status(res));
+               QR_set_notice(result_in, QR_get_notice(res));
+       }
+       /*
+        *      Cleanup garbage results before returning.
+        */
+       if (res && retres != res)
+               QR_Destructor(res);
+       if (result_in && retres != result_in)
+       {
+               if (qi && qi->result_in)
+                       ;
+               else
+                       QR_Destructor(result_in);
+       }
+       return retres;
 }
 
 
@@ -1430,7 +1520,7 @@ CC_send_settings(ConnectionClass *self)
        mylog("%s: result %d, status %d from set DateStyle\n", func, result, status);
 
        /* Disable genetic optimizer based on global flag */
-       if (globals.disable_optimizer)
+       if (ci->drivers.disable_optimizer)
        {
                result = PGAPI_ExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS);
                if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
@@ -1441,7 +1531,7 @@ CC_send_settings(ConnectionClass *self)
        }
 
        /* KSQO */
-       if (globals.ksqo)
+       if (ci->drivers.ksqo)
        {
                result = PGAPI_ExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS);
                if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
@@ -1452,9 +1542,9 @@ CC_send_settings(ConnectionClass *self)
        }
 
        /* Global settings */
-       if (globals.conn_settings[0] != '\0')
+       if (ci->drivers.conn_settings[0] != '\0')
        {
-               cs = strdup(globals.conn_settings);
+               cs = strdup(ci->drivers.conn_settings);
                ptr = strtok(cs, ";");
                while (ptr)
                {
index 4da6a7b7a8538ebe461041b3249f9cb306e8268d..902480896fd0eeb107cab6e8f8e18e4791576883 100644 (file)
@@ -159,6 +159,7 @@ typedef struct
        char            translation_dll[MEDIUM_REGISTRY_LEN];
        char            translation_option[SMALL_REGISTRY_LEN];
        char            focus_password;
+       GLOBAL_VALUES   drivers; /* moved from driver's option */
 } ConnInfo;
 
 /*     Macro to determine is the connection using 6.2 protocol? */
index 799b8c5b77227b1d28bfded2d75b8439a57fdf3d..d0abad249e287acd4a14a7f39e03d38af32f1616 100644 (file)
@@ -58,7 +58,6 @@ typedef signed char SCHAR;
 #endif
 #endif
 
-extern GLOBAL_VALUES globals;
 
 /*
  *     How to map ODBC scalar functions {fn func(args)} to Postgres.
@@ -132,10 +131,10 @@ char         *mapFuncs[][2] = {
        {0, 0}
 };
 
-char      *mapFunction(char *func);
-unsigned int conv_from_octal(unsigned char *s);
-unsigned int conv_from_hex(unsigned char *s);
-char      *conv_to_octal(unsigned char val);
+static char   *mapFunction(const char *func);
+static unsigned int conv_from_octal(const unsigned char *s);
+static unsigned int conv_from_hex(const unsigned char *s);
+static char       *conv_to_octal(unsigned char val);
 
 /*---------
  *                     A Guide for date/time/timestamp conversions
@@ -180,14 +179,16 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
        struct tm  *tim;
        int                     pcbValueOffset,
                                rgbValueOffset;
-       char       *rgbValueBindRow,
-                          *ptr;
+       char       *rgbValueBindRow;
+       const char      *ptr;
        int                     bind_row = stmt->bind_row;
        int                     bind_size = stmt->options.bind_size;
        int                     result = COPY_OK;
        BOOL            changed;
        static          char *tempBuf= NULL;
        static          unsigned int tempBuflen = 0;
+       const char *neutstr = value;
+       char    midtemp[16];
 
        if (!tempBuf)
                tempBuflen = 0;
@@ -298,11 +299,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                                        This is bad ;)
 
                                */
-                                       
-                               if (s[0] == 'T' || s[0] == 't' || s[0] == '1')
-                                       s[0] = '1';
+
+                               strcpy(midtemp, value);
+                               if (s[0] == 'f' || s[0] == 'F' || s[0] == 'n' || s[0] == 'N' || s[0] == '0')
+                                       midtemp[0] = '0';
                                else
-                                   s[0] = '0';
+                                       midtemp[0] = '1';
+                               neutstr = midtemp;
 
                        }
                        break;
@@ -312,7 +315,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                        {
                                int                     nval,
                                                        i;
-                               char       *vp;
+                               const char      *vp;
 
                                /* this is an array of eight integers */
                                short      *short_array = (short *) ((char *) rgbValue + rgbValueOffset);
@@ -423,7 +426,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                                len = 1;
                                if (cbValueMax > len)
                                {
-                                       strcpy(rgbValueBindRow, value);
+                                       strcpy(rgbValueBindRow, neutstr);
                                        mylog("PG_TYPE_BOOL: rgbValueBindRow = '%s'\n", rgbValueBindRow);
                                }
                                break;
@@ -607,13 +610,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                        case SQL_C_BIT:
                                len = 1;
                                if (bind_size > 0)
-                                       *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(value);
+                                       *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neutstr);
                                else
-                                       *((UCHAR *) rgbValue + bind_row) = atoi(value);
+                                       *((UCHAR *) rgbValue + bind_row) = atoi(neutstr);
 
                                /*
-                                * mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n",
-                                * atoi(value), cbValueMax, *((UCHAR *)rgbValue));
+                                * mylog("SQL_C_BIT: bind_row = %d val = %d, cb = %d, rgb=%d\n",
+                                * bind_row, atoi(neutstr), cbValueMax, *((UCHAR *)rgbValue));
                                 */
                                break;
 
@@ -966,10 +969,17 @@ copy_statement_with_parameters(StatementClass *stmt)
        int                     lobj_fd,
                                retval;
        BOOL    check_select_into = FALSE; /* select into check */
+       BOOL    proc_no_param = TRUE;
        unsigned int    declare_pos;
+       ConnectionClass *conn = SC_get_conn(stmt);
+       ConnInfo        *ci = &(conn->connInfo);
+       BOOL    prepare_dummy_cursor = FALSE;
 #ifdef DRIVER_CURSOR_IMPLEMENT
        BOOL ins_ctrl = FALSE;
 #endif /* DRIVER_CURSOR_IMPLEMENT */
+#ifdef PREPARE_TRIAL
+       prepare_dummy_cursor = stmt->pre_executing;
+#endif /* PREPARE_TRIAL */
 
 
        if (!old_statement)
@@ -986,22 +996,6 @@ copy_statement_with_parameters(StatementClass *stmt)
        st.d = tim->tm_mday;
        st.y = tim->tm_year + 1900;
 
-       /* If the application hasn't set a cursor name, then generate one */
-       if (stmt->cursor_name[0] == '\0')
-               sprintf(stmt->cursor_name, "SQL_CUR%p", stmt);
-
-       oldstmtlen = strlen(old_statement);
-       CVT_INIT(oldstmtlen);
-       /* For selects, prepend a declare cursor to the statement */
-       if (stmt->statement_type == STMT_TYPE_SELECT && globals.use_declarefetch)
-       {
-               sprintf(new_statement, "declare %s cursor for ", stmt->cursor_name);
-               npos = strlen(new_statement);
-               check_select_into = TRUE;
-               declare_pos = npos;
-       }
-       param_number = -1;
-
 #ifdef DRIVER_CURSOR_IMPLEMENT
        if (stmt->statement_type != STMT_TYPE_SELECT)
        {
@@ -1021,6 +1015,34 @@ copy_statement_with_parameters(StatementClass *stmt)
                else ins_ctrl = TRUE;
        }
 #endif /* DRIVER_CURSOR_IMPLEMENT */
+
+       /* If the application hasn't set a cursor name, then generate one */
+       if (stmt->cursor_name[0] == '\0')
+               sprintf(stmt->cursor_name, "SQL_CUR%p", stmt);
+       oldstmtlen = strlen(old_statement);
+       CVT_INIT(oldstmtlen);
+       stmt->miscinfo = 0;
+       /* For selects, prepend a declare cursor to the statement */
+       if (stmt->statement_type == STMT_TYPE_SELECT)
+       {
+               SC_set_pre_executable(stmt);
+               if (prepare_dummy_cursor || ci->drivers.use_declarefetch)
+               {
+                       if (prepare_dummy_cursor)
+                       {
+                               if (!CC_is_in_trans(conn))
+                                       strcpy(new_statement, "begin;");
+                       }
+                       else if (ci->drivers.use_declarefetch)
+                               SC_set_fetchcursor(stmt);
+                       sprintf(new_statement, "%s declare %s cursor for ",
+                                new_statement, stmt->cursor_name);
+                       npos = strlen(new_statement);
+                       check_select_into = TRUE;
+                       declare_pos = npos;
+               }
+       }
+       param_number = -1;
 #ifdef MULTIBYTE
        multibyte_init();
 #endif
@@ -1087,7 +1109,9 @@ copy_statement_with_parameters(StatementClass *stmt)
                        /* procedure calls */
                        if (stmt->statement_type == STMT_TYPE_PROCCALL)
                        {
+                               int     lit_call_len = 4;
                                while (isspace((unsigned char) old_statement[++opos]));
+                               /* '=?' to accept return values exists ? */
                                if (old_statement[opos] == '?')
                                {
                                        param_number++;
@@ -1099,13 +1123,16 @@ copy_statement_with_parameters(StatementClass *stmt)
                                        }
                                        while (isspace((unsigned char) old_statement[++opos]));
                                }
-                               if (strnicmp(&old_statement[opos], "call", 4))
+                               if (strnicmp(&old_statement[opos], "call", lit_call_len) ||
+                                       !isspace(old_statement[opos + lit_call_len]))
                                {
                                        opos--;
                                        continue;
                                }
-                               opos += (4 - 1);
-                               CVT_APPEND_STR("SELECT");
+                               opos += lit_call_len; 
+                               CVT_APPEND_STR("SELECT ");
+                               if (strchr(&old_statement[opos], '('))
+                                       proc_no_param = FALSE;
                                continue; 
                        }
                        *end = '\0';
@@ -1128,7 +1155,11 @@ copy_statement_with_parameters(StatementClass *stmt)
                }
                /* End of a procedure call */
                else if (oldchar == '}' && stmt->statement_type == STMT_TYPE_PROCCALL)
+               {
+                       if (proc_no_param)
+                               CVT_APPEND_STR("()");
                        continue;
+               }
 
                /*
                 * Can you have parameter markers inside of quotes?  I dont think
@@ -1151,6 +1182,8 @@ copy_statement_with_parameters(StatementClass *stmt)
                                 into_table_from(&old_statement[opos]))
                        {
                                stmt->statement_type = STMT_TYPE_CREATE;
+                               SC_no_pre_executable(stmt);
+                               SC_no_fetchcursor(stmt);
                                stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
                                memmove(new_statement, new_statement + declare_pos, npos - declare_pos);
                                npos -= declare_pos;
@@ -1446,12 +1479,12 @@ copy_statement_with_parameters(StatementClass *stmt)
                                else
                                {
                                        /* begin transaction if needed */
-                                       if (!CC_is_in_trans(stmt->hdbc))
+                                       if (!CC_is_in_trans(conn))
                                        {
                                                QResultClass *res;
                                                char            ok;
 
-                                               res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
+                                               res = CC_send_query(conn, "BEGIN", NULL);
                                                if (!res)
                                                {
                                                        stmt->errormsg = "Could not begin (in-line) a transaction";
@@ -1469,11 +1502,11 @@ copy_statement_with_parameters(StatementClass *stmt)
                                                        return SQL_ERROR;
                                                }
 
-                                               CC_set_in_trans(stmt->hdbc);
+                                               CC_set_in_trans(conn);
                                        }
 
                                        /* store the oid */
-                                       lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE);
+                                       lobj_oid = lo_creat(conn, INV_READ | INV_WRITE);
                                        if (lobj_oid == 0)
                                        {
                                                stmt->errornumber = STMT_EXEC_ERROR;
@@ -1483,7 +1516,7 @@ copy_statement_with_parameters(StatementClass *stmt)
                                        }
 
                                        /* store the fd */
-                                       lobj_fd = lo_open(stmt->hdbc, lobj_oid, INV_WRITE);
+                                       lobj_fd = lo_open(conn, lobj_oid, INV_WRITE);
                                        if (lobj_fd < 0)
                                        {
                                                stmt->errornumber = STMT_EXEC_ERROR;
@@ -1492,17 +1525,17 @@ copy_statement_with_parameters(StatementClass *stmt)
                                                return SQL_ERROR;
                                        }
 
-                                       retval = lo_write(stmt->hdbc, lobj_fd, buffer, used);
+                                       retval = lo_write(conn, lobj_fd, buffer, used);
 
-                                       lo_close(stmt->hdbc, lobj_fd);
+                                       lo_close(conn, lobj_fd);
 
                                        /* commit transaction if needed */
-                                       if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
+                                       if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn))
                                        {
                                                QResultClass *res;
                                                char            ok;
 
-                                               res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+                                               res = CC_send_query(conn, "COMMIT", NULL);
                                                if (!res)
                                                {
                                                        stmt->errormsg = "Could not commit (in-line) a transaction";
@@ -1520,7 +1553,7 @@ copy_statement_with_parameters(StatementClass *stmt)
                                                        return SQL_ERROR;
                                                }
 
-                                               CC_set_no_trans(stmt->hdbc);
+                                               CC_set_no_trans(conn);
                                        }
                                }
 
@@ -1589,11 +1622,11 @@ copy_statement_with_parameters(StatementClass *stmt)
        /* make sure new_statement is always null-terminated */
        CVT_TERMINATE
 
-       if (stmt->hdbc->DriverToDataSource != NULL)
+       if (conn->DriverToDataSource != NULL)
        {
                int                     length = strlen(new_statement);
 
-               stmt->hdbc->DriverToDataSource(stmt->hdbc->translation_option,
+               conn->DriverToDataSource(conn->translation_option,
                                                                           SQL_CHAR,
                                                                           new_statement, length,
                                                                           new_statement, length, NULL,
@@ -1604,12 +1637,25 @@ copy_statement_with_parameters(StatementClass *stmt)
        if (ins_ctrl)
                stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
 #endif /* DRIVER_CURSOR_IMPLEMENT */
+#ifdef PREPARE_TRIAL
+       if (prepare_dummy_cursor && SC_is_pre_executable(stmt))
+       {
+               char fetchstr[128];     
+               sprintf(fetchstr, ";fetch backward in %s;close %s;",
+                               stmt->cursor_name, stmt->cursor_name);
+               if (!CC_is_in_trans(conn))
+                       strcat(fetchstr, "commit;");
+               CVT_APPEND_STR(fetchstr);
+               stmt->inaccurate_result = TRUE;
+       }
+#endif /* PREPARE_TRIAL */
+
        return SQL_SUCCESS;
 }
 
 
 char *
-mapFunction(char *func)
+mapFunction(const char *func)
 {
        int                     i;
 
@@ -1850,7 +1896,7 @@ convert_linefeeds(const char *si, char *dst, size_t max, BOOL *changed)
  *     Plus, escape any special characters.
  */
 int
-convert_special_chars(char *si, char *dst, int used)
+convert_special_chars(const char *si, char *dst, int used)
 {
        size_t          i = 0,
                                out = 0,
@@ -1904,7 +1950,7 @@ convert_special_chars(char *si, char *dst, int used)
 
 /*     !!! Need to implement this function !!!  */
 int
-convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax)
+convert_pgbinary_to_char(const char *value, char *rgbValue, int cbValueMax)
 {
        mylog("convert_pgbinary_to_char: value = '%s'\n", value);
 
@@ -1914,7 +1960,7 @@ convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax)
 
 
 unsigned int
-conv_from_octal(unsigned char *s)
+conv_from_octal(const unsigned char *s)
 {
        int                     i,
                                y = 0;
@@ -1928,7 +1974,7 @@ conv_from_octal(unsigned char *s)
 
 
 unsigned int
-conv_from_hex(unsigned char *s)
+conv_from_hex(const unsigned char *s)
 {
        int                     i,
                                y = 0,
@@ -1952,7 +1998,7 @@ conv_from_hex(unsigned char *s)
 
 /*     convert octal escapes to bytes */
 int
-convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax)
+convert_from_pgbinary(const unsigned char *value, unsigned char *rgbValue, int cbValueMax)
 {
        size_t          i, ilen = strlen(value);
        int                     o = 0;
@@ -2007,7 +2053,7 @@ conv_to_octal(unsigned char val)
 
 /*     convert non-ascii bytes to octal escape sequences */
 int
-convert_to_pgbinary(unsigned char *in, char *out, int len)
+convert_to_pgbinary(const unsigned char *in, char *out, int len)
 {
        int                     i,
                                o = 0;
@@ -2031,7 +2077,7 @@ convert_to_pgbinary(unsigned char *in, char *out, int len)
 
 
 void
-encode(char *in, char *out)
+encode(const char *in, char *out)
 {
        unsigned int i, ilen = strlen(in),
                                o = 0;
@@ -2058,7 +2104,7 @@ encode(char *in, char *out)
 
 
 void
-decode(char *in, char *out)
+decode(const char *in, char *out)
 {
        unsigned int i, ilen = strlen(in),
                                o = 0;
@@ -2104,7 +2150,8 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
                                result,
                                left = -1;
        BindInfoClass *bindInfo = NULL;
-
+       ConnectionClass *conn = SC_get_conn(stmt);
+       ConnInfo        *ci = &(conn->connInfo);
 
        /* If using SQLGetData, then current_col will be set */
        if (stmt->current_col >= 0)
@@ -2121,12 +2168,12 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
        if (!bindInfo || bindInfo->data_left == -1)
        {
                /* begin transaction if needed */
-               if (!CC_is_in_trans(stmt->hdbc))
+               if (!CC_is_in_trans(conn))
                {
                        QResultClass *res;
                        char            ok;
 
-                       res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
+                       res = CC_send_query(conn, "BEGIN", NULL);
                        if (!res)
                        {
                                stmt->errormsg = "Could not begin (in-line) a transaction";
@@ -2142,11 +2189,11 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
                                return COPY_GENERAL_ERROR;
                        }
 
-                       CC_set_in_trans(stmt->hdbc);
+                       CC_set_in_trans(conn);
                }
 
                oid = atoi(value);
-               stmt->lobj_fd = lo_open(stmt->hdbc, oid, INV_READ);
+               stmt->lobj_fd = lo_open(conn, oid, INV_READ);
                if (stmt->lobj_fd < 0)
                {
                        stmt->errornumber = STMT_EXEC_ERROR;
@@ -2155,15 +2202,15 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
                }
 
                /* Get the size */
-               retval = lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_END);
+               retval = lo_lseek(conn, stmt->lobj_fd, 0L, SEEK_END);
                if (retval >= 0)
                {
-                       left = lo_tell(stmt->hdbc, stmt->lobj_fd);
+                       left = lo_tell(conn, stmt->lobj_fd);
                        if (bindInfo)
                                bindInfo->data_left = left;
 
                        /* return to beginning */
-                       lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_SET);
+                       lo_lseek(conn, stmt->lobj_fd, 0L, SEEK_SET);
                }
        }
 
@@ -2177,18 +2224,18 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
                return COPY_GENERAL_ERROR;
        }
 
-       retval = lo_read(stmt->hdbc, stmt->lobj_fd, (char *) rgbValue, cbValueMax);
+       retval = lo_read(conn, stmt->lobj_fd, (char *) rgbValue, cbValueMax);
        if (retval < 0)
        {
-               lo_close(stmt->hdbc, stmt->lobj_fd);
+               lo_close(conn, stmt->lobj_fd);
 
                /* commit transaction if needed */
-               if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
+               if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn))
                {
                        QResultClass *res;
                        char            ok;
 
-                       res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+                       res = CC_send_query(conn, "COMMIT", NULL);
                        if (!res)
                        {
                                stmt->errormsg = "Could not commit (in-line) a transaction";
@@ -2204,7 +2251,7 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
                                return COPY_GENERAL_ERROR;
                        }
 
-                       CC_set_no_trans(stmt->hdbc);
+                       CC_set_no_trans(conn);
                }
 
                stmt->lobj_fd = -1;
@@ -2227,15 +2274,15 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
 
        if (!bindInfo || bindInfo->data_left == 0)
        {
-               lo_close(stmt->hdbc, stmt->lobj_fd);
+               lo_close(conn, stmt->lobj_fd);
 
                /* commit transaction if needed */
-               if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
+               if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(conn))
                {
                        QResultClass *res;
                        char            ok;
 
-                       res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+                       res = CC_send_query(conn, "COMMIT", NULL);
                        if (!res)
                        {
                                stmt->errormsg = "Could not commit (in-line) a transaction";
@@ -2251,7 +2298,7 @@ convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
                                return COPY_GENERAL_ERROR;
                        }
 
-                       CC_set_no_trans(stmt->hdbc);
+                       CC_set_no_trans(conn);
                }
 
                stmt->lobj_fd = -1;             /* prevent further reading */
index 8a7d15e5d4b8f74e9eb495b0e5715c68ce76159f..aaf1518344414242e7f0ad837de1de035d1a27dc 100644 (file)
@@ -29,8 +29,8 @@ typedef struct
        int                     ss;
 } SIMPLE_TIME;
 
-int                    copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
-int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
+int                    copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, const void *value, int col);
+int copy_and_convert_field(StatementClass *stmt, Int4 field_type, const void *value, Int2 fCType,
                                           PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
 
 int                    copy_statement_with_parameters(StatementClass *stmt);
@@ -38,14 +38,14 @@ char           *convert_escape(char *value);
 char      *convert_money(char *s);
 char           parse_datetime(char *buf, SIMPLE_TIME *st);
 int            convert_linefeeds(const char *s, char *dst, size_t max, BOOL *changed);
-int       convert_special_chars(char *si, char *dst, int used);
-
-int                    convert_pgbinary_to_char(char *value, char *rgbValue, int cbValueMax);
-int                    convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue, int cbValueMax);
-int                    convert_to_pgbinary(unsigned char *in, char *out, int len);
-void           encode(char *in, char *out);
-void           decode(char *in, char *out);
-int convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
+int       convert_special_chars(const char *si, char *dst, int used);
+
+int                    convert_pgbinary_to_char(const char *value, char *rgbValue, int cbValueMax);
+int                    convert_from_pgbinary(const unsigned char *value, unsigned char *rgbValue, int cbValueMax);
+int                    convert_to_pgbinary(const unsigned char *in, char *out, int len);
+void           encode(const char *in, char *out);
+void           decode(const char *in, char *out);
+int convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue,
                   SDWORD cbValueMax, SDWORD *pcbValue);
 
 #endif
index d28fcf966c43670baf38c0cfef3d6297c11f0f1d..facf77dd09983a70b634fc10ddda044091ed5ed4 100644 (file)
 #endif
 
 extern GLOBAL_VALUES globals;
-
+#ifdef WIN32
+static int driver_optionsDraw(HWND, const ConnInfo *, int src, BOOL enable);
+static int driver_options_update(HWND hdlg, ConnInfo *ci, BOOL);
+#endif
+static void updateCommons(const ConnInfo *ci);
 
 #ifdef WIN32
 void
-SetDlgStuff(HWND hdlg, ConnInfo *ci)
+SetDlgStuff(HWND hdlg, const ConnInfo *ci)
 {
 
        /*
@@ -87,145 +91,204 @@ GetDlgStuff(HWND hdlg, ConnInfo *ci)
 }
 
 
-int                    CALLBACK
-driver_optionsProc(HWND hdlg,
-                                  WORD wMsg,
-                                  WPARAM wParam,
-                                  LPARAM lParam)
+static int
+driver_optionsDraw(HWND hdlg, const ConnInfo *ci, int src, BOOL enable)
 {
-       switch (wMsg)
+       const GLOBAL_VALUES     *comval;
+       static BOOL     defset = FALSE;
+       static GLOBAL_VALUES    defval;
+               
+       switch (src)
        {
-                       case WM_INITDIALOG:
-
-                       CheckDlgButton(hdlg, DRV_COMMLOG, globals.commlog);
-                       CheckDlgButton(hdlg, DRV_OPTIMIZER, globals.disable_optimizer);
-                       CheckDlgButton(hdlg, DRV_KSQO, globals.ksqo);
-                       CheckDlgButton(hdlg, DRV_UNIQUEINDEX, globals.unique_index);
-                       CheckDlgButton(hdlg, DRV_READONLY, globals.onlyread);
-                       CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, globals.use_declarefetch);
-
-                       /* Unknown (Default) Data Type sizes */
-                       switch (globals.unknown_sizes)
+               case 0: /* driver common */
+                       comval = &globals;
+                       break;
+               case 1: /* dsn specific */
+                       comval = &(ci->drivers);
+                       break;
+               case 2: /* default */
+                       if (!defset)
                        {
-                               case UNKNOWNS_AS_DONTKNOW:
-                                       CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
-                                       break;
-                               case UNKNOWNS_AS_LONGEST:
-                                       CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 1);
-                                       break;
-                               case UNKNOWNS_AS_MAX:
-                               default:
-                                       CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 1);
-                                       break;
+                               defval.commlog = DEFAULT_COMMLOG;
+                               defval.disable_optimizer = DEFAULT_OPTIMIZER;
+                               defval.ksqo = DEFAULT_KSQO;
+                               defval.unique_index = DEFAULT_UNIQUEINDEX;
+                               defval.onlyread = DEFAULT_READONLY;
+                               defval.use_declarefetch = DEFAULT_USEDECLAREFETCH;
+
+                               defval.parse = DEFAULT_PARSE;
+                               defval.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
+                               defval.debug = DEFAULT_DEBUG;
+
+                               /* Unknown Sizes */
+                               defval.unknown_sizes = DEFAULT_UNKNOWNSIZES;
+                               defval.text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
+                               defval.unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
+                               defval.bools_as_char = DEFAULT_BOOLSASCHAR;
                        }
+                       defset = TRUE;
+                       comval = &defval;
+                       break;
+       }
 
-                       CheckDlgButton(hdlg, DRV_TEXT_LONGVARCHAR, globals.text_as_longvarchar);
-                       CheckDlgButton(hdlg, DRV_UNKNOWNS_LONGVARCHAR, globals.unknowns_as_longvarchar);
-                       CheckDlgButton(hdlg, DRV_BOOLS_CHAR, globals.bools_as_char);
+       CheckDlgButton(hdlg, DRV_COMMLOG, comval->commlog);
+       CheckDlgButton(hdlg, DRV_OPTIMIZER, comval->disable_optimizer);
+       CheckDlgButton(hdlg, DRV_KSQO, comval->ksqo);
+       CheckDlgButton(hdlg, DRV_UNIQUEINDEX, comval->unique_index);
+       EnableWindow(GetDlgItem(hdlg, DRV_UNIQUEINDEX), enable);
+       CheckDlgButton(hdlg, DRV_READONLY, comval->onlyread);
+       EnableWindow(GetDlgItem(hdlg, DRV_READONLY), enable);
+       CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, comval->use_declarefetch);
+
+       /* Unknown Sizes clear */
+       CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 0);
+       CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 0);
+       CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 0);
+       /* Unknown (Default) Data Type sizes */
+       switch (comval->unknown_sizes)
+       {
+               case UNKNOWNS_AS_DONTKNOW:
+                       CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
+                       break;
+               case UNKNOWNS_AS_LONGEST:
+                       CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 1);
+                       break;
+               case UNKNOWNS_AS_MAX:
+               default:
+                       CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 1);
+                       break;
+       }
 
-                       CheckDlgButton(hdlg, DRV_PARSE, globals.parse);
+       CheckDlgButton(hdlg, DRV_TEXT_LONGVARCHAR, comval->text_as_longvarchar);
+       CheckDlgButton(hdlg, DRV_UNKNOWNS_LONGVARCHAR, comval->unknowns_as_longvarchar);
+       CheckDlgButton(hdlg, DRV_BOOLS_CHAR, comval->bools_as_char);
+       CheckDlgButton(hdlg, DRV_PARSE, comval->parse);
+       CheckDlgButton(hdlg, DRV_CANCELASFREESTMT, comval->cancel_as_freestmt);
+       CheckDlgButton(hdlg, DRV_DEBUG, comval->debug);
+       SetDlgItemInt(hdlg, DRV_CACHE_SIZE, comval->fetch_max, FALSE);
+       SetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, comval->max_varchar_size, FALSE);
+       SetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, comval->max_longvarchar_size, TRUE);
+       SetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes);
+
+       /* Driver Connection Settings */
+       SetDlgItemText(hdlg, DRV_CONNSETTINGS, comval->conn_settings);
+       EnableWindow(GetDlgItem(hdlg, DRV_CONNSETTINGS), enable);
+       return 0;
+}
+static int
+driver_options_update(HWND hdlg, ConnInfo *ci, BOOL updateProfile)
+{
+       GLOBAL_VALUES   *comval;
+
+       if (ci)
+               comval = &(ci->drivers);
+       else
+               comval = &globals;
+       comval->commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
+       comval->disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER);
+       comval->ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO);
+       if (!ci)
+       {
+               comval->unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX);
+               comval->onlyread = IsDlgButtonChecked(hdlg, DRV_READONLY);
+       }
+       comval->use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH);
+
+       /* Unknown (Default) Data Type sizes */
+       if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_MAX))
+               comval->unknown_sizes = UNKNOWNS_AS_MAX;
+       else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_DONTKNOW))
+               comval->unknown_sizes = UNKNOWNS_AS_DONTKNOW;
+       else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_LONGEST))
+               comval->unknown_sizes = UNKNOWNS_AS_LONGEST;
+       else
+               comval->unknown_sizes = UNKNOWNS_AS_MAX;
+
+       comval->text_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_TEXT_LONGVARCHAR);
+       comval->unknowns_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_UNKNOWNS_LONGVARCHAR);
+       comval->bools_as_char = IsDlgButtonChecked(hdlg, DRV_BOOLS_CHAR);
+
+       comval->parse = IsDlgButtonChecked(hdlg, DRV_PARSE);
+
+       comval->cancel_as_freestmt = IsDlgButtonChecked(hdlg, DRV_CANCELASFREESTMT);
+       comval->debug = IsDlgButtonChecked(hdlg, DRV_DEBUG);
+
+       comval->fetch_max = GetDlgItemInt(hdlg, DRV_CACHE_SIZE, NULL, FALSE);
+       comval->max_varchar_size = GetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, NULL, FALSE);
+       comval->max_longvarchar_size = GetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, NULL, TRUE);           /* allows for
+                                                                                                                                                                                                                                * SQL_NO_TOTAL */
 
-                       CheckDlgButton(hdlg, DRV_CANCELASFREESTMT, globals.cancel_as_freestmt);
+       GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, sizeof(comval->extra_systable_prefixes));
 
-                       SetDlgItemInt(hdlg, DRV_CACHE_SIZE, globals.fetch_max, FALSE);
-                       SetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, globals.max_varchar_size, FALSE);
-                       SetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, globals.max_longvarchar_size, TRUE);
+       /* Driver Connection Settings */
+       if (!ci)
+               GetDlgItemText(hdlg, DRV_CONNSETTINGS, comval->conn_settings, sizeof(comval->conn_settings));
 
-                       SetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes);
+       if (updateProfile)
+               updateCommons(ci);
 
-                       /* Driver Connection Settings */
-                       SetDlgItemText(hdlg, DRV_CONNSETTINGS, globals.conn_settings);
+       /* fall through */
+       return 0;
+}
 
+int                    CALLBACK
+driver_optionsProc(HWND hdlg,
+                                  WORD wMsg,
+                                  WPARAM wParam,
+                                  LPARAM lParam)
+{
+       ConnInfo *ci;
+       switch (wMsg)
+       {
+               case WM_INITDIALOG:
+                       SetWindowLong(hdlg, DWL_USER, lParam);  /* save for OK etc */
+                       ci = (ConnInfo *) lParam;
+                       if (ci && ci->dsn && ci->dsn[0])
+                       {
+                               driver_optionsDraw(hdlg, NULL, 0, TRUE);
+                       }
+                       else
+                       {
+                               CheckDlgButton(hdlg, DRV_OR_DSN, 1);
+                               ShowWindow(GetDlgItem(hdlg, DRV_OR_DSN), SW_HIDE);
+                               driver_optionsDraw(hdlg, ci, 1, FALSE);
+                       }
                        break;
 
                case WM_COMMAND:
                        switch (GET_WM_COMMAND_ID(wParam, lParam))
                        {
                                case IDOK:
-                                       globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
-                                       globals.disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER);
-                                       globals.ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO);
-                                       globals.unique_index = IsDlgButtonChecked(hdlg, DRV_UNIQUEINDEX);
-                                       globals.onlyread = IsDlgButtonChecked(hdlg, DRV_READONLY);
-                                       globals.use_declarefetch = IsDlgButtonChecked(hdlg, DRV_USEDECLAREFETCH);
-
-                                       /* Unknown (Default) Data Type sizes */
-                                       if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_MAX))
-                                               globals.unknown_sizes = UNKNOWNS_AS_MAX;
-                                       else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_DONTKNOW))
-                                               globals.unknown_sizes = UNKNOWNS_AS_DONTKNOW;
-                                       else if (IsDlgButtonChecked(hdlg, DRV_UNKNOWN_LONGEST))
-                                               globals.unknown_sizes = UNKNOWNS_AS_LONGEST;
-                                       else
-                                               globals.unknown_sizes = UNKNOWNS_AS_MAX;
-
-                                       globals.text_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_TEXT_LONGVARCHAR);
-                                       globals.unknowns_as_longvarchar = IsDlgButtonChecked(hdlg, DRV_UNKNOWNS_LONGVARCHAR);
-                                       globals.bools_as_char = IsDlgButtonChecked(hdlg, DRV_BOOLS_CHAR);
-
-                                       globals.parse = IsDlgButtonChecked(hdlg, DRV_PARSE);
-
-                                       globals.cancel_as_freestmt = IsDlgButtonChecked(hdlg, DRV_CANCELASFREESTMT);
-
-                                       globals.fetch_max = GetDlgItemInt(hdlg, DRV_CACHE_SIZE, NULL, FALSE);
-                                       globals.max_varchar_size = GetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, NULL, FALSE);
-                                       globals.max_longvarchar_size = GetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, NULL, TRUE);           /* allows for
-                                                                                                                                                                                                                                * SQL_NO_TOTAL */
-
-                                       GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes, sizeof(globals.extra_systable_prefixes));
-
-                                       /* Driver Connection Settings */
-                                       GetDlgItemText(hdlg, DRV_CONNSETTINGS, globals.conn_settings, sizeof(globals.conn_settings));
-
-                                       updateGlobals();
-
-                                       /* fall through */
+                                       ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
+                                       driver_options_update(hdlg, IsDlgButtonChecked(hdlg, DRV_OR_DSN) ? ci : NULL,
+                                               ci && ci->dsn && ci->dsn[0]);
 
                                case IDCANCEL:
                                        EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
                                        return TRUE;
 
                                case IDDEFAULTS:
-                                       CheckDlgButton(hdlg, DRV_COMMLOG, DEFAULT_COMMLOG);
-                                       CheckDlgButton(hdlg, DRV_OPTIMIZER, DEFAULT_OPTIMIZER);
-                                       CheckDlgButton(hdlg, DRV_KSQO, DEFAULT_KSQO);
-                                       CheckDlgButton(hdlg, DRV_UNIQUEINDEX, DEFAULT_UNIQUEINDEX);
-                                       CheckDlgButton(hdlg, DRV_READONLY, DEFAULT_READONLY);
-                                       CheckDlgButton(hdlg, DRV_USEDECLAREFETCH, DEFAULT_USEDECLAREFETCH);
-
-                                       CheckDlgButton(hdlg, DRV_PARSE, DEFAULT_PARSE);
-                                       CheckDlgButton(hdlg, DRV_CANCELASFREESTMT, DEFAULT_CANCELASFREESTMT);
-
-                                       /* Unknown Sizes */
-                                       CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 0);
-                                       CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 0);
-                                       CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 0);
-                                       switch (DEFAULT_UNKNOWNSIZES)
+                                       if (IsDlgButtonChecked(hdlg, DRV_OR_DSN))
                                        {
-                                               case UNKNOWNS_AS_DONTKNOW:
-                                                       CheckDlgButton(hdlg, DRV_UNKNOWN_DONTKNOW, 1);
-                                                       break;
-                                               case UNKNOWNS_AS_LONGEST:
-                                                       CheckDlgButton(hdlg, DRV_UNKNOWN_LONGEST, 1);
-                                                       break;
-                                               case UNKNOWNS_AS_MAX:
-                                                       CheckDlgButton(hdlg, DRV_UNKNOWN_MAX, 1);
-                                                       break;
+                                               ConnInfo   *ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
+                                               driver_optionsDraw(hdlg, ci, 0, FALSE);
                                        }
+                                       else
+                                               driver_optionsDraw(hdlg, NULL, 2, TRUE);
+                                       break;
 
-                                       CheckDlgButton(hdlg, DRV_TEXT_LONGVARCHAR, DEFAULT_TEXTASLONGVARCHAR);
-                                       CheckDlgButton(hdlg, DRV_UNKNOWNS_LONGVARCHAR, DEFAULT_UNKNOWNSASLONGVARCHAR);
-                                       CheckDlgButton(hdlg, DRV_BOOLS_CHAR, DEFAULT_BOOLSASCHAR);
-
-                                       SetDlgItemInt(hdlg, DRV_CACHE_SIZE, FETCH_MAX, FALSE);
-                                       SetDlgItemInt(hdlg, DRV_VARCHAR_SIZE, MAX_VARCHAR_SIZE, FALSE);
-                                       SetDlgItemInt(hdlg, DRV_LONGVARCHAR_SIZE, TEXT_FIELD_SIZE, TRUE);
-
-                                       SetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, DEFAULT_EXTRASYSTABLEPREFIXES);
-
-                                       /* Driver Connection Settings */
-                                       SetDlgItemText(hdlg, DRV_CONNSETTINGS, "");
-
+                               case DRV_OR_DSN:
+                                       if (GET_WM_COMMAND_CMD(wParam, lParam) == BN_CLICKED)
+                                       {
+                                               mylog("DRV_OR_DSN clicked\n");
+                                               if (IsDlgButtonChecked(hdlg, DRV_OR_DSN))
+                                               {
+                                                       ConnInfo   *ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
+                                                       driver_optionsDraw(hdlg, ci, ci ? 1 : 0, ci == NULL);
+                                               }
+                                               else
+                                                       driver_optionsDraw(hdlg, NULL, 0, TRUE);
+                                       }
                                        break;
                        }
        }
@@ -331,10 +394,11 @@ ds_optionsProc(HWND hdlg,
 
 
 void
-makeConnectString(char *connect_string, ConnInfo *ci)
+makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len)
 {
        char            got_dsn = (ci->dsn[0] != '\0');
        char            encoded_conn_settings[LARGE_REGISTRY_LEN];
+       UWORD           hlen;
 
        /* fundamental info */
        sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;PWD=%s",
@@ -349,20 +413,64 @@ makeConnectString(char *connect_string, ConnInfo *ci)
        encode(ci->conn_settings, encoded_conn_settings);
 
        /* extra info */
-       sprintf(&connect_string[strlen(connect_string)],
-                       ";READONLY=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;ROWVERSIONING=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s",
+       hlen = strlen(connect_string),
+       sprintf(&connect_string[hlen],
+                       ";READONLY=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;ROWVERSIONING=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s;FETCH=%d;SOCKET=%d;UNKNOWNSIZES=%d;MAXVARCHARSIZE=%d;MAXLONGVARCHARSIZE=%d;DEBUG=%d;COMMLOG=%d;OPTIMIZER=%d;KSQO=%d;USEDECLAREFETCH=%d;TEXTASLONGVARCHAR=%d;UNKNOWNSASLONGVARCHAR=%d;BOOLSASCHAR=%d;PARSE=%d;CANCELASFREESTMT=%d;EXTRASYSTABLEPREFIXES=%s",
+                       ci->onlyread,
+                       ci->protocol,
+                       ci->fake_oid_index,
+                       ci->show_oid_column,
+                       ci->row_versioning,
+                       ci->show_system_tables,
+                       encoded_conn_settings,
+                       ci->drivers.fetch_max,
+                       ci->drivers.socket_buffersize,
+                       ci->drivers.unknown_sizes,
+                       ci->drivers.max_varchar_size,
+                       ci->drivers.max_longvarchar_size,
+                       ci->drivers.debug,
+                       ci->drivers.commlog,
+                       ci->drivers.disable_optimizer,
+                       ci->drivers.ksqo,
+                       ci->drivers.use_declarefetch,
+                       ci->drivers.text_as_longvarchar,
+                       ci->drivers.unknowns_as_longvarchar,
+                       ci->drivers.bools_as_char,
+                       ci->drivers.parse,
+                       ci->drivers.cancel_as_freestmt,
+                       ci->drivers.extra_systable_prefixes);
+       /* Abbrebiation is needed ? */
+       if (strlen(connect_string) >= len)
+               sprintf(&connect_string[hlen],
+                       ";A0=%s;A1=%s;A2=%s;A3=%s;A4=%s;A5=%s;A6=%s;A7=%d;A8=%d;A9=%d;B0=%d;B1=%d;B2=%d;B3=%d;B4=%d;B5=%d;B6=%d;B7=%d;B8=%d;B9=%d;C0=%d;C1=%d;C2=%s",
                        ci->onlyread,
                        ci->protocol,
                        ci->fake_oid_index,
                        ci->show_oid_column,
                        ci->row_versioning,
                        ci->show_system_tables,
-                       encoded_conn_settings);
+                       encoded_conn_settings,
+                       ci->drivers.fetch_max,
+                       ci->drivers.socket_buffersize,
+                       ci->drivers.unknown_sizes,
+                       ci->drivers.max_varchar_size,
+                       ci->drivers.max_longvarchar_size,
+                       ci->drivers.debug,
+                       ci->drivers.commlog,
+                       ci->drivers.disable_optimizer,
+                       ci->drivers.ksqo,
+                       ci->drivers.use_declarefetch,
+                       ci->drivers.text_as_longvarchar,
+                       ci->drivers.unknowns_as_longvarchar,
+                       ci->drivers.bools_as_char,
+                       ci->drivers.parse,
+                       ci->drivers.cancel_as_freestmt,
+                       ci->drivers.extra_systable_prefixes);
 }
 
 
 void
-copyAttributes(ConnInfo *ci, char *attribute, char *value)
+copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
 {
        if (stricmp(attribute, "DSN") == 0)
                strcpy(ci->dsn, value);
@@ -385,25 +493,25 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
        else if (stricmp(attribute, INI_PORT) == 0)
                strcpy(ci->port, value);
 
-       else if (stricmp(attribute, INI_READONLY) == 0)
+       else if (stricmp(attribute, INI_READONLY) == 0 || stricmp(attribute, "A0") == 0)
                strcpy(ci->onlyread, value);
 
-       else if (stricmp(attribute, INI_PROTOCOL) == 0)
+       else if (stricmp(attribute, INI_PROTOCOL) == 0 || stricmp(attribute, "A1") == 0)
                strcpy(ci->protocol, value);
 
-       else if (stricmp(attribute, INI_SHOWOIDCOLUMN) == 0)
+       else if (stricmp(attribute, INI_SHOWOIDCOLUMN) == 0 || stricmp(attribute, "A3") == 0)
                strcpy(ci->show_oid_column, value);
 
-       else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0)
+       else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0 || stricmp(attribute, "A2") == 0)
                strcpy(ci->fake_oid_index, value);
 
-       else if (stricmp(attribute, INI_ROWVERSIONING) == 0)
+       else if (stricmp(attribute, INI_ROWVERSIONING) == 0 || stricmp(attribute, "A4") == 0)
                strcpy(ci->row_versioning, value);
 
-       else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0)
+       else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0 || stricmp(attribute, "A5") == 0)
                strcpy(ci->show_system_tables, value);
 
-       else if (stricmp(attribute, INI_CONNSETTINGS) == 0)
+       else if (stricmp(attribute, INI_CONNSETTINGS) == 0 || stricmp(attribute, "A6") == 0)
        {
                decode(value, ci->conn_settings);
                /* strcpy(ci->conn_settings, value); */
@@ -412,6 +520,66 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
        mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings);
 }
 
+void
+copyCommonAttributes(ConnInfo *ci, const char *attribute, const char *value)
+{
+       if (stricmp(attribute, INI_FETCH) == 0 || stricmp(attribute, "A7") == 0)
+               ci->drivers.fetch_max = atoi(value);
+       else if (stricmp(attribute, INI_SOCKET) == 0 || stricmp(attribute, "A8") == 0)
+               ci->drivers.socket_buffersize = atoi(value);
+       else if (stricmp(attribute, INI_DEBUG) == 0 || stricmp(attribute, "B2") == 0)
+               ci->drivers.debug = atoi(value);
+       else if (stricmp(attribute, INI_COMMLOG) == 0 || stricmp(attribute, "B3") == 0)
+               ci->drivers.commlog = atoi(value);
+       else if (stricmp(attribute, INI_OPTIMIZER) == 0 || stricmp(attribute, "B4") == 0)
+               ci->drivers.disable_optimizer = atoi(value);
+       else if (stricmp(attribute, INI_KSQO) == 0 || stricmp(attribute, "B5") == 0)
+               ci->drivers.ksqo = atoi(value);
+       /*
+       else if (stricmp(attribute, INI_UNIQUEINDEX) == 0 || stricmp(attribute, "UIX") == 0)
+               ci->drivers.unique_index = atoi(value);
+       */
+       else if (stricmp(attribute, INI_UNKNOWNSIZES) == 0 || stricmp(attribute, "A9") == 0)
+               ci->drivers.unknown_sizes = atoi(value);
+       else if (stricmp(attribute, INI_LIE) == 0)
+               ci->drivers.lie = atoi(value);
+       else if (stricmp(attribute, INI_PARSE) == 0 || stricmp(attribute, "C0") == 0)
+               ci->drivers.parse = atoi(value);
+       else if (stricmp(attribute, INI_CANCELASFREESTMT) == 0 || stricmp(attribute, "C1") == 0)
+               ci->drivers.cancel_as_freestmt = atoi(value);
+       else if (stricmp(attribute, INI_USEDECLAREFETCH) == 0 || stricmp(attribute, "B6") == 0)
+               ci->drivers.use_declarefetch = atoi(value);
+       else if (stricmp(attribute, INI_MAXVARCHARSIZE) == 0 || stricmp(attribute, "B0") == 0)
+               ci->drivers.max_varchar_size = atoi(value);
+       else if (stricmp(attribute, INI_MAXLONGVARCHARSIZE) == 0 || stricmp(attribute, "B1") == 0)
+               ci->drivers.max_longvarchar_size = atoi(value);
+       else if (stricmp(attribute, INI_TEXTASLONGVARCHAR) == 0 || stricmp(attribute, "B7") == 0)
+               ci->drivers.text_as_longvarchar = atoi(value);
+       else if (stricmp(attribute, INI_UNKNOWNSASLONGVARCHAR) == 0 || stricmp(attribute, "B8") == 0)
+               ci->drivers.unknowns_as_longvarchar = atoi(value);
+       else if (stricmp(attribute, INI_BOOLSASCHAR) == 0 || stricmp(attribute, "B9") == 0)
+               ci->drivers.bools_as_char = atoi(value);
+       else if (stricmp(attribute, INI_EXTRASYSTABLEPREFIXES) == 0 || stricmp(attribute, "C2") == 0)
+               strcpy(ci->drivers.extra_systable_prefixes, value);
+       mylog("CopyCommonAttributes: A7=%d;A8=%d;A9=%d;B0=%d;B1=%d;B2=%d;B3=%d;B4=%d;B5=%d;B6=%d;B7=%d;B8=%d;B9=%d;C0=%d;C1=%d;C2=%s",
+                       ci->drivers.fetch_max,
+                       ci->drivers.socket_buffersize,
+                       ci->drivers.unknown_sizes,
+                       ci->drivers.max_varchar_size,
+                       ci->drivers.max_longvarchar_size,
+                       ci->drivers.debug,
+                       ci->drivers.commlog,
+                       ci->drivers.disable_optimizer,
+                       ci->drivers.ksqo,
+                       ci->drivers.use_declarefetch,
+                       ci->drivers.text_as_longvarchar,
+                       ci->drivers.unknowns_as_longvarchar,
+                       ci->drivers.bools_as_char,
+                       ci->drivers.parse,
+                       ci->drivers.cancel_as_freestmt,
+                       ci->drivers.extra_systable_prefixes);
+}
+
 
 void
 getDSNdefaults(ConnInfo *ci)
@@ -449,6 +617,7 @@ getDSNinfo(ConnInfo *ci, char overwrite)
  *     If a driver keyword was present, then dont use a DSN and return.
  *     If DSN is null and no driver, then use the default datasource.
  */
+       memcpy(&ci->drivers, &globals, sizeof(globals));
        if (DSN[0] == '\0')
        {
                if (ci->driver[0] != '\0')
@@ -512,7 +681,8 @@ getDSNinfo(ConnInfo *ci, char overwrite)
                SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI);
 
        /* Allow override of odbcinst.ini parameters here */
-       getGlobalDefaults(DSN, ODBC_INI, TRUE);
+       /* getGlobalDefaults(DSN, ODBC_INI, TRUE); */
+       getCommonDefaults(DSN, ODBC_INI, ci);
 
        qlog("DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n",
                 DSN,
@@ -546,9 +716,9 @@ getDSNinfo(ConnInfo *ci, char overwrite)
 
 /*     This is for datasource based options only */
 void
-writeDSNinfo(ConnInfo *ci)
+writeDSNinfo(const ConnInfo *ci)
 {
-       char       *DSN = ci->dsn;
+       const char   *DSN = ci->dsn;
        char            encoded_conn_settings[LARGE_REGISTRY_LEN];
 
        encode(ci->conn_settings, encoded_conn_settings);
@@ -625,152 +795,159 @@ writeDSNinfo(ConnInfo *ci)
  *     the registry and gets any driver defaults.
  */
 void
-getGlobalDefaults(char *section, char *filename, char override)
+getCommonDefaults(const char *section, const char *filename, ConnInfo *ci)
 {
        char            temp[256];
+       GLOBAL_VALUES   *comval;
 
+       if (ci)
+               comval = &(ci->drivers);
+       else
+               comval = &globals;
        /* Fetch Count is stored in driver section */
        SQLGetPrivateProfileString(section, INI_FETCH, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
        {
-               globals.fetch_max = atoi(temp);
+               comval->fetch_max = atoi(temp);
                /* sanity check if using cursors */
-               if (globals.fetch_max <= 0)
-                       globals.fetch_max = FETCH_MAX;
+               if (comval->fetch_max <= 0)
+                       comval->fetch_max = FETCH_MAX;
        }
-       else if (!override)
-               globals.fetch_max = FETCH_MAX;
+       else if (!ci)
+               comval->fetch_max = FETCH_MAX;
 
        /* Socket Buffersize is stored in driver section */
        SQLGetPrivateProfileString(section, INI_SOCKET, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.socket_buffersize = atoi(temp);
-       else if (!override)
-               globals.socket_buffersize = SOCK_BUFFER_SIZE;
+               comval->socket_buffersize = atoi(temp);
+       else if (!ci)
+               comval->socket_buffersize = SOCK_BUFFER_SIZE;
 
        /* Debug is stored in the driver section */
        SQLGetPrivateProfileString(section, INI_DEBUG, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.debug = atoi(temp);
-       else if (!override)
-               globals.debug = DEFAULT_DEBUG;
+               comval->debug = atoi(temp);
+       else if (!ci)
+               comval->debug = DEFAULT_DEBUG;
 
        /* CommLog is stored in the driver section */
        SQLGetPrivateProfileString(section, INI_COMMLOG, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.commlog = atoi(temp);
-       else if (!override)
-               globals.commlog = DEFAULT_COMMLOG;
+               comval->commlog = atoi(temp);
+       else if (!ci)
+               comval->commlog = DEFAULT_COMMLOG;
 
+       if (!ci)
+               logs_on_off(0, 0, 0);
        /* Optimizer is stored in the driver section only */
        SQLGetPrivateProfileString(section, INI_OPTIMIZER, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.disable_optimizer = atoi(temp);
-       else if (!override)
-               globals.disable_optimizer = DEFAULT_OPTIMIZER;
+               comval->disable_optimizer = atoi(temp);
+       else if (!ci)
+               comval->disable_optimizer = DEFAULT_OPTIMIZER;
 
        /* KSQO is stored in the driver section only */
        SQLGetPrivateProfileString(section, INI_KSQO, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.ksqo = atoi(temp);
-       else if (!override)
-               globals.ksqo = DEFAULT_KSQO;
+               comval->ksqo = atoi(temp);
+       else if (!ci)
+               comval->ksqo = DEFAULT_KSQO;
 
        /* Recognize Unique Index is stored in the driver section only */
        SQLGetPrivateProfileString(section, INI_UNIQUEINDEX, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.unique_index = atoi(temp);
-       else if (!override)
-               globals.unique_index = DEFAULT_UNIQUEINDEX;
+               comval->unique_index = atoi(temp);
+       else if (!ci)
+               comval->unique_index = DEFAULT_UNIQUEINDEX;
 
 
        /* Unknown Sizes is stored in the driver section only */
        SQLGetPrivateProfileString(section, INI_UNKNOWNSIZES, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.unknown_sizes = atoi(temp);
-       else if (!override)
-               globals.unknown_sizes = DEFAULT_UNKNOWNSIZES;
+               comval->unknown_sizes = atoi(temp);
+       else if (!ci)
+               comval->unknown_sizes = DEFAULT_UNKNOWNSIZES;
 
 
        /* Lie about supported functions? */
        SQLGetPrivateProfileString(section, INI_LIE, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.lie = atoi(temp);
-       else if (!override)
-               globals.lie = DEFAULT_LIE;
+               comval->lie = atoi(temp);
+       else if (!ci)
+               comval->lie = DEFAULT_LIE;
 
        /* Parse statements */
        SQLGetPrivateProfileString(section, INI_PARSE, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.parse = atoi(temp);
-       else if (!override)
-               globals.parse = DEFAULT_PARSE;
+               comval->parse = atoi(temp);
+       else if (!ci)
+               comval->parse = DEFAULT_PARSE;
 
        /* SQLCancel calls SQLFreeStmt in Driver Manager */
        SQLGetPrivateProfileString(section, INI_CANCELASFREESTMT, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.cancel_as_freestmt = atoi(temp);
-       else if (!override)
-               globals.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
+               comval->cancel_as_freestmt = atoi(temp);
+       else if (!ci)
+               comval->cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
 
        /* UseDeclareFetch is stored in the driver section only */
        SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.use_declarefetch = atoi(temp);
-       else if (!override)
-               globals.use_declarefetch = DEFAULT_USEDECLAREFETCH;
+               comval->use_declarefetch = atoi(temp);
+       else if (!ci)
+               comval->use_declarefetch = DEFAULT_USEDECLAREFETCH;
 
        /* Max Varchar Size */
        SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.max_varchar_size = atoi(temp);
-       else if (!override)
-               globals.max_varchar_size = MAX_VARCHAR_SIZE;
+               comval->max_varchar_size = atoi(temp);
+       else if (!ci)
+               comval->max_varchar_size = MAX_VARCHAR_SIZE;
 
        /* Max TextField Size */
        SQLGetPrivateProfileString(section, INI_MAXLONGVARCHARSIZE, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.max_longvarchar_size = atoi(temp);
-       else if (!override)
-               globals.max_longvarchar_size = TEXT_FIELD_SIZE;
+               comval->max_longvarchar_size = atoi(temp);
+       else if (!ci)
+               comval->max_longvarchar_size = TEXT_FIELD_SIZE;
 
        /* Text As LongVarchar  */
        SQLGetPrivateProfileString(section, INI_TEXTASLONGVARCHAR, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.text_as_longvarchar = atoi(temp);
-       else if (!override)
-               globals.text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
+               comval->text_as_longvarchar = atoi(temp);
+       else if (!ci)
+               comval->text_as_longvarchar = DEFAULT_TEXTASLONGVARCHAR;
 
        /* Unknowns As LongVarchar      */
        SQLGetPrivateProfileString(section, INI_UNKNOWNSASLONGVARCHAR, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.unknowns_as_longvarchar = atoi(temp);
-       else if (!override)
-               globals.unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
+               comval->unknowns_as_longvarchar = atoi(temp);
+       else if (!ci)
+               comval->unknowns_as_longvarchar = DEFAULT_UNKNOWNSASLONGVARCHAR;
 
        /* Bools As Char */
        SQLGetPrivateProfileString(section, INI_BOOLSASCHAR, "",
                                                           temp, sizeof(temp), filename);
        if (temp[0])
-               globals.bools_as_char = atoi(temp);
-       else if (!override)
-               globals.bools_as_char = DEFAULT_BOOLSASCHAR;
+               comval->bools_as_char = atoi(temp);
+       else if (!ci)
+               comval->bools_as_char = DEFAULT_BOOLSASCHAR;
 
        /* Extra Systable prefixes */
 
@@ -781,15 +958,15 @@ getGlobalDefaults(char *section, char *filename, char override)
        SQLGetPrivateProfileString(section, INI_EXTRASYSTABLEPREFIXES, "@@@",
                                                           temp, sizeof(temp), filename);
        if (strcmp(temp, "@@@"))
-               strcpy(globals.extra_systable_prefixes, temp);
-       else if (!override)
-               strcpy(globals.extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES);
+               strcpy(comval->extra_systable_prefixes, temp);
+       else if (!ci)
+               strcpy(comval->extra_systable_prefixes, DEFAULT_EXTRASYSTABLEPREFIXES);
 
-       mylog("globals.extra_systable_prefixes = '%s'\n", globals.extra_systable_prefixes);
+       mylog("globals.extra_systable_prefixes = '%s'\n", comval->extra_systable_prefixes);
 
 
        /* Dont allow override of an override! */
-       if (!override)
+       if (!ci)
        {
 
                /*
@@ -797,15 +974,15 @@ getGlobalDefaults(char *section, char *filename, char override)
                 * for override
                 */
                SQLGetPrivateProfileString(section, INI_CONNSETTINGS, "",
-                globals.conn_settings, sizeof(globals.conn_settings), filename);
+                       comval->conn_settings, sizeof(comval->conn_settings), filename);
 
                /* Default state for future DSN's Readonly attribute */
                SQLGetPrivateProfileString(section, INI_READONLY, "",
                                                                   temp, sizeof(temp), filename);
                if (temp[0])
-                       globals.onlyread = atoi(temp);
+                       comval->onlyread = atoi(temp);
                else
-                       globals.onlyread = DEFAULT_READONLY;
+                       comval->onlyread = DEFAULT_READONLY;
 
                /*
                 * Default state for future DSN's protocol attribute This isn't a
@@ -815,85 +992,113 @@ getGlobalDefaults(char *section, char *filename, char override)
                SQLGetPrivateProfileString(section, INI_PROTOCOL, "@@@",
                                                                   temp, sizeof(temp), filename);
                if (strcmp(temp, "@@@"))
-                       strcpy(globals.protocol, temp);
+                       strcpy(comval->protocol, temp);
                else
-                       strcpy(globals.protocol, DEFAULT_PROTOCOL);
+                       strcpy(comval->protocol, DEFAULT_PROTOCOL);
        }
 }
 
-
 /*
  *     This function writes any global parameters (that can be manipulated)
  *     to the ODBCINST.INI portion of the registry
  */
-void
-updateGlobals(void)
+static void
+updateCommons(const ConnInfo *ci)
 {
+       const   char            *sectionName;
+       const   char            *fileName;
+       const   GLOBAL_VALUES   *comval;
        char            tmp[128];
 
-       sprintf(tmp, "%d", globals.fetch_max);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_FETCH, tmp, ODBCINST_INI);
+       if (ci)
+               if (ci->dsn && ci->dsn[0])
+               {
+                       mylog("DSN=%s updating\n", ci->dsn);
+                       comval = &(ci->drivers);
+                       sectionName = ci->dsn;
+                       fileName = ODBC_INI;
+               }
+               else
+               {
+                       mylog("ci but dsn==NULL\n");
+                       return;
+               } 
+       else
+       {
+               mylog("drivers updating\n");
+               comval = &globals;
+               sectionName = DBMS_NAME;
+               fileName = ODBCINST_INI;
+       }
+       sprintf(tmp, "%d", comval->fetch_max);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_FETCH, tmp, fileName);
+
+       sprintf(tmp, "%d", comval->commlog);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_COMMLOG, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.commlog);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_COMMLOG, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->debug);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_DEBUG, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.disable_optimizer);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_OPTIMIZER, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->disable_optimizer);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_OPTIMIZER, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.ksqo);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_KSQO, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->ksqo);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_KSQO, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.unique_index);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_UNIQUEINDEX, tmp, ODBCINST_INI);
+       /* Never update the onlyread, unique_index from this module 
+       sprintf(tmp, "%d", comval->unique_index);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_UNIQUEINDEX, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.onlyread);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_READONLY, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->onlyread);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_READONLY, tmp, fileName);*/
 
-       sprintf(tmp, "%d", globals.use_declarefetch);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_USEDECLAREFETCH, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->use_declarefetch);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_USEDECLAREFETCH, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.unknown_sizes);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_UNKNOWNSIZES, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->unknown_sizes);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_UNKNOWNSIZES, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.text_as_longvarchar);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                          INI_TEXTASLONGVARCHAR, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->text_as_longvarchar);
+       SQLWritePrivateProfileString(sectionName,
+                                                          INI_TEXTASLONGVARCHAR, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.unknowns_as_longvarchar);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                  INI_UNKNOWNSASLONGVARCHAR, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->unknowns_as_longvarchar);
+       SQLWritePrivateProfileString(sectionName,
+                                                  INI_UNKNOWNSASLONGVARCHAR, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.bools_as_char);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_BOOLSASCHAR, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->bools_as_char);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_BOOLSASCHAR, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.parse);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_PARSE, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->parse);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_PARSE, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.cancel_as_freestmt);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_CANCELASFREESTMT, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->cancel_as_freestmt);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_CANCELASFREESTMT, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.max_varchar_size);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_MAXVARCHARSIZE, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->max_varchar_size);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_MAXVARCHARSIZE, tmp, fileName);
 
-       sprintf(tmp, "%d", globals.max_longvarchar_size);
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                         INI_MAXLONGVARCHARSIZE, tmp, ODBCINST_INI);
+       sprintf(tmp, "%d", comval->max_longvarchar_size);
+       SQLWritePrivateProfileString(sectionName,
+                                                         INI_MAXLONGVARCHARSIZE, tmp, fileName);
 
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                                                INI_EXTRASYSTABLEPREFIXES, globals.extra_systable_prefixes, ODBCINST_INI);
+       SQLWritePrivateProfileString(sectionName,
+                                                                INI_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, fileName);
 
-       SQLWritePrivateProfileString(DBMS_NAME,
-                                 INI_CONNSETTINGS, globals.conn_settings, ODBCINST_INI);
+       /* Never update the conn_setting from this module 
+       SQLWritePrivateProfileString(sectionName,
+                                 INI_CONNSETTINGS, comval->conn_settings, fileName); */
 }
index 67f99449754771cec22e58c8dcb3493cc3c06719..6d9885434f5e71a006498be2c37a0f520ae642d5 100644 (file)
 #define DEFAULT_EXTRASYSTABLEPREFIXES  "dd_;"
 
 /*     prototypes */
-void           getGlobalDefaults(char *section, char *filename, char override);
+void           getCommonDefaults(const char *section, const char *filename, ConnInfo *ci);
 
 #ifdef WIN32
-void           SetDlgStuff(HWND hdlg, ConnInfo *ci);
+void           SetDlgStuff(HWND hdlg, const ConnInfo *ci);
 void           GetDlgStuff(HWND hdlg, ConnInfo *ci);
 
 int CALLBACK driver_optionsProc(HWND hdlg,
@@ -144,11 +144,12 @@ int CALLBACK ds_optionsProc(HWND hdlg,
 #endif  /* WIN32 */
 
 void           updateGlobals(void);
-void           writeDSNinfo(ConnInfo *ci);
+void           writeDSNinfo(const ConnInfo *ci);
 void           getDSNdefaults(ConnInfo *ci);
 void           getDSNinfo(ConnInfo *ci, char overwrite);
-void           makeConnectString(char *connect_string, ConnInfo *ci);
-void           copyAttributes(ConnInfo *ci, char *attribute, char *value);
+void           makeConnectString(char *connect_string, const ConnInfo *ci, UWORD);
+void           copyAttributes(ConnInfo *ci, const char *attribute, const char *value);
+void           copyCommonAttributes(ConnInfo *ci, const char *attribute, const char *value);
 
 
 #endif
index e224cbda5e713f225367d37c136477b63e79b047..e1eee25de553b4a099b32e8b103ec4c2d48a7e6e 100644 (file)
@@ -51,7 +51,8 @@
 #include "dlg_specific.h"
 
 /* prototypes */
-void           dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci);
+void           dconn_get_connect_attributes(const UCHAR FAR *connect_string, ConnInfo *ci);
+static void    dconn_get_common_attributes(const UCHAR FAR *connect_string, ConnInfo *ci);
 
 #ifdef WIN32
 BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
@@ -61,8 +62,6 @@ extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
 
 #endif
 
-extern GLOBAL_VALUES globals;
-
 
 RETCODE SQL_API
 PGAPI_DriverConnect(
@@ -115,6 +114,8 @@ PGAPI_DriverConnect(
         * given -- if not, it does nothing!)
         */
        getDSNinfo(ci, CONN_DONT_OVERWRITE);
+       dconn_get_common_attributes(connStrIn, ci);
+       logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
 
        /* Fill in any default parameters if they are not there. */
        getDSNdefaults(ci);
@@ -210,7 +211,7 @@ dialog:
         */
        result = SQL_SUCCESS;
 
-       makeConnectString(connStrOut, ci);
+       makeConnectString(connStrOut, ci, cbConnStrOutMax);
        len = strlen(connStrOut);
 
        if (szConnStrOut)
@@ -238,7 +239,7 @@ dialog:
        if (pcbConnStrOut)
                *pcbConnStrOut = len;
 
-       mylog("szConnStrOut = '%s'\n", szConnStrOut);
+       mylog("szConnStrOut = '%s' len=%d,%d\n", szConnStrOut, len, cbConnStrOutMax);
        qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut);
 
 
@@ -323,8 +324,9 @@ dconn_FDriverConnectProc(
                                        return TRUE;
 
                                case IDC_DRIVER:
+                                       ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
                                        DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
-                                                               hdlg, driver_optionsProc, (LPARAM) NULL);
+                                                               hdlg, driver_optionsProc, (LPARAM) ci);
                                        break;
 
                                case IDC_DATASOURCE:
@@ -342,7 +344,7 @@ dconn_FDriverConnectProc(
 
 
 void
-dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
+dconn_get_connect_attributes(const UCHAR FAR *connect_string, ConnInfo *ci)
 {
        char       *our_connect_string;
        char       *pair,
@@ -386,3 +388,47 @@ dconn_get_connect_attributes(UCHAR FAR *connect_string, ConnInfo *ci)
 
        free(our_connect_string);
 }
+
+static void
+dconn_get_common_attributes(const UCHAR FAR *connect_string, ConnInfo *ci)
+{
+       char       *our_connect_string;
+       char       *pair,
+                          *attribute,
+                          *value,
+                          *equals;
+       char       *strtok_arg;
+
+       our_connect_string = strdup(connect_string);
+       strtok_arg = our_connect_string;
+
+       mylog("our_connect_string = '%s'\n", our_connect_string);
+
+       while (1)
+       {
+               pair = strtok(strtok_arg, ";");
+               if (strtok_arg)
+                       strtok_arg = 0;
+               if (!pair)
+                       break;
+
+               equals = strchr(pair, '=');
+               if (!equals)
+                       continue;
+
+               *equals = '\0';
+               attribute = pair;               /* ex. DSN */
+               value = equals + 1;             /* ex. 'CEO co1' */
+
+               mylog("attribute = '%s', value = '%s'\n", attribute, value);
+
+               if (!attribute || !value)
+                       continue;
+
+               /* Copy the appropriate value to the conninfo  */
+               copyCommonAttributes(ci, attribute, value);
+
+       }
+
+       free(our_connect_string);
+}
index d21c0540cac8a36dd6a3945ce7a94d261b49db5c..8e9156d2d0c61328761c8eb9a22a90f94d3c7914 100644 (file)
@@ -43,7 +43,7 @@ PGAPI_AllocEnv(HENV FAR *phenv)
         * should work.
         */
        if (globals.socket_buffersize <= 0)
-               getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+               getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
 
        *phenv = (HENV) EN_Constructor();
        if (!*phenv)
index 374d700193de400100c5652ade59fef2bc58b2b7..bd2600bd4fe1b7b1a41054da5613c31ad9c71e79 100644 (file)
@@ -34,7 +34,7 @@
 #include "lobj.h"
 #include "pgapifunc.h"
 
-extern GLOBAL_VALUES globals;
+/*extern GLOBAL_VALUES globals;*/
 
 
 /*             Perform a Prepare on the SQL statement */
@@ -340,7 +340,32 @@ PGAPI_Execute(
                return retval;
 
        mylog("   stmt_with_params = '%s'\n", stmt->stmt_with_params);
-
+#ifdef PREPARE_TRIAL
+       if (stmt->inaccurate_result)
+               if (SC_is_pre_executable(stmt))
+               {
+                       BOOL    in_trans = CC_is_in_trans(conn);
+                       QResultClass    *res;
+                       CC_set_in_trans(conn);
+                       stmt->result = res = CC_send_query(conn, stmt->stmt_with_params, NULL);
+                       if (res && QR_aborted(res))
+                       {
+                               CC_abort(conn);
+                               stmt->errornumber = STMT_EXEC_ERROR;
+                               stmt->errormsg = "Handle prepare error";
+                               return SQL_ERROR;
+                       }
+                       else
+                       {
+                               if (!in_trans)
+                                       CC_set_no_trans(conn);
+                               stmt->status =STMT_FINISHED;
+                               return SQL_SUCCESS;
+                       }
+               }
+               else
+                       return SQL_SUCCESS;
+#endif /* PREPARE_TRIAL */
        return SC_execute(stmt);
 }
 
@@ -437,6 +462,7 @@ PGAPI_Cancel(
 #ifdef WIN32
        HMODULE         hmodule;
        FARPROC         addr;
+       ConnInfo *ci;
 
 #endif
 
@@ -448,6 +474,7 @@ PGAPI_Cancel(
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        /*
         * Not in the middle of SQLParamData/SQLPutData so cancel like a
@@ -466,7 +493,7 @@ PGAPI_Cancel(
                 */
 
 #ifdef WIN32
-               if (globals.cancel_as_freestmt)
+               if (ci->drivers.cancel_as_freestmt)
                {
                        hmodule = GetModuleHandle("ODBC32");
                        addr = GetProcAddress(hmodule, "SQLFreeStmt");
@@ -569,6 +596,7 @@ PGAPI_ParamData(
        StatementClass *stmt = (StatementClass *) hstmt;
        int                     i,
                                retval;
+       ConnInfo *ci;
 
        mylog("%s: entering...\n", func);
 
@@ -577,6 +605,7 @@ PGAPI_ParamData(
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, stmt->parameters_allocated);
 
@@ -602,7 +631,7 @@ PGAPI_ParamData(
                lo_close(stmt->hdbc, stmt->lobj_fd);
 
                /* commit transaction if needed */
-               if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
+               if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
                {
                        QResultClass *res;
                        char            ok;
index 1bc96ac888c61af3866e4b549d34caaa0e065478..2f5d4c88d0318e8deb48606808b0ffd3c2d0030b 100644 (file)
@@ -54,7 +54,7 @@
 #define TRIGGER_UPDATE 0x02
 
 
-extern GLOBAL_VALUES globals;
+/* extern GLOBAL_VALUES globals; */
 
 
 
@@ -83,7 +83,7 @@ PGAPI_GetInfo(
                return SQL_INVALID_HANDLE;
        }
 
-       ci = &conn->connInfo;
+       ci = &(conn->connInfo);
 
        switch (fInfoType)
        {
@@ -113,7 +113,7 @@ PGAPI_GetInfo(
                case SQL_BOOKMARK_PERSISTENCE:  /* ODBC 2.0 */
                        /* very simple bookmark support */
                        len = 4;
-                       value = globals.use_declarefetch ? 0 : (SQL_BP_SCROLL);
+                       value = ci->drivers.use_declarefetch ? 0 : (SQL_BP_SCROLL);
                        break;
 
                case SQL_COLUMN_ALIAS:  /* ODBC 2.0 */
@@ -167,7 +167,7 @@ PGAPI_GetInfo(
                        len = 2;
                        value = SQL_CB_CLOSE;
 #ifdef DRIVER_CURSOR_IMPLEMENT
-                       if (!globals.use_declarefetch)
+                       if (!ci->drivers.use_declarefetch)
                                value = SQL_CB_PRESERVE;
 #endif /* DRIVER_CURSOR_IMPLEMENT */
                        break;
@@ -176,7 +176,7 @@ PGAPI_GetInfo(
                        len = 2;
                        value = SQL_CB_CLOSE;
 #ifdef DRIVER_CURSOR_IMPLEMENT
-                       if (!globals.use_declarefetch)
+                       if (!ci->drivers.use_declarefetch)
                                value = SQL_CB_PRESERVE;
 #endif /* DRIVER_CURSOR_IMPLEMENT */
                        break;
@@ -261,7 +261,7 @@ PGAPI_GetInfo(
 
                case SQL_FETCH_DIRECTION:               /* ODBC 1.0 */
                        len = 4;
-                       value = globals.use_declarefetch ? (SQL_FD_FETCH_NEXT) : (SQL_FD_FETCH_NEXT |
+                       value = ci->drivers.use_declarefetch ? (SQL_FD_FETCH_NEXT) : (SQL_FD_FETCH_NEXT |
                                                                                                         SQL_FD_FETCH_FIRST |
                                                                                                          SQL_FD_FETCH_LAST |
                                                                                                         SQL_FD_FETCH_PRIOR |
@@ -315,7 +315,7 @@ PGAPI_GetInfo(
 
                case SQL_LOCK_TYPES:    /* ODBC 2.0 */
                        len = 4;
-                       value = globals.lie ? (SQL_LCK_NO_CHANGE | SQL_LCK_EXCLUSIVE | SQL_LCK_UNLOCK) : SQL_LCK_NO_CHANGE;
+                       value = ci->drivers.lie ? (SQL_LCK_NO_CHANGE | SQL_LCK_EXCLUSIVE | SQL_LCK_UNLOCK) : SQL_LCK_NO_CHANGE;
                        break;
 
                case SQL_MAX_BINARY_LITERAL_LEN:                /* ODBC 2.0 */
@@ -523,12 +523,12 @@ PGAPI_GetInfo(
 
                case SQL_POS_OPERATIONS:                /* ODBC 2.0 */
                        len = 4;
-                       value = globals.lie ? (SQL_POS_POSITION | SQL_POS_REFRESH | SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD) : (SQL_POS_POSITION | SQL_POS_REFRESH);
+                       value = ci->drivers.lie ? (SQL_POS_POSITION | SQL_POS_REFRESH | SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD) : (SQL_POS_POSITION | SQL_POS_REFRESH);
                        break;
 
                case SQL_POSITIONED_STATEMENTS: /* ODBC 2.0 */
                        len = 4;
-                       value = globals.lie ? (SQL_PS_POSITIONED_DELETE |
+                       value = ci->drivers.lie ? (SQL_PS_POSITIONED_DELETE |
                                                                   SQL_PS_POSITIONED_UPDATE |
                                                                   SQL_PS_SELECT_FOR_UPDATE) : 0;
                        break;
@@ -571,12 +571,12 @@ PGAPI_GetInfo(
                         * Driver doesn't support keyset-driven or mixed cursors, so
                         * not much point in saying row updates are supported
                         */
-                       p = globals.lie ? "Y" : "N";
+                       p = ci->drivers.lie ? "Y" : "N";
                        break;
 
                case SQL_SCROLL_CONCURRENCY:    /* ODBC 1.0 */
                        len = 4;
-                       value = globals.lie ? (SQL_SCCO_READ_ONLY |
+                       value = ci->drivers.lie ? (SQL_SCCO_READ_ONLY |
                                                                   SQL_SCCO_LOCK |
                                                                   SQL_SCCO_OPT_ROWVER |
                                                         SQL_SCCO_OPT_VALUES) : (SQL_SCCO_READ_ONLY);
@@ -584,11 +584,11 @@ PGAPI_GetInfo(
 
                case SQL_SCROLL_OPTIONS:                /* ODBC 1.0 */
                        len = 4;
-                       value = globals.lie ? (SQL_SO_FORWARD_ONLY |
+                       value = ci->drivers.lie ? (SQL_SO_FORWARD_ONLY |
                                                                   SQL_SO_STATIC |
                                                                   SQL_SO_KEYSET_DRIVEN |
                                                                   SQL_SO_DYNAMIC |
-                                                                  SQL_SO_MIXED) : (globals.use_declarefetch ? SQL_SO_FORWARD_ONLY : (SQL_SO_FORWARD_ONLY | SQL_SO_STATIC));
+                                                                  SQL_SO_MIXED) : (ci->drivers.use_declarefetch ? SQL_SO_FORWARD_ONLY : (SQL_SO_FORWARD_ONLY | SQL_SO_STATIC));
                        break;
 
                case SQL_SEARCH_PATTERN_ESCAPE: /* ODBC 1.0 */
@@ -605,7 +605,7 @@ PGAPI_GetInfo(
 
                case SQL_STATIC_SENSITIVITY:    /* ODBC 2.0 */
                        len = 4;
-                       value = globals.lie ? (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES) : 0;
+                       value = ci->drivers.lie ? (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES) : 0;
                        break;
 
                case SQL_STRING_FUNCTIONS:              /* ODBC 1.0 */
@@ -782,7 +782,7 @@ PGAPI_GetTypeInfo(
 
        for (i = 0, sqlType = sqlTypes[0]; sqlType; sqlType = sqlTypes[++i])
        {
-               pgType = sqltype_to_pgtype(sqlType);
+               pgType = sqltype_to_pgtype(stmt, sqlType);
 
                if (fSqlType == SQL_ALL_TYPES || fSqlType == sqlType)
                {
@@ -833,12 +833,13 @@ PGAPI_GetFunctions(
                                UWORD FAR *pfExists)
 {
        static char *func = "PGAPI_GetFunctions";
+       ConnInfo *ci = &(((ConnectionClass *)hdbc)->connInfo);
 
        mylog("%s: entering...%u\n", func, fFunction);
 
        if (fFunction == SQL_API_ALL_FUNCTIONS)
        {
-               if (globals.lie)
+               if (ci->drivers.lie)
                {
                        int                     i;
 
@@ -923,7 +924,7 @@ PGAPI_GetFunctions(
        }
        else
        {
-               if (globals.lie)
+               if (ci->drivers.lie)
                        *pfExists = TRUE;
                else
                {
@@ -1156,8 +1157,8 @@ PGAPI_Tables(
        stmt->manual_result = TRUE;
        stmt->errormsg_created = TRUE;
 
-       conn = (ConnectionClass *) (stmt->hdbc);
-       ci = &stmt->hdbc->connInfo;
+       conn = SC_get_conn(stmt);
+       ci = &(conn->connInfo);
 
        result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt);
        if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
@@ -1188,7 +1189,7 @@ PGAPI_Tables(
        my_strcat(tables_query, " and relname like '%.*s'", szTableName, cbTableName);
 
        /* Parse the extra systable prefix      */
-       strcpy(prefixes, globals.extra_systable_prefixes);
+       strcpy(prefixes, ci->drivers.extra_systable_prefixes);
        i = 0;
        prefix[i] = strtok(prefixes, ";");
        while (prefix[i] && i < 32)
@@ -1477,8 +1478,8 @@ PGAPI_Columns(
        stmt->manual_result = TRUE;
        stmt->errormsg_created = TRUE;
 
-       conn = (ConnectionClass *) (stmt->hdbc);
-       ci = &stmt->hdbc->connInfo;
+       conn = SC_get_conn(stmt);
+       ci = &(conn->connInfo);
 
        /*
         * Create the query to find out the columns (Note: pre 6.3 did not
@@ -1778,8 +1779,8 @@ PGAPI_Columns(
                        if (mod_length >= 4)
                                mod_length -= 4;/* the length is in atttypmod - 4 */
 
-                       if (mod_length > globals.max_varchar_size || mod_length <= 0)
-                               mod_length = globals.max_varchar_size;
+                       if (mod_length > ci->drivers.max_varchar_size || mod_length <= 0)
+                               mod_length = ci->drivers.max_varchar_size;
 
                        mylog("%s: field type is VARCHAR,BPCHAR: field_type = %d, mod_length = %d\n", func, field_type, mod_length);
 
@@ -1896,7 +1897,7 @@ PGAPI_SpecialColumns(
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
-       ci = &stmt->hdbc->connInfo;
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        stmt->manual_result = TRUE;
 
@@ -2062,7 +2063,7 @@ PGAPI_Statistics(
        stmt->manual_result = TRUE;
        stmt->errormsg_created = TRUE;
 
-       ci = &stmt->hdbc->connInfo;
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        stmt->result = QR_Constructor();
        if (!stmt->result)
@@ -2301,7 +2302,7 @@ PGAPI_Statistics(
                set_tuplefield_string(&row->tuple[2], table_name);
 
                /* non-unique index? */
-               set_tuplefield_int2(&row->tuple[3], (Int2) (globals.unique_index ? FALSE : TRUE));
+               set_tuplefield_int2(&row->tuple[3], (Int2) (ci->drivers.unique_index ? FALSE : TRUE));
 
                /* no index qualifier */
                set_tuplefield_string(&row->tuple[4], "");
@@ -2345,7 +2346,7 @@ PGAPI_Statistics(
                                set_tuplefield_string(&row->tuple[2], table_name);
 
                                /* non-unique index? */
-                               if (globals.unique_index)
+                               if (ci->drivers.unique_index)
                                        set_tuplefield_int2(&row->tuple[3], (Int2) (atoi(isunique) ? FALSE : TRUE));
                                else
                                        set_tuplefield_int2(&row->tuple[3], TRUE);
@@ -2556,7 +2557,7 @@ PGAPI_PrimaryKeys(
                return SQL_ERROR;
        }
 
-       conn = (ConnectionClass *) (stmt->hdbc);
+       conn = SC_get_conn(stmt);
        if (PG_VERSION_LE(conn, 6.4))
                qstart = 2;
        else
index 1bfb877cbf7f318b0b3cd8d57b4f2dc3ee39b3cb..87a4ee01ff501d2dd989dfc748ca85365dc1733d 100644 (file)
 #endif
 
 extern GLOBAL_VALUES globals;
-void           generate_filename(char *, char *, char *);
+void   generate_filename(const char *, const char *, char *);
 
 
 void
-generate_filename(char *dirname, char *prefix, char *filename)
+generate_filename(const char *dirname, const char *prefix, char *filename)
 {
        int                     pid = 0;
 
@@ -58,6 +58,33 @@ generate_filename(char *dirname, char *prefix, char *filename)
        return;
 }
 
+static int     mylog_on = 0, qlog_on = 0;
+void logs_on_off(int cnopen, int mylog_onoff, int qlog_onoff)
+{
+       static  int     mylog_on_count = 0, mylog_off_count = 0,
+                       qlog_on_count = 0, qlog_off_count = 0;
+
+       if (mylog_onoff)
+               mylog_on_count += cnopen;
+       else 
+               mylog_off_count += cnopen;
+       if (mylog_on_count > 0)
+               mylog_on = 1;
+       else if (mylog_off_count > 0)
+               mylog_on = 0;
+       else
+               mylog_on = globals.debug;
+       if (qlog_onoff)
+               qlog_on_count += cnopen;
+       else 
+               qlog_off_count += cnopen;
+       if (qlog_on_count > 0)
+               qlog_on = 1;
+       else if (qlog_off_count > 0)
+               qlog_on = 0;
+       else
+               qlog_on = globals.commlog;
+}
 
 #ifdef MY_LOG
 void
@@ -65,9 +92,9 @@ mylog(char *fmt,...)
 {
        va_list         args;
        char            filebuf[80];
-       FILE       *LOGFP = globals.mylogFP;
+       static FILE     *LOGFP = NULL;
 
-       if (globals.debug)
+       if (mylog_on)
        {
                va_start(args, fmt);
 
@@ -75,7 +102,6 @@ mylog(char *fmt,...)
                {
                        generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
                        LOGFP = fopen(filebuf, PG_BINARY_W);
-                       globals.mylogFP = LOGFP;
                        setbuf(LOGFP, NULL);
                }
 
@@ -95,9 +121,9 @@ qlog(char *fmt,...)
 {
        va_list         args;
        char            filebuf[80];
-       FILE       *LOGFP = globals.qlogFP;
+       static FILE   *LOGFP = NULL;
 
-       if (globals.commlog)
+       if (qlog_on)
        {
                va_start(args, fmt);
 
@@ -105,7 +131,6 @@ qlog(char *fmt,...)
                {
                        generate_filename(QLOGDIR, QLOGFILE, filebuf);
                        LOGFP = fopen(filebuf, PG_BINARY_W);
-                       globals.qlogFP = LOGFP;
                        setbuf(LOGFP, NULL);
                }
 
@@ -139,7 +164,7 @@ qlog(char *fmt,...)
  *     (not including null term)
  */
 int
-my_strcpy(char *dst, int dst_len, char *src, int src_len)
+my_strcpy(char *dst, int dst_len, const char *src, int src_len)
 {
        if (dst_len <= 0)
                return STRCPY_FAIL;
@@ -214,7 +239,7 @@ strncpy_null(char *dst, const char *src, int len)
  *------
  */
 char *
-make_string(char *s, int len, char *buf)
+make_string(const char *s, int len, char *buf)
 {
        int                     length;
        char       *str;
@@ -248,7 +273,7 @@ make_string(char *s, int len, char *buf)
  *     This routine could be modified to use vsprintf() to handle multiple arguments.
  */
 char *
-my_strcat(char *buf, char *fmt, char *s, int len)
+my_strcat(char *buf, const char *fmt, const char *s, int len)
 {
        if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
        {
index dc2ef0d5bea560f5bb3271539687c7ab8b1f0f00..016b4b7a5e91ce41b6abb3c22d14472fd0d0bf87 100644 (file)
@@ -89,8 +89,8 @@ extern void qlog(char *fmt,...);
 void           remove_newlines(char *string);
 char      *strncpy_null(char *dst, const char *src, int len);
 char      *trim(char *string);
-char      *make_string(char *s, int len, char *buf);
-char      *my_strcat(char *buf, char *fmt, char *s, int len);
+char      *make_string(const char *s, int len, char *buf);
+char      *my_strcat(char *buf, const char *fmt, const char *s, int len);
 
 /* defines for return value of my_strcpy */
 #define STRCPY_SUCCESS         1
@@ -98,6 +98,6 @@ char     *my_strcat(char *buf, char *fmt, char *s, int len);
 #define STRCPY_TRUNCATED       (-1)
 #define STRCPY_NULL                    (-2)
 
-int                    my_strcpy(char *dst, int dst_len, char *src, int src_len);
+int                    my_strcpy(char *dst, int dst_len, const char *src, int src_len);
 
 #endif
index abc6b3d6eb4c67b47b8f3e721210bdedc24afa5a..fa81f4775f4d9f7032698826fde814a731d18992 100644 (file)
@@ -88,7 +88,7 @@ check_client_encoding(unsigned char *str)
                multibyte_client_encoding = BIG5;
                return ("BIG5");
        }
-       return ("OHTER");
+       return ("OTHER");
 }
 
 
index 60205c011b6b81cb10c6f6424974052326166712..dbb3142401f0acedbd71aa667e0308282c8571a2 100644 (file)
@@ -254,7 +254,7 @@ RETCODE  SQL_API SQLGetData(HSTMT StatementHandle,
 RETCODE  SQL_API SQLGetFunctions(HDBC ConnectionHandle,
            SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported)
 {
-       mylog("[SQLGetFunctions");
+       mylog("[SQLGetFunctions]");
 #if (ODBCVER >= 0x3000)
        if (FunctionId == SQL_API_ODBC3_ALL_FUNCTIONS)
                return PGAPI_GetFunctions30(ConnectionHandle, FunctionId, Supported);
@@ -270,10 +270,12 @@ RETCODE  SQL_API SQLGetInfo(HDBC ConnectionHandle,
        mylog("[SQLGetInfo(30)]");
        if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
                BufferLength, StringLength)) == SQL_ERROR)
-               return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
-               BufferLength, StringLength);
-       else
-               return ret;
+       {
+               if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x3000)
+                       return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
+                               BufferLength, StringLength);
+       }
+       return ret;
 #else
        mylog("[SQLGetInfo]");
        return PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
index cee57934df2e8c2878e948042502b981dc31bf40..e657595c031038806de17eebbdaf8c4946beb369 100644 (file)
@@ -395,7 +395,7 @@ RETCODE  SQL_API SQLSetEnvAttr(HENV EnvironmentHandle,
                        /* *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; */
                        return SQL_SUCCESS;
                case SQL_ATTR_ODBC_VERSION:
-                       if ((SQLUINTEGER) Value == SQL_OV_ODBC3)
+                       if ((SQLUINTEGER) Value == SQL_OV_ODBC2)
                                return SQL_SUCCESS;
                        break;
                case SQL_ATTR_OUTPUT_NTS:
index 77421b63ebda07758145db614332029a32b256c8..aa18bb1615c62faf03ecfef9de1ef08f6460e4d4 100644 (file)
@@ -33,7 +33,6 @@
 #include "pgapifunc.h"
 
 
-extern GLOBAL_VALUES globals;
 
 RETCODE set_statement_option(ConnectionClass *conn,
                                         StatementClass *stmt,
@@ -49,7 +48,12 @@ set_statement_option(ConnectionClass *conn,
 {
        static char *func = "set_statement_option";
        char            changed = FALSE;
+       ConnInfo *ci = NULL;
 
+       if (conn)
+               ci = &(conn->connInfo);
+       else if (stmt)
+               ci = &(SC_get_conn(stmt)->connInfo);
        switch (fOption)
        {
                case SQL_ASYNC_ENABLE:  /* ignored */
@@ -70,7 +74,7 @@ set_statement_option(ConnectionClass *conn,
                         * read-only
                         */
                        mylog("SetStmtOption(): SQL_CONCURRENCY = %d\n", vParam);
-                       if (globals.lie || vParam == SQL_CONCUR_READ_ONLY || vParam == SQL_CONCUR_ROWVER)
+                       if (ci->drivers.lie || vParam == SQL_CONCUR_READ_ONLY || vParam == SQL_CONCUR_ROWVER)
                        {
                                if (conn)
                                        conn->stmtOptions.scroll_concurrency = vParam;
@@ -95,7 +99,7 @@ set_statement_option(ConnectionClass *conn,
                         */
                        mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam);
 
-                       if (globals.lie)
+                       if (ci->drivers.lie)
                        {
                                if (conn)
                                        conn->stmtOptions.cursor_type = vParam;
@@ -104,7 +108,7 @@ set_statement_option(ConnectionClass *conn,
                        }
                        else
                        {
-                               if (globals.use_declarefetch)
+                               if (ci->drivers.use_declarefetch)
                                {
                                        if (conn)
                                                conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY;
@@ -147,7 +151,7 @@ set_statement_option(ConnectionClass *conn,
                        break;
 
                        /*-------
-                        *      if (globals.lie)
+                        *      if (ci->drivers.lie)
                         *              stmt->keyset_size = vParam;
                         *      else
                         *      {
@@ -433,6 +437,7 @@ PGAPI_GetConnectOption(
 {
        static char *func = "PGAPI_GetConnectOption";
        ConnectionClass *conn = (ConnectionClass *) hdbc;
+       ConnInfo *ci = &(conn->connInfo);
 
        mylog("%s: entering...\n", func);
 
@@ -464,7 +469,7 @@ PGAPI_GetConnectOption(
                        break;
 
                case SQL_PACKET_SIZE:   /* NOT SUPPORTED */
-                       *((UDWORD *) pvParam) = globals.socket_buffersize;
+                       *((UDWORD *) pvParam) = ci->drivers.socket_buffersize;
                        break;
 
                case SQL_QUIET_MODE:    /* NOT SUPPORTED */
@@ -536,6 +541,7 @@ PGAPI_GetStmtOption(
        static char *func = "PGAPI_GetStmtOption";
        StatementClass *stmt = (StatementClass *) hstmt;
        QResultClass *res;
+       ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
 
        mylog("%s: entering...\n", func);
 
@@ -557,7 +563,7 @@ PGAPI_GetStmtOption(
 
                        res = stmt->result;
 
-                       if (stmt->manual_result || !globals.use_declarefetch)
+                       if (stmt->manual_result || !ci->drivers.use_declarefetch)
                        {
                                /* make sure we're positioned on a valid row */
                                if ((stmt->currTuple < 0) ||
index fdc38d62a19f2c74551482d101d82f2f5f2e18c0..f2b185359010824b7bfc655404f42f4470316add 100644 (file)
@@ -34,7 +34,6 @@
 #endif
 
 
-extern GLOBAL_VALUES globals;
 
 Int4           getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
 
@@ -105,9 +104,10 @@ Int2               sqlTypes[] = {
 
 
 Int4
-sqltype_to_pgtype(SWORD fSqlType)
+sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
 {
        Int4            pgType;
+       ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
 
        switch (fSqlType)
        {
@@ -120,7 +120,7 @@ sqltype_to_pgtype(SWORD fSqlType)
                        break;
 
                case SQL_BIT:
-                       pgType = globals.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
+                       pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
                        break;
 
                case SQL_DATE:
@@ -150,7 +150,7 @@ sqltype_to_pgtype(SWORD fSqlType)
                        break;
 
                case SQL_LONGVARCHAR:
-                       pgType = globals.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
+                       pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
                        break;
 
                case SQL_REAL:
@@ -202,6 +202,7 @@ sqltype_to_pgtype(SWORD fSqlType)
 Int2
 pgtype_to_sqltype(StatementClass *stmt, Int4 type)
 {
+       ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
        switch (type)
        {
                case PG_TYPE_CHAR:
@@ -218,7 +219,7 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
                        return SQL_VARCHAR;
 
                case PG_TYPE_TEXT:
-                       return globals.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
+                       return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
 
                case PG_TYPE_BYTEA:
                        return SQL_VARBINARY;
@@ -255,7 +256,7 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
                case PG_TYPE_MONEY:
                        return SQL_FLOAT;
                case PG_TYPE_BOOL:
-                       return globals.bools_as_char ? SQL_CHAR : SQL_BIT;
+                       return ci->drivers.bools_as_char ? SQL_CHAR : SQL_BIT;
 
                default:
 
@@ -268,7 +269,7 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
                        if (type == stmt->hdbc->lobj_type)
                                return SQL_LONGVARBINARY;
 
-                       return globals.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
+                       return ci->drivers.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
        }
 }
 
@@ -276,6 +277,7 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
 Int2
 pgtype_to_ctype(StatementClass *stmt, Int4 type)
 {
+       ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
        switch (type)
        {
                case PG_TYPE_INT8:
@@ -303,7 +305,7 @@ pgtype_to_ctype(StatementClass *stmt, Int4 type)
                case PG_TYPE_MONEY:
                        return SQL_C_FLOAT;
                case PG_TYPE_BOOL:
-                       return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
+                       return ci->drivers.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
 
                case PG_TYPE_BYTEA:
                        return SQL_C_BINARY;
@@ -470,6 +472,7 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
                                maxsize;
        QResultClass *result;
        ColumnInfoClass *flds;
+       ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
 
        mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type, col, handle_unknown_size_as);
 
@@ -477,22 +480,22 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
        switch (type)
        {
                case PG_TYPE_TEXT:
-                       if (globals.text_as_longvarchar)
-                               maxsize = globals.max_longvarchar_size;
+                       if (ci->drivers.text_as_longvarchar)
+                               maxsize = ci->drivers.max_longvarchar_size;
                        else
-                               maxsize = globals.max_varchar_size;
+                               maxsize = ci->drivers.max_varchar_size;
                        break;
 
                case PG_TYPE_VARCHAR:
                case PG_TYPE_BPCHAR:
-                       maxsize = globals.max_varchar_size;
+                       maxsize = ci->drivers.max_varchar_size;
                        break;
 
                default:
-                       if (globals.unknowns_as_longvarchar)
-                               maxsize = globals.max_longvarchar_size;
+                       if (ci->drivers.unknowns_as_longvarchar)
+                               maxsize = ci->drivers.max_longvarchar_size;
                        else
-                               maxsize = globals.max_varchar_size;
+                               maxsize = ci->drivers.max_varchar_size;
                        break;
        }
 
index 03cc2babd16a1f2d32daafa270cac76cfe7b4793..7bd33cf7512d6e1232852aaf526bea61ee0d2c4b 100644 (file)
@@ -68,7 +68,7 @@ extern Int2 sqlTypes[];
 /*     Defines for pgtype_precision */
 #define PG_STATIC                              (-1)
 
-Int4           sqltype_to_pgtype(Int2 fSqlType);
+Int4           sqltype_to_pgtype(StatementClass *stmt, Int2 fSqlType);
 
 Int2           pgtype_to_sqltype(StatementClass *stmt, Int4 type);
 Int2           pgtype_to_ctype(StatementClass *stmt, Int4 type);
index 9851af2ee66e237c8258efc24e33817ccd03c823..ad156379d0a105bb4cf960d2b45b7b0633fb9092 100644 (file)
@@ -60,7 +60,7 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
                                return FALSE;
                        }
 
-                       getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+                       getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
                        break;
 
                case DLL_THREAD_ATTACH:
@@ -99,7 +99,7 @@ static BOOL
 __attribute__((constructor))
 init(void)
 {
-       getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+       getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
        return TRUE;
 }
 
@@ -112,7 +112,7 @@ init(void)
 BOOL
 _init(void)
 {
-       getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+       getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
        return TRUE;
 }
 
index 542fe7ff596ac57056b3a86caad4eb3aec2ac661..a6c5d9eda34122f2257c69b539ceec339369f3b6 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Comments:           See "notice.txt" for copyright and license information.
  *
- * $Id: psqlodbc.h,v 1.46 2001/08/24 14:07:50 petere Exp $
+ * $Id: psqlodbc.h,v 1.47 2001/09/07 06:02:22 inoue Exp $
  *
  */
 
@@ -145,10 +145,6 @@ typedef struct GlobalValues_
        char            extra_systable_prefixes[MEDIUM_REGISTRY_LEN];
        char            conn_settings[LARGE_REGISTRY_LEN];
        char            protocol[SMALL_REGISTRY_LEN];
-
-
-       FILE       *mylogFP;
-       FILE       *qlogFP;
 } GLOBAL_VALUES;
 
 typedef struct StatementOptions_
@@ -176,6 +172,7 @@ typedef struct QueryInfo_
        char       *cursor;
 } QueryInfo;
 
+void logs_on_off(int cnopen, int, int);
 
 #define PG_TYPE_LO                                     (-999)          /* hack until permanent
                                                                                                 * type available */
index 85bfcdb2893749b4c8b357b8b1e23b5a7835ae46..aa149ade93864b1c1db2b7ba3f47c604eeea4f3e 100644 (file)
@@ -83,7 +83,7 @@ BEGIN
                     DRV_MSG_LABEL,25,4,238,10
 END
 
-DLG_OPTIONS_DRV DIALOG DISCARDABLE  0, 0, 306, 213
+DLG_OPTIONS_DRV DIALOG DISCARDABLE  0, 0, 306, 226
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Advanced Options (Driver)"
 FONT 10, "Terminal"
@@ -104,34 +104,38 @@ BEGIN
                     BS_AUTOCHECKBOX | WS_TABSTOP,13,47,84,10
     CONTROL         "Cancel as FreeStmt (Exp)",DRV_CANCELASFREESTMT,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,164,50,112,10
-    GROUPBOX        "Unknown Sizes",IDC_STATIC,13,63,175,24
+    CONTROL         "Mylog(Debug ouput",DRV_DEBUG,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,164,63,112,10
+    GROUPBOX        "Unknown Sizes",IDC_STATIC,13,76,175,24
     CONTROL         "Maximum",DRV_UNKNOWN_MAX,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP | WS_TABSTOP,21,71,44,10
+                    WS_GROUP | WS_TABSTOP,21,84,44,10
     CONTROL         "Don't Know",DRV_UNKNOWN_DONTKNOW,"Button",
-                    BS_AUTORADIOBUTTON | WS_TABSTOP,72,71,56,10
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,72,84,56,10
     CONTROL         "Longest",DRV_UNKNOWN_LONGEST,"Button",
-                    BS_AUTORADIOBUTTON | WS_TABSTOP,135,71,44,10
-    GROUPBOX        "Data Type Options",IDC_STATIC,13,91,282,23
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,135,84,44,10
+    GROUPBOX        "Data Type Options",IDC_STATIC,13,104,282,23
     CONTROL         "Text as LongVarChar",DRV_TEXT_LONGVARCHAR,"Button",
-                    BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,102,92,10
+                    BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,115,92,10
     CONTROL         "Unknowns as LongVarChar",DRV_UNKNOWNS_LONGVARCHAR,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,102,108,10
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,115,108,10
     CONTROL         "Bools as Char",DRV_BOOLS_CHAR,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP,225,102,68,10
-    LTEXT           "&Cache Size:",IDC_STATIC,15,120,45,8
-    EDITTEXT        DRV_CACHE_SIZE,61,116,35,12,ES_AUTOHSCROLL
-    LTEXT           "Max &Varchar:",IDC_STATIC,99,120,49,8
-    EDITTEXT        DRV_VARCHAR_SIZE,149,116,35,12,ES_AUTOHSCROLL
-    LTEXT           "Max Lon&gVarChar:",IDC_STATIC,192,120,65,8
-    EDITTEXT        DRV_LONGVARCHAR_SIZE,259,116,35,12,ES_AUTOHSCROLL
-    LTEXT           "SysTable &Prefixes:",IDC_STATIC,23,131,36,20
-    EDITTEXT        DRV_EXTRASYSTABLEPREFIXES,61,137,75,12,ES_AUTOHSCROLL
-    LTEXT           "Connect &Settings:",IDC_STATIC,22,152,35,20
-    EDITTEXT        DRV_CONNSETTINGS,61,153,225,25,ES_MULTILINE | 
+                    WS_TABSTOP,225,115,68,10
+    LTEXT           "&Cache Size:",IDC_STATIC,15,133,45,8
+    EDITTEXT        DRV_CACHE_SIZE,61,129,35,12,ES_AUTOHSCROLL
+    LTEXT           "Max &Varchar:",IDC_STATIC,99,133,49,8
+    EDITTEXT        DRV_VARCHAR_SIZE,149,129,35,12,ES_AUTOHSCROLL
+    LTEXT           "Max Lon&gVarChar:",IDC_STATIC,192,133,65,8
+    EDITTEXT        DRV_LONGVARCHAR_SIZE,259,129,35,12,ES_AUTOHSCROLL
+    LTEXT           "SysTable &Prefixes:",IDC_STATIC,23,144,36,20
+    EDITTEXT        DRV_EXTRASYSTABLEPREFIXES,61,153,75,12,ES_AUTOHSCROLL
+    LTEXT           "Connect &Settings:",IDC_STATIC,22,165,35,20
+    EDITTEXT        DRV_CONNSETTINGS,61,165,225,25,ES_MULTILINE | 
                     ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
-    DEFPUSHBUTTON   "OK",IDOK,59,188,50,14,WS_GROUP
-    PUSHBUTTON      "Cancel",IDCANCEL,129,188,50,14
-    PUSHBUTTON      "Defaults",IDDEFAULTS,199,188,50,15
+    DEFPUSHBUTTON   "OK",IDOK,59,201,50,14,WS_GROUP
+    PUSHBUTTON      "Cancel",IDCANCEL,129,201,50,14
+    PUSHBUTTON      "Defaults",IDDEFAULTS,199,201,50,15
+    CONTROL         "DSN",DRV_OR_DSN,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
+                    BS_NOTIFY | WS_TABSTOP,243,208,30,10
 END
 
 DLG_OPTIONS_DS DIALOG DISCARDABLE  0, 0, 267, 161
@@ -194,7 +198,7 @@ BEGIN
                     DRV_MSG_LABEL,36,5,220,15
 END
 
-DLG_OPTIONS_DRV DIALOG DISCARDABLE  0, 0, 287, 226
+DLG_OPTIONS_DRV DIALOG DISCARDABLE  0, 0, 287, 241
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Advanced Options (Driver)"
 FONT 8, "MS Sans Serif"
@@ -215,34 +219,38 @@ BEGIN
                     BS_AUTOCHECKBOX | WS_TABSTOP,15,50,80,10
     CONTROL         "Cancel as FreeStmt (Exp)",DRV_CANCELASFREESTMT,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,140,50,105,10
-    GROUPBOX        "Unknown Sizes",IDC_STATIC,10,65,175,25
+    CONTROL         "Mylog(Debug ouput)",DRV_DEBUG,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,140,65,112,10
+    GROUPBOX        "Unknown Sizes",IDC_STATIC,10,80,175,25
     CONTROL         "Maximum",DRV_UNKNOWN_MAX,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP | WS_TABSTOP,15,76,45,10
+                    WS_GROUP | WS_TABSTOP,15,91,45,10
     CONTROL         "Don't Know",DRV_UNKNOWN_DONTKNOW,"Button",
-                    BS_AUTORADIOBUTTON | WS_TABSTOP,70,76,53,10
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,70,91,53,10
     CONTROL         "Longest",DRV_UNKNOWN_LONGEST,"Button",
-                    BS_AUTORADIOBUTTON | WS_TABSTOP,130,76,50,10
-    GROUPBOX        "Data Type Options",IDC_STATIC,10,95,270,25
+                    BS_AUTORADIOBUTTON | WS_TABSTOP,130,91,50,10
+    GROUPBOX        "Data Type Options",IDC_STATIC,10,110,270,25
     CONTROL         "Text as LongVarChar",DRV_TEXT_LONGVARCHAR,"Button",
-                    BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,105,80,10
+                    BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,120,80,10
     CONTROL         "Unknowns as LongVarChar",DRV_UNKNOWNS_LONGVARCHAR,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,105,100,10
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,120,100,10
     CONTROL         "Bools as Char",DRV_BOOLS_CHAR,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP,215,105,60,10
-    LTEXT           "&Cache Size:",IDC_STATIC,10,130,40,10
-    EDITTEXT        DRV_CACHE_SIZE,50,130,35,12,ES_AUTOHSCROLL
-    LTEXT           "Max &Varchar:",IDC_STATIC,90,130,45,10
-    EDITTEXT        DRV_VARCHAR_SIZE,135,130,35,12,ES_AUTOHSCROLL
-    LTEXT           "Max Lon&gVarChar:",IDC_STATIC,180,130,60,10
-    EDITTEXT        DRV_LONGVARCHAR_SIZE,240,130,35,12,ES_AUTOHSCROLL
-    LTEXT           "SysTable &Prefixes:",IDC_STATIC,15,145,35,20
-    EDITTEXT        DRV_EXTRASYSTABLEPREFIXES,50,151,75,12,ES_AUTOHSCROLL
-    RTEXT           "Connect &Settings:",IDC_STATIC,10,170,35,20
-    EDITTEXT        DRV_CONNSETTINGS,50,170,225,25,ES_MULTILINE | 
+                    WS_TABSTOP,215,120,60,10
+    LTEXT           "&Cache Size:",IDC_STATIC,10,145,40,10
+    EDITTEXT        DRV_CACHE_SIZE,50,145,35,12,ES_AUTOHSCROLL
+    LTEXT           "Max &Varchar:",IDC_STATIC,90,145,45,10
+    EDITTEXT        DRV_VARCHAR_SIZE,135,145,35,12,ES_AUTOHSCROLL
+    LTEXT           "Max Lon&gVarChar:",IDC_STATIC,180,145,60,10
+    EDITTEXT        DRV_LONGVARCHAR_SIZE,240,145,35,12,ES_AUTOHSCROLL
+    LTEXT           "SysTable &Prefixes:",IDC_STATIC,15,160,35,20
+    EDITTEXT        DRV_EXTRASYSTABLEPREFIXES,50,166,75,12,ES_AUTOHSCROLL
+    RTEXT           "Connect &Settings:",IDC_STATIC,10,185,35,20
+    EDITTEXT        DRV_CONNSETTINGS,50,185,225,25,ES_MULTILINE | 
                     ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
-    DEFPUSHBUTTON   "OK",IDOK,45,205,50,14,WS_GROUP
-    PUSHBUTTON      "Cancel",IDCANCEL,115,205,50,14
-    PUSHBUTTON      "Defaults",IDDEFAULTS,185,205,50,15
+    DEFPUSHBUTTON   "OK",IDOK,45,220,50,14,WS_GROUP
+    PUSHBUTTON      "Cancel",IDCANCEL,115,220,50,14
+    PUSHBUTTON      "Defaults",IDDEFAULTS,185,220,50,15
+    CONTROL         "DSN",DRV_OR_DSN,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
+                    BS_NOTIFY | WS_TABSTOP,243,224,30,10
 END
 
 DLG_OPTIONS_DS DIALOG DISCARDABLE  0, 0, 267, 161
index 086f4b875234e8ee5fe31f2188438485acc53a74..e2d7541e362e885d194616edf913858f8d2530ea 100644 (file)
@@ -86,7 +86,7 @@ QR_inc_base(QResultClass *self, int base_inc)
  * CLASS QResult
  */
 QResultClass *
-QR_Constructor(void)
+QR_Constructor()
 {
        QResultClass *rv;
 
@@ -239,6 +239,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
         */
        if (conn != NULL)
        {
+               ConnInfo *ci = &(conn->connInfo);
                self->conn = conn;
 
                mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor == NULL) ? "" : cursor, self->cursor);
@@ -246,7 +247,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
                if (self->cursor)
                        free(self->cursor);
 
-               if (globals.use_declarefetch)
+               if (ci->drivers.use_declarefetch)
                {
                        if (!cursor || cursor[0] == '\0')
                        {
@@ -276,13 +277,14 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
 
                mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields);
 
-               if (globals.use_declarefetch)
+               if (ci->drivers.use_declarefetch)
                        tuple_size = self->cache_size;
                else
                        tuple_size = TUPLE_MALLOC_INC;
 
                /* allocate memory for the tuple cache */
                mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
+               self->count_allocated = 0;
                self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);
                if (!self->backend_tuples)
                {
@@ -329,7 +331,7 @@ QR_close(QResultClass *self)
 {
        QResultClass *res;
 
-       if (globals.use_declarefetch && self->conn && self->cursor)
+       if (self->conn && self->cursor && self->conn->connInfo.drivers.use_declarefetch)
        {
                char            buf[64];
 
@@ -399,6 +401,7 @@ QR_next_tuple(QResultClass *self)
        char            cmdbuffer[ERROR_MSG_LENGTH + 1];
        char            fetch[128];
        QueryInfo       qi;
+       ConnInfo        *ci = NULL;
 
        if (fetch_count < fcount)
        {
@@ -430,7 +433,8 @@ QR_next_tuple(QResultClass *self)
 
                if (!self->inTuples)
                {
-                       if (!globals.use_declarefetch)
+                       ci = &(self->conn->connInfo);
+                       if (!ci->drivers.use_declarefetch)
                        {
                                mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count);
                                self->tupleField = NULL;
@@ -442,10 +446,10 @@ QR_next_tuple(QResultClass *self)
                        {
                                /* not a correction */
                                /* Determine the optimum cache size.  */
-                               if (globals.fetch_max % self->rowset_size == 0)
-                                       fetch_size = globals.fetch_max;
-                               else if (self->rowset_size < globals.fetch_max)
-                                       fetch_size = (globals.fetch_max / self->rowset_size) * self->rowset_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;
 
@@ -465,13 +469,17 @@ QR_next_tuple(QResultClass *self)
                                self->fetch_count++;
                        }
 
-                       if (self->cache_size > self->count_allocated)
-                               self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
-                       if (!self->backend_tuples)
+                       if (!self->backend_tuples || self->cache_size > self->count_allocated)
                        {
-                               self->status = PGRES_FATAL_ERROR;
-                               QR_set_message(self, "Out of memory while reading tuples.");
-                               return FALSE;
+                               self->count_allocated = 0;
+                               self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
+                               if (!self->backend_tuples)
+                               {
+                                       self->status = PGRES_FATAL_ERROR;
+                                       QR_set_message(self, "Out of memory while reading tuples.");
+                                       return FALSE;
+                               }
+                               self->count_allocated = self->cache_size;
                        }
                        sprintf(fetch, "fetch %d in %s", fetch_size, self->cursor);
 
@@ -482,10 +490,12 @@ QR_next_tuple(QResultClass *self)
                        qi.result_in = self;
                        qi.cursor = NULL;
                        res = CC_send_query(self->conn, fetch, &qi);
-                       if (res == NULL)
+                       if (res == NULL || QR_get_aborted(res))
                        {
                                self->status = PGRES_FATAL_ERROR;
                                QR_set_message(self, "Error fetching next group.");
+                               if (res)
+                                       QR_Destructor(res);
                                return FALSE;
                        }
                        self->inTuples = TRUE;
@@ -511,6 +521,7 @@ QR_next_tuple(QResultClass *self)
 
        sock = CC_get_socket(self->conn);
        self->tupleField = NULL;
+       ci = &(self->conn->connInfo);
 
        for (;;)
        {
@@ -526,7 +537,7 @@ QR_next_tuple(QResultClass *self)
                        case 'B':                       /* Tuples in binary format */
                        case 'D':                       /* Tuples in ASCII format  */
 
-                               if (!globals.use_declarefetch && self->fcount >= self->count_allocated)
+                               if (!ci->drivers.use_declarefetch && self->fcount >= self->count_allocated)
                                {
                                        int tuple_size = self->count_allocated;
 
index 213f6f5d8c0054f778b0cf35fc1fb8a3e6954fe2..5ac559c478d4c49c1a24d37bf90fe2f19e8de9ea 100644 (file)
@@ -1,62 +1,64 @@
-/* {{NO_DEPENDENCIES}} */
-/* Microsoft Developer Studio generated include file. */
-/* Used by psqlodbc.rc */
-
-#define IDS_BADDSN                                             1
-#define IDS_MSGTITLE                                   2
-#define DLG_OPTIONS_DRV                                        102
-#define DLG_OPTIONS_DS                                 103
-#define IDC_DSNAME                                             400
-#define IDC_DSNAMETEXT                                 401
-#define IDC_DESC                                               404
-#define IDC_SERVER                                             407
-#define IDC_DATABASE                                   408
-#define DLG_CONFIG                                             1001
-#define IDC_PORT                                               1002
-#define IDC_USER                                               1006
-#define IDC_PASSWORD                                   1009
-#define DS_READONLY                                            1011
-#define DS_SHOWOIDCOLUMN                               1012
-#define DS_FAKEOIDINDEX                                        1013
-#define DRV_COMMLOG                                            1014
-#define DS_PG62                                                        1016
-#define IDC_DATASOURCE                                 1018
-#define DRV_OPTIMIZER                                  1019
-#define DS_CONNSETTINGS                                        1020
-#define IDC_DRIVER                                             1021
-#define DRV_CONNSETTINGS                               1031
-#define DRV_UNIQUEINDEX                                        1032
-#define DRV_UNKNOWN_MAX                                        1035
-#define DRV_UNKNOWN_DONTKNOW                   1036
-#define DRV_READONLY                                   1037
-#define IDC_DESCTEXT                                   1039
-#define DRV_MSG_LABEL                                  1040
-#define DRV_UNKNOWN_LONGEST                            1041
-#define DRV_TEXT_LONGVARCHAR                   1043
-#define DRV_UNKNOWNS_LONGVARCHAR               1044
-#define DRV_CACHE_SIZE                                 1045
-#define DRV_VARCHAR_SIZE                               1046
-#define DRV_LONGVARCHAR_SIZE                   1047
-#define IDDEFAULTS                                             1048
-#define DRV_USEDECLAREFETCH                            1049
-#define DRV_BOOLS_CHAR                                 1050
-#define DS_SHOWSYSTEMTABLES                            1051
-#define DRV_EXTRASYSTABLEPREFIXES              1051
-#define DS_ROWVERSIONING                               1052
-#define DRV_PARSE                                              1052
-#define DRV_CANCELASFREESTMT                   1053
-#define IDC_OPTIONS                                            1054
-#define DRV_KSQO                                               1055
-#define DS_PG64                                                        1057
-#define DS_PG63                                                        1058
-
-/* Next default values for new objects */
-
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE               104
-#define _APS_NEXT_COMMAND_VALUE                        40001
-#define _APS_NEXT_CONTROL_VALUE                        1060
-#define _APS_NEXT_SYMED_VALUE                  101
-#endif
-#endif
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Developer Studio generated include file.\r
+// Used by psqlodbc.rc\r
+//\r
+#define IDS_BADDSN                      1\r
+#define IDS_MSGTITLE                    2\r
+#define DLG_OPTIONS_DRV                 102\r
+#define DLG_OPTIONS_DS                  103\r
+#define IDC_DSNAME                      400\r
+#define IDC_DSNAMETEXT                  401\r
+#define IDC_DESC                        404\r
+#define IDC_SERVER                      407\r
+#define IDC_DATABASE                    408\r
+#define DLG_CONFIG                      1001\r
+#define IDC_PORT                        1002\r
+#define IDC_USER                        1006\r
+#define IDC_PASSWORD                    1009\r
+#define DS_READONLY                     1011\r
+#define DS_SHOWOIDCOLUMN                1012\r
+#define DS_FAKEOIDINDEX                 1013\r
+#define DRV_COMMLOG                     1014\r
+#define DS_PG62                         1016\r
+#define IDC_DATASOURCE                  1018\r
+#define DRV_OPTIMIZER                   1019\r
+#define DS_CONNSETTINGS                 1020\r
+#define IDC_DRIVER                      1021\r
+#define DRV_CONNSETTINGS                1031\r
+#define DRV_UNIQUEINDEX                 1032\r
+#define DRV_UNKNOWN_MAX                 1035\r
+#define DRV_UNKNOWN_DONTKNOW            1036\r
+#define DRV_READONLY                    1037\r
+#define IDC_DESCTEXT                    1039\r
+#define DRV_MSG_LABEL                   1040\r
+#define DRV_UNKNOWN_LONGEST             1041\r
+#define DRV_TEXT_LONGVARCHAR            1043\r
+#define DRV_UNKNOWNS_LONGVARCHAR        1044\r
+#define DRV_CACHE_SIZE                  1045\r
+#define DRV_VARCHAR_SIZE                1046\r
+#define DRV_LONGVARCHAR_SIZE            1047\r
+#define IDDEFAULTS                      1048\r
+#define DRV_USEDECLAREFETCH             1049\r
+#define DRV_BOOLS_CHAR                  1050\r
+#define DS_SHOWSYSTEMTABLES             1051\r
+#define DRV_EXTRASYSTABLEPREFIXES       1051\r
+#define DS_ROWVERSIONING                1052\r
+#define DRV_PARSE                       1052\r
+#define DRV_CANCELASFREESTMT            1053\r
+#define IDC_OPTIONS                     1054\r
+#define DRV_KSQO                        1055\r
+#define DS_PG64                         1057\r
+#define DS_PG63                         1058\r
+#define DRV_OR_DSN                      1059\r
+#define DRV_DEBUG                      1060\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NEXT_RESOURCE_VALUE        105\r
+#define _APS_NEXT_COMMAND_VALUE         40001\r
+#define _APS_NEXT_CONTROL_VALUE         1061\r
+#define _APS_NEXT_SYMED_VALUE           101\r
+#endif\r
+#endif\r
index bb1f2975df6ec4593103160b7dd7cdc8271d7ed5..b63a214b816625e6c1714537c86cbb25d5bcbacb 100644 (file)
@@ -38,7 +38,6 @@
 #endif
 #include "pgapifunc.h"
 
-extern GLOBAL_VALUES globals;
 
 
 RETCODE SQL_API
@@ -51,12 +50,14 @@ PGAPI_RowCount(
        QResultClass *res;
        char       *msg,
                           *ptr;
+       ConnInfo *ci;
 
        if (!stmt)
        {
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
+       ci = &(SC_get_conn(stmt)->connInfo);
        if (stmt->manual_result)
        {
                if (pcrow)
@@ -72,7 +73,7 @@ PGAPI_RowCount(
 
                        if (res && pcrow)
                        {
-                               *pcrow = globals.use_declarefetch ? -1 : QR_get_num_tuples(res);
+                               *pcrow = ci->drivers.use_declarefetch ? -1 : QR_get_num_tuples(res);
                                return SQL_SUCCESS;
                        }
                }
@@ -119,17 +120,19 @@ PGAPI_NumResultCols(
        StatementClass *stmt = (StatementClass *) hstmt;
        QResultClass *result;
        char            parse_ok;
+       ConnInfo *ci;
 
        if (!stmt)
        {
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        SC_clear_error(stmt);
 
        parse_ok = FALSE;
-       if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
+       if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT)
        {
                if (stmt->parse_status == STMT_PARSE_NONE)
                {
@@ -211,7 +214,7 @@ PGAPI_DescribeCol(
                return SQL_INVALID_HANDLE;
        }
 
-       ci = &(stmt->hdbc->connInfo);
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        SC_clear_error(stmt);
 
@@ -223,7 +226,7 @@ PGAPI_DescribeCol(
        icol--;                                         /* use zero based column numbers */
 
        parse_ok = FALSE;
-       if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
+       if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT)
        {
                if (stmt->parse_status == STMT_PARSE_NONE)
                {
@@ -288,7 +291,7 @@ PGAPI_DescribeCol(
                fieldtype = QR_get_field_type(res, icol);
 
                /* atoi(ci->unknown_sizes) */
-               precision = pgtype_precision(stmt, fieldtype, icol, globals.unknown_sizes);
+               precision = pgtype_precision(stmt, fieldtype, icol, ci->drivers.unknown_sizes);
        }
 
        mylog("describeCol: col %d fieldname = '%s'\n", icol, col_name);
@@ -400,7 +403,7 @@ PGAPI_ColAttributes(
                return SQL_INVALID_HANDLE;
        }
 
-       ci = &(stmt->hdbc->connInfo);
+       ci = &(SC_get_conn(stmt)->connInfo);
 
        /*
         * Dont check for bookmark column.      This is the responsibility of the
@@ -411,14 +414,14 @@ PGAPI_ColAttributes(
        icol--;
 
        /* atoi(ci->unknown_sizes); */
-       unknown_sizes = globals.unknown_sizes;
+       unknown_sizes = ci->drivers.unknown_sizes;
 
        /* not appropriate for SQLColAttributes() */
        if (unknown_sizes == UNKNOWNS_AS_DONTKNOW)
                unknown_sizes = UNKNOWNS_AS_MAX;
 
        parse_ok = FALSE;
-       if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
+       if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT)
        {
                if (stmt->parse_status == STMT_PARSE_NONE)
                {
@@ -660,6 +663,7 @@ PGAPI_GetData(
        void       *value = NULL;
        int                     result;
        char            get_bookmark = FALSE;
+       ConnInfo *ci;
 
        mylog("PGAPI_GetData: enter, stmt=%u\n", stmt);
 
@@ -668,6 +672,7 @@ PGAPI_GetData(
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
+       ci = &(SC_get_conn(stmt)->connInfo);
        res = stmt->result;
 
        if (STMT_EXECUTING == stmt->status)
@@ -723,7 +728,7 @@ PGAPI_GetData(
                }
        }
 
-       if (stmt->manual_result || !globals.use_declarefetch)
+       if (stmt->manual_result || !ci->drivers.use_declarefetch)
        {
                /* make sure we're positioned on a valid row */
                num_rows = QR_get_num_tuples(res);
@@ -913,6 +918,7 @@ PGAPI_ExtendedFetch(
        RETCODE         result;
        char            truncated,
                                error;
+       ConnInfo *ci;
 
        mylog("PGAPI_ExtendedFetch: stmt=%u\n", stmt);
 
@@ -921,8 +927,9 @@ PGAPI_ExtendedFetch(
                SC_log_error(func, "", NULL);
                return SQL_INVALID_HANDLE;
        }
+       ci = &(SC_get_conn(stmt)->connInfo);
 
-       if (globals.use_declarefetch && !stmt->manual_result)
+       if (ci->drivers.use_declarefetch && !stmt->manual_result)
        {
                if (fFetchType != SQL_FETCH_NEXT)
                {
@@ -1101,7 +1108,7 @@ PGAPI_ExtendedFetch(
         * Handle Declare Fetch style specially because the end is not really
         * the end...
         */
-       if (globals.use_declarefetch && !stmt->manual_result)
+       if (ci->drivers.use_declarefetch && !stmt->manual_result)
        {
                if (QR_end_tuples(res))
                        return SQL_NO_DATA_FOUND;
@@ -1183,7 +1190,7 @@ PGAPI_ExtendedFetch(
        stmt->currTuple = stmt->rowset_start;
 
        /* For declare/fetch, need to reset cursor to beginning of rowset */
-       if (globals.use_declarefetch && !stmt->manual_result)
+       if (ci->drivers.use_declarefetch && !stmt->manual_result)
                QR_set_position(res, 0);
 
        /* Set the number of rows retrieved */
index 2a779b417fc1c19989365fdd6db9ea685242a197..65f3423cf15916af1da990573787022049e9d8ce 100644 (file)
@@ -27,7 +27,6 @@
 #define INTFUNC  __stdcall
 
 extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
-extern GLOBAL_VALUES globals;
 
 /* Constants */
 #define MIN(x,y)         ((x) < (y) ? (x) : (y))
@@ -218,48 +217,48 @@ ConfigDlgProc(HWND hdlg,
                          WPARAM wParam,
                          LPARAM lParam)
 {
+       LPSETUPDLG      lpsetupdlg;
+       ConnInfo        *ci;
        switch (wMsg)
        {
-                       /* Initialize the dialog */
-                       case WM_INITDIALOG:
+               /* Initialize the dialog */
+               case WM_INITDIALOG:
+                       lpsetupdlg = (LPSETUPDLG) lParam;
+                       ci = &lpsetupdlg->ci;
+
+                       /* Hide the driver connect message */
+                       ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
+
+                       SetWindowLong(hdlg, DWL_USER, lParam);
+                       CenterDialog(hdlg);             /* Center dialog */
+
+                       /*
+                        * NOTE: Values supplied in the attribute string will
+                        * always
+                        */
+                       /* override settings in ODBC.INI */
+
+                       /* Get the rest of the common attributes */
+                       getDSNinfo(ci, CONN_DONT_OVERWRITE);
+
+                       /* Fill in any defaults */
+                       getDSNdefaults(ci);
+
+                       /* Initialize dialog fields */
+                       SetDlgStuff(hdlg, ci);
+
+                       if (lpsetupdlg->fDefault)
                        {
-                               LPSETUPDLG      lpsetupdlg = (LPSETUPDLG) lParam;
-                               ConnInfo   *ci = &lpsetupdlg->ci;
-
-                               /* Hide the driver connect message */
-                               ShowWindow(GetDlgItem(hdlg, DRV_MSG_LABEL), SW_HIDE);
-
-                               SetWindowLong(hdlg, DWL_USER, lParam);
-                               CenterDialog(hdlg);             /* Center dialog */
-
-                               /*
-                                * NOTE: Values supplied in the attribute string will
-                                * always
-                                */
-                               /* override settings in ODBC.INI */
-
-                               /* Get the rest of the common attributes */
-                               getDSNinfo(ci, CONN_DONT_OVERWRITE);
-
-                               /* Fill in any defaults */
-                               getDSNdefaults(ci);
-
-                               /* Initialize dialog fields */
-                               SetDlgStuff(hdlg, ci);
-
-                               if (lpsetupdlg->fDefault)
-                               {
-                                       EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
-                                       EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
-                               }
-                               else
-                                       SendDlgItemMessage(hdlg, IDC_DSNAME,
-                                                        EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
-
-                               SendDlgItemMessage(hdlg, IDC_DESC,
-                                                          EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
-                               return TRUE;    /* Focus was not set */
+                               EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
+                               EnableWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), FALSE);
                        }
+                       else
+                               SendDlgItemMessage(hdlg, IDC_DSNAME,
+                                                EM_LIMITTEXT, (WPARAM) (MAXDSNAME - 1), 0L);
+
+                       SendDlgItemMessage(hdlg, IDC_DESC,
+                                                  EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
+                       return TRUE;    /* Focus was not set */
 
                        /* Process buttons */
                case WM_COMMAND:
@@ -286,21 +285,17 @@ ConfigDlgProc(HWND hdlg,
 
                                        /* Accept results */
                                case IDOK:
-                                       {
-                                               LPSETUPDLG      lpsetupdlg;
-
-                                               lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
-                                               /* Retrieve dialog values */
-                                               if (!lpsetupdlg->fDefault)
-                                                       GetDlgItemText(hdlg, IDC_DSNAME,
+                                       lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
+                                       /* Retrieve dialog values */
+                                       if (!lpsetupdlg->fDefault)
+                                               GetDlgItemText(hdlg, IDC_DSNAME,
                                                                                   lpsetupdlg->ci.dsn,
                                                                                   sizeof(lpsetupdlg->ci.dsn));
-                                               /* Get Dialog Values */
-                                               GetDlgStuff(hdlg, &lpsetupdlg->ci);
+                                       /* Get Dialog Values */
+                                       GetDlgStuff(hdlg, &lpsetupdlg->ci);
 
-                                               /* Update ODBC.INI */
-                                               SetDSNAttributes(hdlg, lpsetupdlg);
-                                       }
+                                       /* Update ODBC.INI */
+                                       SetDSNAttributes(hdlg, lpsetupdlg);
 
                                        /* Return to caller */
                                case IDCANCEL:
@@ -308,22 +303,18 @@ ConfigDlgProc(HWND hdlg,
                                        return TRUE;
 
                                case IDC_DRIVER:
+                                       lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
                                        DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
-                                                               hdlg, driver_optionsProc, (LPARAM) NULL);
-
+                                                               hdlg, driver_optionsProc, (LPARAM) &lpsetupdlg->ci);
                                        return TRUE;
 
                                case IDC_DATASOURCE:
-                                       {
-                                               LPSETUPDLG      lpsetupdlg;
+                                       lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
 
-                                               lpsetupdlg = (LPSETUPDLG) GetWindowLong(hdlg, DWL_USER);
-
-                                               DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
+                                       DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
                                                 hdlg, ds_optionsProc, (LPARAM) &lpsetupdlg->ci);
 
-                                               return TRUE;
-                                       }
+                                       return TRUE;
                        }
                        break;
        }
index ed3fd2913c6b0e58eb0cb6645a9478fcd43c72c6..fbfb5ca929797a77be1d456f4339da165cbfd388 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "socket.h"
+#include "connection.h"
 
 #ifndef WIN32
 #include <stdlib.h>
@@ -41,7 +42,7 @@ SOCK_clear_error(SocketClass *self)
 
 
 SocketClass *
-SOCK_Constructor()
+SOCK_Constructor(const ConnectionClass *conn)
 {
        SocketClass *rv;
 
@@ -54,14 +55,18 @@ SOCK_Constructor()
                rv->buffer_filled_out = 0;
                rv->buffer_read_in = 0;
 
-               rv->buffer_in = (unsigned char *) malloc(globals.socket_buffersize);
+               if (rv)
+                       rv->buffer_size = conn->connInfo.drivers.socket_buffersize;
+               else
+                       rv->buffer_size = globals.socket_buffersize;
+               rv->buffer_in = (unsigned char *) malloc(rv->buffer_size);
                if (!rv->buffer_in)
                {
                        free(rv);
                        return NULL;
                }
 
-               rv->buffer_out = (unsigned char *) malloc(globals.socket_buffersize);
+               rv->buffer_out = (unsigned char *) malloc(rv->buffer_size);
                if (!rv->buffer_out)
                {
                        free(rv->buffer_in);
@@ -79,6 +84,7 @@ SOCK_Constructor()
 void
 SOCK_Destructor(SocketClass *self)
 {
+mylog("SOCK_Destructor\n");
        if (self->socket != -1)
        {
                SOCK_put_char(self, 'X');
@@ -305,9 +311,9 @@ SOCK_get_next_byte(SocketClass *self)
                 * there are no more bytes left in the buffer so reload the buffer
                 */
                self->buffer_read_in = 0;
-               self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, globals.socket_buffersize, 0);
+               self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, self->buffer_size, 0);
 
-               mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, globals.socket_buffersize);
+               mylog("read %d, global_socket_buffersize=%d\n", self->buffer_filled_in, self->buffer_size);
 
                if (self->buffer_filled_in < 0)
                {
@@ -335,11 +341,11 @@ SOCK_put_next_byte(SocketClass *self, unsigned char next_byte)
 
        self->buffer_out[self->buffer_filled_out++] = next_byte;
 
-       if (self->buffer_filled_out == globals.socket_buffersize)
+       if (self->buffer_filled_out == self->buffer_size)
        {
                /* buffer is full, so write it out */
-               bytes_sent = send(self->socket, (char *) self->buffer_out, globals.socket_buffersize, 0);
-               if (bytes_sent != globals.socket_buffersize)
+               bytes_sent = send(self->socket, (char *) self->buffer_out, self->buffer_size, 0);
+               if (bytes_sent != self->buffer_size)
                {
                        self->errornumber = SOCKET_WRITE_ERROR;
                        self->errormsg = "Error while writing to the socket.";
index b24be9504d45e37b1196cffc33b14057ab79a010..f4c7b9e4e43bd93dc976b51080fd9e8c915930f0 100644 (file)
@@ -53,6 +53,7 @@ typedef unsigned int in_addr_t;
 struct SocketClass_
 {
 
+       int                     buffer_size;
        int                     buffer_filled_in;
        int                     buffer_filled_out;
        int                     buffer_read_in;
@@ -79,7 +80,7 @@ struct SocketClass_
 
 
 /* Socket prototypes */
-SocketClass *SOCK_Constructor(void);
+SocketClass *SOCK_Constructor(const ConnectionClass *conn);
 void           SOCK_Destructor(SocketClass *self);
 char           SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname);
 void           SOCK_get_n_char(SocketClass *self, char *buffer, int len);
index 891f47df8312f7216db563d2cac101094644e796..bb4fab9bccf9d62f274be212ba3d6ddae2e89f2c 100644 (file)
@@ -32,7 +32,6 @@
 #endif
 #include "pgapifunc.h"
 
-extern GLOBAL_VALUES globals;
 
 #ifndef WIN32
 #ifndef HAVE_STRICMP
@@ -291,6 +290,7 @@ SC_Constructor(void)
 
                rv->pre_executing = FALSE;
                rv->inaccurate_result = FALSE;
+               rv->miscinfo = 0;
        }
        return rv;
 }
@@ -560,6 +560,7 @@ SC_pre_execute(StatementClass *self)
        {
                mylog("              preprocess: status = READY\n");
 
+               self->miscinfo = 0;
                if (self->statement_type == STMT_TYPE_SELECT)
                {
                        char            old_pre_executing = self->pre_executing;
@@ -577,7 +578,7 @@ SC_pre_execute(StatementClass *self)
                                self->status = STMT_PREMATURE;
                        }
                }
-               else
+               if (!SC_is_pre_executable(self))
                {
                        self->result = QR_Constructor();
                        QR_set_status(self->result, PGRES_TUPLES_OK);
@@ -718,15 +719,16 @@ SC_fetch(StatementClass *self)
                                lf;
        Oid                     type;
        char       *value;
-       ColumnInfoClass *ci;
+       ColumnInfoClass *coli;
        /* TupleField *tupleField; */
+       ConnInfo *ci = &(SC_get_conn(self)->connInfo);
 
        self->last_fetch_count = 0;
-       ci = QR_get_fields(res);        /* the column info */
+       coli = QR_get_fields(res);      /* the column info */
 
-       mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, globals.use_declarefetch);
+       mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch);
 
-       if (self->manual_result || !globals.use_declarefetch)
+       if (self->manual_result || !ci->drivers.use_declarefetch)
        {
                if (self->currTuple >= QR_get_num_tuples(res) - 1 ||
                        (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))
@@ -807,7 +809,7 @@ SC_fetch(StatementClass *self)
                        /* this column has a binding */
 
                        /* type = QR_get_field_type(res, lf); */
-                       type = CI_get_oid(ci, lf);      /* speed things up */
+                       type = CI_get_oid(coli, lf);    /* speed things up */
 
                        mylog("type = %d\n", type);
 
@@ -816,7 +818,7 @@ SC_fetch(StatementClass *self)
                                value = QR_get_value_manual(res, self->currTuple, lf);
                                mylog("manual_result\n");
                        }
-                       else if (globals.use_declarefetch)
+                       else if (ci->drivers.use_declarefetch)
                                value = QR_get_value_backend(res, lf);
                        else
                                value = QR_get_value_backend_row(res, self->currTuple, lf);
@@ -895,9 +897,11 @@ SC_execute(StatementClass *self)
        Int2            oldstatus,
                                numcols;
        QueryInfo       qi;
+       ConnInfo *ci;
 
 
        conn = SC_get_conn(self);
+       ci = &(conn->connInfo);
 
        /* Begin a transaction if one is not already in progress */
 
@@ -910,7 +914,8 @@ SC_execute(StatementClass *self)
         * OTHER.
         */
        if (!self->internal && !CC_is_in_trans(conn) &&
-               ((globals.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) || (!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER)))
+           ((ci->drivers.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) ||
+            (!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER)))
        {
                mylog("   about to begin a transaction on statement = %u\n", self);
                res = CC_send_query(conn, "BEGIN", NULL);
@@ -959,7 +964,7 @@ SC_execute(StatementClass *self)
                /* send the declare/select */
                self->result = CC_send_query(conn, self->stmt_with_params, NULL);
 
-               if (globals.use_declarefetch && self->result != NULL &&
+               if (ci->drivers.use_declarefetch && self->result != NULL &&
                        QR_command_successful(self->result))
                {
                        QR_Destructor(self->result);
@@ -970,7 +975,7 @@ SC_execute(StatementClass *self)
                         */
                        qi.result_in = NULL;
                        qi.cursor = self->cursor_name;
-                       qi.row_size = globals.fetch_max;
+                       qi.row_size = ci->drivers.fetch_max;
 
                        /*
                         * Most likely the rowset size will not be set by the
@@ -1075,21 +1080,21 @@ SC_execute(StatementClass *self)
            (self->errornumber == STMT_OK ||
             self->errornumber == STMT_INFO_ONLY) &&
            self->parameters &&
-           self->parameters[0].buflen > 0 &&
+           self->parameters[0].buffer &&
            self->parameters[0].paramType == SQL_PARAM_OUTPUT)
        {       /* get the return value of the procedure call */
                RETCODE ret;
                HSTMT hstmt = (HSTMT) self;
-               ret = PGAPI_BindCol(hstmt, 1, self->parameters[0].CType, self->parameters[0].buffer, self->parameters[0].buflen, self->parameters[0].used);
-               if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) 
-                       SC_fetch(hstmt);
-               else
-               {
-                       self->errornumber = STMT_EXEC_ERROR;
-                       self->errormsg = "BindCol to Procedure return failed.";
+               ret = SC_fetch(hstmt);
+               if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
+               { 
+                       ret = PGAPI_GetData(hstmt, 1, self->parameters[0].CType, self->parameters[0].buffer, self->parameters[0].buflen, self->parameters[0].used);
+                       if (ret != SQL_SUCCESS) 
+                       {
+                               self->errornumber = STMT_EXEC_ERROR;
+                               self->errormsg = "GetData to Procedure return failed.";
+                       }
                }
-               if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) 
-                       PGAPI_BindCol(hstmt, 1, self->parameters[0].CType, NULL, 0, NULL);
                else
                {
                        self->errornumber = STMT_EXEC_ERROR;
index 571d13edaca8dc3849fbe2ebb493a801603338ea..95ae1437a12a65cd902d80a9f1a18652472867e6 100644 (file)
@@ -216,10 +216,10 @@ struct StatementClass_
        int             stmt_size_limit;        
 
        char            pre_executing;  /* This statement is prematurely executing */
-       char            inaccurate_result;              /* Current status is PREMATURE but
-                                                                                * result is inaccurate */
-       char            errormsg_malloced;              /* Current status is PREMATURE but
+       char            inaccurate_result;      /* Current status is PREMATURE but
                                                                                 * result is inaccurate */
+       char            errormsg_malloced;      /* Current error message is malloed (not in a static variable) ? */
+       char            miscinfo;
 };
 
 #define SC_get_conn(a)   (a->hdbc)
@@ -229,6 +229,14 @@ struct StatementClass_
 #define STMT_FREE_PARAMS_ALL                           0
 #define STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY     1
 
+/*     misc info */
+#define SC_set_pre_executable(a) (a->miscinfo |= 1L)
+#define SC_no_pre_executable(a)        (a->miscinfo &= ~1L)
+#define SC_is_pre_executable(a)        (a->miscinfo & 1L != 0)
+#define SC_set_fetchcursor(a)  (a->miscinfo |= 2L)
+#define SC_no_fetchcursor(a)   (a->miscinfo &= ~2L)
+#define SC_is_fetchcursor(a)   (a->miscinfo & 2L != 0)
+
 /*     Statement prototypes */
 StatementClass *SC_Constructor(void);
 void           InitializeStatementOptions(StatementOptions *opt);