1) Most driver options could be set per DSN.
authorHiroshi Inoue
Fri, 7 Sep 2001 06:02:24 +0000 (06:02 +0000)
committerHiroshi Inoue
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 
@@ -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);