2) Keep FE/BE protocol more precisely.
3) Improve procedure calls.
4) A trial to avoid PREMATURE execution(#ifdef'd now).
Hiroshi Inoue
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);
/* 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);
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 */
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;
{
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)
*/
if (!self->sock)
{
- self->sock = SOCK_Constructor();
+ self->sock = SOCK_Constructor(self);
if (!self->sock)
{
self->errornumber = CONNECTION_SERVER_NOT_REACHED;
*/
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;
}
else
{
- mylog("auth got 'R'\n");
areq = SOCK_get_int(sock, 4);
if (areq == AUTH_REQ_MD5)
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 */
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];
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);
{
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);
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
{
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
*/
- 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)
{
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);
/*
}
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);
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':
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);
{
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)
{
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;
}
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))
}
/* 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))
}
/* 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)
{
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? */
#endif
#endif
-extern GLOBAL_VALUES globals;
/*
* How to map ODBC scalar functions {fn func(args)} to Postgres.
{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
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;
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;
{
int nval,
i;
- char *vp;
+ const char *vp;
/* this is an array of eight integers */
short *short_array = (short *) ((char *) rgbValue + rgbValueOffset);
len = 1;
if (cbValueMax > len)
{
- strcpy(rgbValueBindRow, value);
+ strcpy(rgbValueBindRow, neutstr);
mylog("PG_TYPE_BOOL: rgbValueBindRow = '%s'\n", rgbValueBindRow);
}
break;
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;
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)
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)
{
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
/* 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++;
}
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';
}
/* 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
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;
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";
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;
}
/* 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;
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";
return SQL_ERROR;
}
- CC_set_no_trans(stmt->hdbc);
+ CC_set_no_trans(conn);
}
}
/* 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,
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;
* 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,
/* !!! 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);
unsigned int
-conv_from_octal(unsigned char *s)
+conv_from_octal(const unsigned char *s)
{
int i,
y = 0;
unsigned int
-conv_from_hex(unsigned char *s)
+conv_from_hex(const unsigned char *s)
{
int i,
y = 0,
/* 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;
/* 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;
void
-encode(char *in, char *out)
+encode(const char *in, char *out)
{
unsigned int i, ilen = strlen(in),
o = 0;
void
-decode(char *in, char *out)
+decode(const char *in, char *out)
{
unsigned int i, ilen = strlen(in),
o = 0;
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)
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";
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;
}
/* 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);
}
}
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";
return COPY_GENERAL_ERROR;
}
- CC_set_no_trans(stmt->hdbc);
+ CC_set_no_trans(conn);
}
stmt->lobj_fd = -1;
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";
return COPY_GENERAL_ERROR;
}
- CC_set_no_trans(stmt->hdbc);
+ CC_set_no_trans(conn);
}
stmt->lobj_fd = -1; /* prevent further reading */
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);
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
#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)
{
/*
}
-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;
}
}
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",
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);
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); */
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)
* 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')
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,
/* 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);
* 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 */
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)
{
/*
* 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
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); */
}
#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,
#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
#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);
#endif
-extern GLOBAL_VALUES globals;
-
RETCODE SQL_API
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);
*/
result = SQL_SUCCESS;
- makeConnectString(connStrOut, ci);
+ makeConnectString(connStrOut, ci, cbConnStrOutMax);
len = strlen(connStrOut);
if (szConnStrOut)
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);
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:
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,
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);
+}
* 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)
#include "lobj.h"
#include "pgapifunc.h"
-extern GLOBAL_VALUES globals;
+/*extern GLOBAL_VALUES globals;*/
/* Perform a Prepare on the SQL statement */
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);
}
#ifdef WIN32
HMODULE hmodule;
FARPROC addr;
+ ConnInfo *ci;
#endif
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
*/
#ifdef WIN32
- if (globals.cancel_as_freestmt)
+ if (ci->drivers.cancel_as_freestmt)
{
hmodule = GetModuleHandle("ODBC32");
addr = GetProcAddress(hmodule, "SQLFreeStmt");
StatementClass *stmt = (StatementClass *) hstmt;
int i,
retval;
+ ConnInfo *ci;
mylog("%s: entering...\n", func);
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);
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;
#define TRIGGER_UPDATE 0x02
-extern GLOBAL_VALUES globals;
+/* extern GLOBAL_VALUES globals; */
return SQL_INVALID_HANDLE;
}
- ci = &conn->connInfo;
+ ci = &(conn->connInfo);
switch (fInfoType)
{
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 */
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;
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;
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 |
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 */
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;
* 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);
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 */
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 */
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)
{
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;
}
else
{
- if (globals.lie)
+ if (ci->drivers.lie)
*pfExists = TRUE;
else
{
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))
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)
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
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);
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
- ci = &stmt->hdbc->connInfo;
+ ci = &(SC_get_conn(stmt)->connInfo);
stmt->manual_result = TRUE;
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)
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], "");
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);
return SQL_ERROR;
}
- conn = (ConnectionClass *) (stmt->hdbc);
+ conn = SC_get_conn(stmt);
if (PG_VERSION_LE(conn, 6.4))
qstart = 2;
else
#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;
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
{
va_list args;
char filebuf[80];
- FILE *LOGFP = globals.mylogFP;
+ static FILE *LOGFP = NULL;
- if (globals.debug)
+ if (mylog_on)
{
va_start(args, fmt);
{
generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
LOGFP = fopen(filebuf, PG_BINARY_W);
- globals.mylogFP = LOGFP;
setbuf(LOGFP, NULL);
}
{
va_list args;
char filebuf[80];
- FILE *LOGFP = globals.qlogFP;
+ static FILE *LOGFP = NULL;
- if (globals.commlog)
+ if (qlog_on)
{
va_start(args, fmt);
{
generate_filename(QLOGDIR, QLOGFILE, filebuf);
LOGFP = fopen(filebuf, PG_BINARY_W);
- globals.qlogFP = LOGFP;
setbuf(LOGFP, NULL);
}
* (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;
*------
*/
char *
-make_string(char *s, int len, char *buf)
+make_string(const char *s, int len, char *buf)
{
int length;
char *str;
* 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)))
{
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
#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
multibyte_client_encoding = BIG5;
return ("BIG5");
}
- return ("OHTER");
+ return ("OTHER");
}
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);
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,
/* *((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:
#include "pgapifunc.h"
-extern GLOBAL_VALUES globals;
RETCODE set_statement_option(ConnectionClass *conn,
StatementClass *stmt,
{
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 */
* 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;
*/
mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam);
- if (globals.lie)
+ if (ci->drivers.lie)
{
if (conn)
conn->stmtOptions.cursor_type = vParam;
}
else
{
- if (globals.use_declarefetch)
+ if (ci->drivers.use_declarefetch)
{
if (conn)
conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY;
break;
/*-------
- * if (globals.lie)
+ * if (ci->drivers.lie)
* stmt->keyset_size = vParam;
* else
* {
{
static char *func = "PGAPI_GetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc;
+ ConnInfo *ci = &(conn->connInfo);
mylog("%s: entering...\n", func);
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 */
static char *func = "PGAPI_GetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *res;
+ ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
mylog("%s: entering...\n", func);
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) ||
#endif
-extern GLOBAL_VALUES globals;
Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4
-sqltype_to_pgtype(SWORD fSqlType)
+sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
{
Int4 pgType;
+ ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
switch (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:
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:
Int2
pgtype_to_sqltype(StatementClass *stmt, Int4 type)
{
+ ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
switch (type)
{
case PG_TYPE_CHAR:
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;
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:
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;
}
}
Int2
pgtype_to_ctype(StatementClass *stmt, Int4 type)
{
+ ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
switch (type)
{
case PG_TYPE_INT8:
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;
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);
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;
}
/* 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);
return FALSE;
}
- getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+ getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
break;
case DLL_THREAD_ATTACH:
__attribute__((constructor))
init(void)
{
- getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+ getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
return TRUE;
}
BOOL
_init(void)
{
- getGlobalDefaults(DBMS_NAME, ODBCINST_INI, FALSE);
+ getCommonDefaults(DBMS_NAME, ODBCINST_INI, NULL);
return TRUE;
}
*
* 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 $
*
*/
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_
char *cursor;
} QueryInfo;
+void logs_on_off(int cnopen, int, int);
#define PG_TYPE_LO (-999) /* hack until permanent
* type available */
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"
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
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"
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
* CLASS QResult
*/
QResultClass *
-QR_Constructor(void)
+QR_Constructor()
{
QResultClass *rv;
*/
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);
if (self->cursor)
free(self->cursor);
- if (globals.use_declarefetch)
+ if (ci->drivers.use_declarefetch)
{
if (!cursor || cursor[0] == '\0')
{
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)
{
{
QResultClass *res;
- if (globals.use_declarefetch && self->conn && self->cursor)
+ if (self->conn && self->cursor && self->conn->connInfo.drivers.use_declarefetch)
{
char buf[64];
char cmdbuffer[ERROR_MSG_LENGTH + 1];
char fetch[128];
QueryInfo qi;
+ ConnInfo *ci = NULL;
if (fetch_count < fcount)
{
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;
{
/* 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;
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);
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;
sock = CC_get_socket(self->conn);
self->tupleField = NULL;
+ ci = &(self->conn->connInfo);
for (;;)
{
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;
-/* {{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
#endif
#include "pgapifunc.h"
-extern GLOBAL_VALUES globals;
RETCODE SQL_API
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)
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;
}
}
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)
{
return SQL_INVALID_HANDLE;
}
- ci = &(stmt->hdbc->connInfo);
+ ci = &(SC_get_conn(stmt)->connInfo);
SC_clear_error(stmt);
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)
{
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);
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
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)
{
void *value = NULL;
int result;
char get_bookmark = FALSE;
+ ConnInfo *ci;
mylog("PGAPI_GetData: enter, stmt=%u\n", stmt);
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
+ ci = &(SC_get_conn(stmt)->connInfo);
res = stmt->result;
if (STMT_EXECUTING == stmt->status)
}
}
- 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);
RETCODE result;
char truncated,
error;
+ ConnInfo *ci;
mylog("PGAPI_ExtendedFetch: stmt=%u\n", stmt);
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)
{
* 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;
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 */
#define INTFUNC __stdcall
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
-extern GLOBAL_VALUES globals;
/* Constants */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
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:
/* 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:
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;
}
*/
#include "socket.h"
+#include "connection.h"
#ifndef WIN32
#include <stdlib.h>
SocketClass *
-SOCK_Constructor()
+SOCK_Constructor(const ConnectionClass *conn)
{
SocketClass *rv;
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);
void
SOCK_Destructor(SocketClass *self)
{
+mylog("SOCK_Destructor\n");
if (self->socket != -1)
{
SOCK_put_char(self, 'X');
* 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)
{
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.";
struct SocketClass_
{
+ int buffer_size;
int buffer_filled_in;
int buffer_filled_out;
int buffer_read_in;
/* 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);
#endif
#include "pgapifunc.h"
-extern GLOBAL_VALUES globals;
#ifndef WIN32
#ifndef HAVE_STRICMP
rv->pre_executing = FALSE;
rv->inaccurate_result = FALSE;
+ rv->miscinfo = 0;
}
return rv;
}
{
mylog(" preprocess: status = READY\n");
+ self->miscinfo = 0;
if (self->statement_type == STMT_TYPE_SELECT)
{
char old_pre_executing = self->pre_executing;
self->status = STMT_PREMATURE;
}
}
- else
+ if (!SC_is_pre_executable(self))
{
self->result = QR_Constructor();
QR_set_status(self->result, PGRES_TUPLES_OK);
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))
/* 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);
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);
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 */
* 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);
/* 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);
*/
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
(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;
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)
#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);