mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
1) Implement SQLParamOptions().
2) Handle Multiple results and implement SQLMoreResult(). 3) Improve multibyte handling thanks to Eiji Tokuya. 4) Add new options. LF <-> CR/LF converion. TRUE is -1 (for VB). 5) Introduce unicode(UCS-2) support. 6) Reduce the length of connection strings. 7) Improve SQLError, SQLGetDiagRec(ODBC 3.0). 8) Implement SQLTablePrivileges(). 9) Miscellaneous changes for ODBC 3.0 support.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
* Classes: BindInfoClass, ParameterInfoClass
|
||||
*
|
||||
* API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams,
|
||||
* SQLParamOptions(NI)
|
||||
* SQLParamOptions
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*-------
|
||||
@ -331,17 +331,9 @@ PGAPI_ParamOptions(
|
||||
|
||||
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);
|
||||
return SQL_ERROR;
|
||||
stmt->options.paramset_size = crow;
|
||||
stmt->options.param_processed_ptr = pirow;
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +75,8 @@ PGAPI_AllocConnect(
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
*phdbc = (HDBC) conn;
|
||||
if (phdbc)
|
||||
*phdbc = (HDBC) conn;
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
@ -228,6 +229,16 @@ PGAPI_FreeConnect(
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CC_conninfo_init(ConnInfo *conninfo)
|
||||
{
|
||||
memset(conninfo, 0, sizeof(ConnInfo));
|
||||
conninfo->disallow_premature = -1;
|
||||
conninfo->updatable_cursors = -1;
|
||||
conninfo->lf_conversion = -1;
|
||||
conninfo->true_is_minus1 = -1;
|
||||
memcpy(&(conninfo->drivers), &globals, sizeof(globals));
|
||||
}
|
||||
/*
|
||||
* IMPLEMENTATION CONNECTION CLASS
|
||||
*/
|
||||
@ -249,11 +260,7 @@ CC_Constructor()
|
||||
rv->status = CONN_NOT_CONNECTED;
|
||||
rv->transact_status = CONN_IN_AUTOCOMMIT; /* autocommit by default */
|
||||
|
||||
memset(&rv->connInfo, 0, sizeof(ConnInfo));
|
||||
#ifdef DRIVER_CURSOR_IMPLEMENT
|
||||
rv->connInfo.updatable_cursors = 1;
|
||||
#endif /* DRIVER_CURSOR_IMPLEMENT */
|
||||
memcpy(&(rv->connInfo.drivers), &globals, sizeof(globals));
|
||||
CC_conninfo_init(&(rv->connInfo));
|
||||
rv->sock = SOCK_Constructor(rv);
|
||||
if (!rv->sock)
|
||||
return NULL;
|
||||
@ -280,6 +287,7 @@ CC_Constructor()
|
||||
rv->pg_version_major = 0;
|
||||
rv->pg_version_minor = 0;
|
||||
rv->ms_jet = 0;
|
||||
rv->unicode = 0;
|
||||
#ifdef MULTIBYTE
|
||||
rv->client_encoding = NULL;
|
||||
rv->server_encoding = NULL;
|
||||
@ -338,7 +346,7 @@ CC_cursor_count(ConnectionClass *self)
|
||||
for (i = 0; i < self->num_stmts; i++)
|
||||
{
|
||||
stmt = self->stmts[i];
|
||||
if (stmt && stmt->result && stmt->result->cursor)
|
||||
if (stmt && SC_get_Result(stmt) && SC_get_Result(stmt)->cursor)
|
||||
count++;
|
||||
}
|
||||
|
||||
@ -366,18 +374,18 @@ CC_begin(ConnectionClass *self)
|
||||
char ret = TRUE;
|
||||
if (!CC_is_in_trans(self))
|
||||
{
|
||||
QResultClass *res = CC_send_query(self, "BEGIN", NULL);
|
||||
QResultClass *res = CC_send_query(self, "BEGIN", NULL, TRUE);
|
||||
mylog("CC_begin: sending BEGIN!\n");
|
||||
|
||||
if (res != NULL)
|
||||
{
|
||||
ret = (!QR_aborted(res) && QR_command_successful(res));
|
||||
ret = QR_command_successful(res);
|
||||
QR_Destructor(res);
|
||||
if (ret)
|
||||
CC_set_in_trans(self);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -393,7 +401,7 @@ CC_commit(ConnectionClass *self)
|
||||
char ret = FALSE;
|
||||
if (CC_is_in_trans(self))
|
||||
{
|
||||
QResultClass *res = CC_send_query(self, "COMMIT", NULL);
|
||||
QResultClass *res = CC_send_query(self, "COMMIT", NULL, TRUE);
|
||||
mylog("CC_commit: sending COMMIT!\n");
|
||||
|
||||
CC_set_no_trans(self);
|
||||
@ -404,7 +412,7 @@ CC_commit(ConnectionClass *self)
|
||||
QR_Destructor(res);
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -419,7 +427,7 @@ CC_abort(ConnectionClass *self)
|
||||
{
|
||||
if (CC_is_in_trans(self))
|
||||
{
|
||||
QResultClass *res = CC_send_query(self, "ROLLBACK", NULL);
|
||||
QResultClass *res = CC_send_query(self, "ROLLBACK", NULL, TRUE);
|
||||
mylog("CC_abort: sending ABORT!\n");
|
||||
|
||||
CC_set_no_trans(self);
|
||||
@ -488,11 +496,7 @@ CC_cleanup(ConnectionClass *self)
|
||||
|
||||
self->status = CONN_NOT_CONNECTED;
|
||||
self->transact_status = CONN_IN_AUTOCOMMIT;
|
||||
memset(&self->connInfo, 0, sizeof(ConnInfo));
|
||||
#ifdef DRIVER_CURSOR_IMPLEMENT
|
||||
self->connInfo.updatable_cursors = 1;
|
||||
#endif /* DRIVER_CURSOR_IMPLEMENT */
|
||||
memcpy(&(self->connInfo.drivers), &globals, sizeof(globals));
|
||||
CC_conninfo_init(&(self->connInfo));
|
||||
#ifdef MULTIBYTE
|
||||
if (self->client_encoding)
|
||||
free(self->client_encoding);
|
||||
@ -578,12 +582,12 @@ md5_auth_send(ConnectionClass *self, const char *salt)
|
||||
{
|
||||
free(pwd1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!(pwd2 = malloc(MD5_PASSWD_LEN + 1)))
|
||||
{
|
||||
free(pwd1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!EncryptMD5(pwd1 + strlen("md5"), salt, 4, pwd2))
|
||||
{
|
||||
free(pwd2);
|
||||
@ -595,7 +599,7 @@ md5_auth_send(ConnectionClass *self, const char *salt)
|
||||
SOCK_put_n_char(sock, pwd2, strlen(pwd2) + 1);
|
||||
SOCK_flush_output(sock);
|
||||
free(pwd2);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char
|
||||
@ -608,7 +612,7 @@ CC_connect(ConnectionClass *self, char do_password)
|
||||
ConnInfo *ci = &(self->connInfo);
|
||||
int areq = -1;
|
||||
int beresp;
|
||||
char msgbuffer[ERROR_MSG_LENGTH];
|
||||
static char msgbuffer[ERROR_MSG_LENGTH];
|
||||
char salt[5];
|
||||
static char *func = "CC_connect";
|
||||
|
||||
@ -651,15 +655,16 @@ CC_connect(ConnectionClass *self, char do_password)
|
||||
if (encoding && strcmp(encoding, "OTHER"))
|
||||
self->client_encoding = strdup(encoding);
|
||||
}
|
||||
if (self->client_encoding)
|
||||
self->ccsc = pg_CS_code(self->client_encoding);
|
||||
qlog(" extra_systable_prefixes='%s', conn_settings='%s' conn_encoding='%s'\n",
|
||||
ci->drivers.extra_systable_prefixes,
|
||||
ci->drivers.conn_settings,
|
||||
encoding ? encoding : "");
|
||||
#else
|
||||
qlog(" extra_systable_prefixes='%s', conn_settings='%s', protocol='%s'\n",
|
||||
qlog(" extra_systable_prefixes='%s', conn_settings='%s'\n",
|
||||
ci->drivers.extra_systable_prefixes,
|
||||
ci->drivers.conn_settings,
|
||||
ci->protocol);
|
||||
ci->drivers.conn_settings);
|
||||
#endif
|
||||
|
||||
if (self->status != CONN_NOT_CONNECTED)
|
||||
@ -914,7 +919,7 @@ another_version_retry:
|
||||
*/
|
||||
mylog("sending an empty query...\n");
|
||||
|
||||
res = CC_send_query(self, " ", NULL);
|
||||
res = CC_send_query(self, " ", NULL, TRUE);
|
||||
if (res == NULL || QR_get_status(res) != PGRES_EMPTY_QUERY)
|
||||
{
|
||||
mylog("got no result from the empty query. (probably database does not exist)\n");
|
||||
@ -942,13 +947,55 @@ another_version_retry:
|
||||
* function instead.
|
||||
*/
|
||||
CC_send_settings(self);
|
||||
CC_lookup_lo(self); /* a hack to get the oid of our large
|
||||
* object oid type */
|
||||
#ifdef MULTIBYTE
|
||||
CC_lookup_characterset(self);
|
||||
#endif
|
||||
CC_lookup_pg_version(self); /* Get PostgreSQL version for SQLGetInfo
|
||||
* use */
|
||||
CC_lookup_lo(self); /* a hack to get the oid of
|
||||
our large object oid type */
|
||||
CC_lookup_pg_version(self); /* Get PostgreSQL version for
|
||||
SQLGetInfo use */
|
||||
|
||||
/*
|
||||
* Multibyte handling is available ?
|
||||
*/
|
||||
#ifdef MULTIBYTE
|
||||
if (PG_VERSION_GE(self, 7.0))
|
||||
{
|
||||
CC_lookup_characterset(self);
|
||||
if (self->errornumber != 0)
|
||||
return 0;
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (self->unicode)
|
||||
{
|
||||
if (!self->client_encoding ||
|
||||
stricmp(self->client_encoding, "UNICODE"))
|
||||
{
|
||||
QResultClass *res;
|
||||
if (PG_VERSION_LT(self, 7.1))
|
||||
{
|
||||
self->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
|
||||
self->errormsg = "UTF-8 conversion isn't implemented before 7.1";
|
||||
return 0;
|
||||
}
|
||||
if (self->client_encoding)
|
||||
free(self->client_encoding);
|
||||
self->client_encoding = NULL;
|
||||
if (res = CC_send_query(self, "set client_encoding to 'UTF8'", NULL, TRUE), res)
|
||||
{
|
||||
self->client_encoding = strdup("UNICODE");
|
||||
QR_Destructor(res);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
}
|
||||
#ifdef UNICODE_SUPPORT
|
||||
else if (self->unicode)
|
||||
{
|
||||
self->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
|
||||
self->errormsg = "Unicode isn't supported before 7.0";
|
||||
return 0;
|
||||
}
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
#endif /* MULTIBYTE */
|
||||
|
||||
CC_clear_error(self); /* clear any initial command errors */
|
||||
self->status = CONN_CONNECTED;
|
||||
@ -1081,11 +1128,12 @@ CC_get_error(ConnectionClass *self, int *number, char **message)
|
||||
* 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
|
||||
*/
|
||||
QResultClass *
|
||||
CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL clear_result_on_abort)
|
||||
{
|
||||
QResultClass *result_in = NULL,
|
||||
*res = NULL,
|
||||
*retres = NULL;
|
||||
*cmdres = NULL,
|
||||
*retres = NULL,
|
||||
*res = NULL;
|
||||
char swallow,
|
||||
*wq;
|
||||
int id;
|
||||
@ -1094,9 +1142,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
empty_reqs;
|
||||
BOOL msg_truncated,
|
||||
ReadyToReturn,
|
||||
tuples_return = FALSE,
|
||||
query_completed = FALSE,
|
||||
before_64 = PG_VERSION_LT(self, 6.4),
|
||||
aborted = FALSE,
|
||||
used_passed_result_object = FALSE;
|
||||
|
||||
/* ERROR_MSG_LENGTH is suffcient */
|
||||
@ -1156,6 +1204,20 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
;
|
||||
if (*wq == '\0')
|
||||
empty_reqs = 1;
|
||||
cmdres = qi ? qi->result_in : NULL;
|
||||
if (cmdres)
|
||||
used_passed_result_object = TRUE;
|
||||
else
|
||||
{
|
||||
cmdres = QR_Constructor();
|
||||
if (!cmdres)
|
||||
{
|
||||
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
|
||||
self->errormsg = "Could not create result info in send_query.";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
res = cmdres;
|
||||
while (!ReadyToReturn)
|
||||
{
|
||||
/* what type of message is coming now ? */
|
||||
@ -1199,12 +1261,14 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
{
|
||||
mylog("send_query: ok - 'C' - %s\n", cmdbuffer);
|
||||
|
||||
if (res == NULL) /* allow for "show" style info */
|
||||
res = QR_Constructor();
|
||||
if (query_completed) /* allow for "show" style notices */
|
||||
{
|
||||
res->next = QR_Constructor();
|
||||
res = res->next;
|
||||
}
|
||||
|
||||
mylog("send_query: setting cmdbuffer = '%s'\n", cmdbuffer);
|
||||
|
||||
/* Only save the first command */
|
||||
if (QR_command_successful(res))
|
||||
QR_set_status(res, PGRES_COMMAND_OK);
|
||||
QR_set_command(res, cmdbuffer);
|
||||
@ -1233,44 +1297,19 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
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;
|
||||
if (aborted || query_completed)
|
||||
retres = cmdres;
|
||||
else
|
||||
ReadyToReturn = FALSE;
|
||||
}
|
||||
break;
|
||||
case 'N': /* INFO, NOTICE, WARNING */
|
||||
case 'N': /* NOTICE: */
|
||||
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
|
||||
if (!res)
|
||||
res = QR_Constructor();
|
||||
if (QR_command_successful(res))
|
||||
QR_set_status(res, PGRES_NONFATAL_ERROR);
|
||||
QR_set_notice(res, cmdbuffer); /* will dup this string */
|
||||
#ifdef MULTIBYTE
|
||||
if (strstr(cmdbuffer,"encoding is"))
|
||||
{
|
||||
if (strstr(cmdbuffer,"Current client encoding is"))
|
||||
strcpy(PG_CCSS, cmdbuffer + 36);
|
||||
if (strstr(cmdbuffer,"Current server encoding is"))
|
||||
strcpy(PG_SCSS, cmdbuffer + 36);
|
||||
mylog("~~~ WARNING: '%s'\n", cmdbuffer);
|
||||
qlog("WARNING from backend during send_query: '%s'\n ClientEncoding = %s\n ServerEncoding = %s\n", cmdbuffer, PG_CCSS, PG_SCSS);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
mylog("~~~ WARNING: '%s'\n", cmdbuffer);
|
||||
qlog("WARNING from backend during send_query: '%s'\n", cmdbuffer);
|
||||
}
|
||||
#else
|
||||
mylog("~~~ WARNING: '%s'\n", cmdbuffer);
|
||||
qlog("WARNING from backend during send_query: '%s'\n", cmdbuffer);
|
||||
#endif
|
||||
mylog("~~~ NOTICE: '%s'\n", cmdbuffer);
|
||||
qlog("NOTICE from backend during send_query: '%s'\n", cmdbuffer);
|
||||
while (msg_truncated)
|
||||
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
|
||||
|
||||
@ -1280,15 +1319,13 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
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)";
|
||||
QR_set_status(res, PGRES_FATAL_ERROR);
|
||||
ReadyToReturn = TRUE;
|
||||
retres = res;
|
||||
retres = cmdres;
|
||||
break;
|
||||
}
|
||||
else
|
||||
@ -1315,8 +1352,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
qlog("ERROR from backend during send_query: '%s'\n", self->errormsg);
|
||||
|
||||
/* We should report that an error occured. Zoltan */
|
||||
if (!res)
|
||||
res = QR_Constructor();
|
||||
|
||||
if (!strncmp(self->errormsg, "FATAL", 5))
|
||||
{
|
||||
@ -1327,6 +1362,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
|
||||
QR_set_status(res, PGRES_FATAL_ERROR);
|
||||
QR_set_aborted(res, TRUE);
|
||||
aborted = TRUE;
|
||||
while (msg_truncated)
|
||||
msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
|
||||
|
||||
@ -1337,13 +1373,11 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
|
||||
break;
|
||||
case 'T': /* Tuple results start here */
|
||||
result_in = qi ? qi->result_in : NULL;
|
||||
|
||||
if (result_in == NULL)
|
||||
if (query_completed)
|
||||
{
|
||||
result_in = QR_Constructor();
|
||||
mylog("send_query: 'T' no result_in: res = %u\n", result_in);
|
||||
if (!result_in)
|
||||
res->next = QR_Constructor();
|
||||
mylog("send_query: 'T' no result_in: res = %u\n", res->next);
|
||||
if (!res->next)
|
||||
{
|
||||
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
|
||||
self->errormsg = "Could not create result info in send_query.";
|
||||
@ -1351,55 +1385,60 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
retres = NULL;
|
||||
break;
|
||||
}
|
||||
res = res->next;
|
||||
|
||||
if (qi)
|
||||
QR_set_cache_size(result_in, qi->row_size);
|
||||
|
||||
if (!QR_fetch_tuples(result_in, self, qi ? qi->cursor : NULL))
|
||||
QR_set_cache_size(res, qi->row_size);
|
||||
}
|
||||
if (!used_passed_result_object)
|
||||
{
|
||||
if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL))
|
||||
{
|
||||
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
|
||||
self->errormsg = QR_get_message(result_in);
|
||||
self->errormsg = QR_get_message(res);
|
||||
ReadyToReturn = TRUE;
|
||||
retres = NULL;
|
||||
break;
|
||||
}
|
||||
query_completed = TRUE;
|
||||
}
|
||||
else
|
||||
{ /* next fetch, so reuse an existing result */
|
||||
|
||||
used_passed_result_object = TRUE;
|
||||
/*
|
||||
* called from QR_next_tuple and must return
|
||||
* immediately.
|
||||
*/
|
||||
ReadyToReturn = TRUE;
|
||||
if (!QR_fetch_tuples(result_in, NULL, NULL))
|
||||
if (!QR_fetch_tuples(res, NULL, NULL))
|
||||
{
|
||||
self->errornumber = CONNECTION_COULD_NOT_RECEIVE;
|
||||
self->errormsg = QR_get_message(result_in);
|
||||
self->errormsg = QR_get_message(res);
|
||||
retres = NULL;
|
||||
break;
|
||||
}
|
||||
retres = result_in;
|
||||
retres = cmdres;
|
||||
}
|
||||
|
||||
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);
|
||||
if (query_completed)
|
||||
{
|
||||
res->next = QR_Constructor();
|
||||
res = res->next;
|
||||
}
|
||||
QR_set_status(res, PGRES_COPY_IN);
|
||||
ReadyToReturn = TRUE;
|
||||
retres = res;
|
||||
retres = cmdres;
|
||||
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);
|
||||
if (query_completed)
|
||||
{
|
||||
res->next = QR_Constructor();
|
||||
res = res->next;
|
||||
}
|
||||
QR_set_status(res, PGRES_COPY_OUT);
|
||||
ReadyToReturn = TRUE;
|
||||
retres = res;
|
||||
retres = cmdres;
|
||||
break;
|
||||
default:
|
||||
self->errornumber = CONNECTION_BACKEND_CRAZY;
|
||||
@ -1417,7 +1456,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
*/
|
||||
if (before_64)
|
||||
{
|
||||
if (empty_reqs == 0 && (query_completed || tuples_return))
|
||||
if (empty_reqs == 0 && query_completed)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1426,34 +1465,44 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
|
||||
* Break before being ready to return.
|
||||
*/
|
||||
if (!ReadyToReturn)
|
||||
{
|
||||
if (res && QR_get_aborted(res))
|
||||
retres = res;
|
||||
else if (tuples_return)
|
||||
retres = result_in;
|
||||
else
|
||||
retres = res;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
retres = cmdres;
|
||||
|
||||
/*
|
||||
* Cleanup garbage results before returning.
|
||||
*/
|
||||
if (res && retres != res)
|
||||
QR_Destructor(res);
|
||||
if (result_in && retres != result_in)
|
||||
if (cmdres && retres != cmdres && !used_passed_result_object)
|
||||
QR_Destructor(cmdres);
|
||||
/*
|
||||
* Cleanup the aborted result if specified
|
||||
*/
|
||||
if (retres)
|
||||
{
|
||||
if (!used_passed_result_object)
|
||||
QR_Destructor(result_in);
|
||||
if (aborted)
|
||||
{
|
||||
if (clear_result_on_abort)
|
||||
{
|
||||
if (!used_passed_result_object)
|
||||
{
|
||||
QR_Destructor(retres);
|
||||
retres = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* discard results other than errors.
|
||||
*/
|
||||
QResultClass *qres;
|
||||
for (qres = retres; qres->next; qres = retres)
|
||||
{
|
||||
if (QR_get_aborted(qres))
|
||||
break;
|
||||
retres = qres->next;
|
||||
qres->next = NULL;
|
||||
QR_Destructor(qres);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retres;
|
||||
}
|
||||
@ -1591,7 +1640,7 @@ CC_send_function(ConnectionClass *self, int fnid, void *result_buf, int *actual_
|
||||
SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
|
||||
|
||||
mylog("send_function(G): 'N' - %s\n", msgbuffer);
|
||||
qlog("WARNING from backend during send_function: '%s'\n", msgbuffer);
|
||||
qlog("NOTICE from backend during send_function: '%s'\n", msgbuffer);
|
||||
|
||||
continue; /* dont return a result -- continue
|
||||
* reading */
|
||||
@ -1869,7 +1918,7 @@ CC_lookup_pg_version(ConnectionClass *self)
|
||||
|
||||
|
||||
void
|
||||
CC_log_error(char *func, char *desc, ConnectionClass *self)
|
||||
CC_log_error(const char *func, const char *desc, const ConnectionClass *self)
|
||||
{
|
||||
#ifdef PRN_NULLCHECK
|
||||
#define nullcheck(a) (a ? a : "(NULL)")
|
||||
@ -1894,7 +1943,10 @@ CC_log_error(char *func, char *desc, ConnectionClass *self)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
mylog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
}
|
||||
#undef PRN_NULLCHECK
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,8 @@ typedef struct
|
||||
char focus_password;
|
||||
char disallow_premature;
|
||||
char updatable_cursors;
|
||||
char lf_conversion;
|
||||
char true_is_minus1;
|
||||
GLOBAL_VALUES drivers; /* moved from driver's option */
|
||||
} ConnInfo;
|
||||
|
||||
@ -271,6 +273,7 @@ struct ConnectionClass_
|
||||
char *client_encoding;
|
||||
char *server_encoding;
|
||||
#endif /* MULTIBYTE */
|
||||
int ccsc;
|
||||
};
|
||||
|
||||
|
||||
@ -290,6 +293,7 @@ struct ConnectionClass_
|
||||
|
||||
/* prototypes */
|
||||
ConnectionClass *CC_Constructor(void);
|
||||
void CC_conninfo_init(ConnInfo *conninfo);
|
||||
char CC_Destructor(ConnectionClass *self);
|
||||
int CC_cursor_count(ConnectionClass *self);
|
||||
char CC_cleanup(ConnectionClass *self);
|
||||
@ -301,7 +305,7 @@ char CC_connect(ConnectionClass *self, char do_password);
|
||||
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
|
||||
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
|
||||
char CC_get_error(ConnectionClass *self, int *number, char **message);
|
||||
QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi);
|
||||
QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, BOOL);
|
||||
void CC_clear_error(ConnectionClass *self);
|
||||
char *CC_create_errormsg(ConnectionClass *self);
|
||||
int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
|
||||
@ -309,7 +313,7 @@ char CC_send_settings(ConnectionClass *self);
|
||||
void CC_lookup_lo(ConnectionClass *conn);
|
||||
void CC_lookup_pg_version(ConnectionClass *conn);
|
||||
void CC_initialize_pg_version(ConnectionClass *conn);
|
||||
void CC_log_error(char *func, char *desc, ConnectionClass *self);
|
||||
void CC_log_error(const char *func, const char *desc, const ConnectionClass *self);
|
||||
int CC_get_max_query_len(const ConnectionClass *self);
|
||||
|
||||
#endif
|
||||
|
@ -335,12 +335,15 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
int bind_row = stmt->bind_row;
|
||||
int bind_size = stmt->options.bind_size;
|
||||
int result = COPY_OK;
|
||||
BOOL changed;
|
||||
BOOL changed, true_is_minus1 = FALSE;
|
||||
const char *neut_str = value;
|
||||
char midtemp[2][32];
|
||||
int mtemp_cnt = 0;
|
||||
static BindInfoClass sbic;
|
||||
BindInfoClass *pbic;
|
||||
#ifdef UNICODE_SUPPORT
|
||||
BOOL wchanged = FALSE;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
if (stmt->current_col >= 0)
|
||||
{
|
||||
@ -474,15 +477,23 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
char *s;
|
||||
|
||||
s = midtemp[mtemp_cnt];
|
||||
strcpy(s, (char *) value);
|
||||
if (s[0] == 'f' || s[0] == 'F' || s[0] == 'n' || s[0] == 'N' || s[0] == '0')
|
||||
s[0] = '0';
|
||||
else
|
||||
s[0] = '1';
|
||||
s[1] = '\0';
|
||||
switch (((char *)value)[0])
|
||||
{
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'n':
|
||||
case 'N':
|
||||
case '0':
|
||||
strcpy(s, "0");
|
||||
break;
|
||||
default:
|
||||
if (true_is_minus1)
|
||||
strcpy(s, "-1");
|
||||
else
|
||||
strcpy(s, "1");
|
||||
}
|
||||
neut_str = midtemp[mtemp_cnt];
|
||||
mtemp_cnt++;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@ -567,7 +578,11 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
|
||||
rgbValueBindRow = (char *) rgbValue + rgbValueOffset;
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (fCType == SQL_C_CHAR || fCType == SQL_C_WCHAR)
|
||||
#else
|
||||
if (fCType == SQL_C_CHAR)
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
{
|
||||
/* Special character formatting as required */
|
||||
|
||||
@ -599,7 +614,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
break;
|
||||
|
||||
case PG_TYPE_BOOL:
|
||||
len = 1;
|
||||
len = strlen(neut_str);
|
||||
if (cbValueMax > len)
|
||||
{
|
||||
strcpy(rgbValueBindRow, neut_str);
|
||||
@ -637,8 +652,18 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
pbic = &stmt->bindings[stmt->current_col];
|
||||
if (pbic->data_left < 0)
|
||||
{
|
||||
BOOL lf_conv = SC_get_conn(stmt)->connInfo.lf_conversion;
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (fCType == SQL_C_WCHAR)
|
||||
{
|
||||
len = utf8_to_ucs2(neut_str, -1, NULL, 0);
|
||||
len *= 2;
|
||||
wchanged = changed = TRUE;
|
||||
}
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
/* convert linefeeds to carriage-return/linefeed */
|
||||
len = convert_linefeeds(neut_str, NULL, 0, &changed);
|
||||
len = convert_linefeeds(neut_str, NULL, 0, lf_conv, &changed);
|
||||
if (cbValueMax == 0) /* just returns length
|
||||
* info */
|
||||
{
|
||||
@ -654,7 +679,14 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
pbic->ttlbuf = realloc(pbic->ttlbuf, len + 1);
|
||||
pbic->ttlbuflen = len + 1;
|
||||
}
|
||||
convert_linefeeds(neut_str, pbic->ttlbuf, pbic->ttlbuflen, &changed);
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (fCType == SQL_C_WCHAR)
|
||||
{
|
||||
utf8_to_ucs2(neut_str, -1, (SQLWCHAR *) pbic->ttlbuf, len / 2);
|
||||
}
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
convert_linefeeds(neut_str, pbic->ttlbuf, pbic->ttlbuflen, lf_conv, &changed);
|
||||
ptr = pbic->ttlbuf;
|
||||
}
|
||||
else
|
||||
@ -715,7 +747,25 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
||||
mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValueBindRow = '%s'\n", len, cbValueMax, rgbValueBindRow);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (SQL_C_WCHAR == fCType && ! wchanged)
|
||||
{
|
||||
if (cbValueMax > 2 * len)
|
||||
{
|
||||
char *str = strdup(rgbValueBindRow);
|
||||
UInt4 ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / 2);
|
||||
if (cbValueMax < 2 * (SDWORD) ucount)
|
||||
result = COPY_RESULT_TRUNCATED;
|
||||
len = ucount * 2;
|
||||
free(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
len *= 2;
|
||||
result = COPY_RESULT_TRUNCATED;
|
||||
}
|
||||
}
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
}
|
||||
else
|
||||
@ -1107,11 +1157,11 @@ do { \
|
||||
*/
|
||||
#define CVT_SPECIAL_CHARS(buf, used) \
|
||||
do { \
|
||||
int cnvlen = convert_special_chars(buf, NULL, used); \
|
||||
int cnvlen = convert_special_chars(buf, NULL, used, lf_conv, conn->ccsc); \
|
||||
unsigned int newlimit = npos + cnvlen; \
|
||||
\
|
||||
ENLARGE_NEWSTATEMENT(newlimit); \
|
||||
convert_special_chars(buf, &new_statement[npos], used); \
|
||||
convert_special_chars(buf, &new_statement[npos], used, lf_conv, conn->ccsc); \
|
||||
npos += cnvlen; \
|
||||
} while (0)
|
||||
|
||||
@ -1181,9 +1231,9 @@ table_for_update(const char *stmt, int *endpos)
|
||||
}
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
#define my_strchr(s1,c1) multibyte_strchr(s1,c1)
|
||||
#define my_strchr(conn, s1,c1) pg_mbschr(conn->ccsc, s1,c1)
|
||||
#else
|
||||
#define my_strchr(s1,c1) strchr(s1,c1)
|
||||
#define my_strchr(conn, s1,c1) strchr(s1,c1)
|
||||
#endif
|
||||
/*
|
||||
* This function inserts parameters into an SQL statements.
|
||||
@ -1213,8 +1263,7 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
time_t t = time(NULL);
|
||||
struct tm *tim;
|
||||
SDWORD used;
|
||||
char *buffer,
|
||||
*buf;
|
||||
char *buffer, *buf, *allocbuf;
|
||||
BOOL in_quote = FALSE,
|
||||
in_dquote = FALSE,
|
||||
in_escape = FALSE;
|
||||
@ -1234,6 +1283,10 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
BOOL prev_token_end;
|
||||
UInt4 offset = stmt->options.param_offset_ptr ? *stmt->options.param_offset_ptr : 0;
|
||||
UInt4 current_row = stmt->exec_current_row < 0 ? 0 : stmt->exec_current_row;
|
||||
BOOL lf_conv = ci->lf_conversion;
|
||||
#ifdef MULTIBYTE
|
||||
encoded_str encstr;
|
||||
#endif /* MULTIBYTE */
|
||||
|
||||
#ifdef DRIVER_CURSOR_IMPLEMENT
|
||||
BOOL search_from_pos = FALSE;
|
||||
@ -1311,14 +1364,14 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
}
|
||||
param_number = -1;
|
||||
#ifdef MULTIBYTE
|
||||
multibyte_init();
|
||||
make_encoded_str(&encstr, conn, old_statement);
|
||||
#endif
|
||||
|
||||
for (opos = 0; opos < oldstmtlen; opos++)
|
||||
{
|
||||
oldchar = old_statement[opos];
|
||||
#ifdef MULTIBYTE
|
||||
if (multibyte_char_check(oldchar) != 0)
|
||||
oldchar = encoded_byte_check(&encstr, opos);
|
||||
if (ENCODE_STATUS(encstr) != 0)
|
||||
{
|
||||
CVT_APPEND_CHAR(oldchar);
|
||||
continue;
|
||||
@ -1327,6 +1380,8 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
/*
|
||||
* From here we are guaranteed to handle a 1-byte character.
|
||||
*/
|
||||
#else
|
||||
oldchar = old_statement[opos];
|
||||
#endif
|
||||
|
||||
if (in_escape) /* escape check */
|
||||
@ -1352,7 +1407,7 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
* nor a double quote.
|
||||
*/
|
||||
/* Squeeze carriage-return/linefeed pairs to linefeed only */
|
||||
else if (oldchar == '\r' && opos + 1 < oldstmtlen &&
|
||||
else if (lf_conv && oldchar == '\r' && opos + 1 < oldstmtlen &&
|
||||
old_statement[opos + 1] == '\n')
|
||||
continue;
|
||||
|
||||
@ -1390,11 +1445,12 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
}
|
||||
opos += lit_call_len;
|
||||
CVT_APPEND_STR("SELECT ");
|
||||
if (my_strchr(&old_statement[opos], '('))
|
||||
if (my_strchr(conn, &old_statement[opos], '('))
|
||||
proc_no_param = FALSE;
|
||||
continue;
|
||||
}
|
||||
if (convert_escape(begin, stmt, &npos, &new_stsize, &end) != CONVERT_ESCAPE_OK)
|
||||
if (convert_escape(begin, stmt, &npos, &new_stsize, &end
|
||||
) != CONVERT_ESCAPE_OK)
|
||||
{
|
||||
stmt->errormsg = "ODBC escape convert error";
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
@ -1585,7 +1641,7 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
if (param_ctype == SQL_C_DEFAULT)
|
||||
param_ctype = sqltype_to_default_ctype(param_sqltype);
|
||||
|
||||
buf = NULL;
|
||||
allocbuf = buf = NULL;
|
||||
param_string[0] = '\0';
|
||||
cbuf[0] = '\0';
|
||||
|
||||
@ -1597,6 +1653,13 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
buf = buffer;
|
||||
break;
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case SQL_C_WCHAR:
|
||||
buf = allocbuf = ucs2_to_utf8((SQLWCHAR *) buffer, used / 2, &used);
|
||||
used *= 2;
|
||||
break;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
case SQL_C_DOUBLE:
|
||||
sprintf(param_string, "%.15g",
|
||||
*((SDOUBLE *) buffer));
|
||||
@ -1729,6 +1792,11 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
case SQL_CHAR:
|
||||
case SQL_VARCHAR:
|
||||
case SQL_LONGVARCHAR:
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case SQL_WCHAR:
|
||||
case SQL_WVARCHAR:
|
||||
case SQL_WLONGVARCHAR:
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
CVT_APPEND_CHAR('\''); /* Open Quote */
|
||||
|
||||
@ -1801,7 +1869,7 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
tmp[0] = '\'';
|
||||
/* Time zone stuff is unreliable */
|
||||
stime2timestamp(&st, tmp + 1, USE_ZONE, PG_VERSION_GE(conn, 7.2));
|
||||
strcat(tmp, "'");
|
||||
strcat(tmp, "'::timestamp");
|
||||
|
||||
CVT_APPEND_STR(tmp);
|
||||
|
||||
@ -1942,6 +2010,10 @@ copy_statement_with_parameters(StatementClass *stmt)
|
||||
|
||||
break;
|
||||
}
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (allocbuf)
|
||||
free(allocbuf);
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
} /* end, for */
|
||||
|
||||
/* make sure new_statement is always null-terminated */
|
||||
@ -2032,7 +2104,7 @@ int inner_convert_escape(const ConnectionClass *conn, const char *value,
|
||||
while ((*valptr != '\0') && isspace((unsigned char) *valptr))
|
||||
valptr++;
|
||||
|
||||
if (end = my_strchr(valptr, '}'), NULL == end)
|
||||
if (end = my_strchr(conn, valptr, '}'), NULL == end)
|
||||
{
|
||||
mylog("%s couldn't find the ending }\n",func);
|
||||
return CONVERT_ESCAPE_ERROR;
|
||||
@ -2226,13 +2298,16 @@ int processParameters(const ConnectionClass *conn, const char *value,
|
||||
const char *valptr;
|
||||
char buf[1024];
|
||||
BOOL in_quote, in_dquote, in_escape, leadingSpace;
|
||||
#ifdef MULTIBYTE
|
||||
encoded_str encstr;
|
||||
#endif /* MULTIBYTE */
|
||||
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
innerParenthesis = 0;
|
||||
in_quote = in_dquote = in_escape = leadingSpace = FALSE;
|
||||
param_count = 0;
|
||||
#ifdef MULTIBYTE
|
||||
multibyte_init();
|
||||
make_encoded_str(&encstr, conn, value);
|
||||
#endif /* MULTIBYTE */
|
||||
/* begin with outer '(' */
|
||||
for (stop = FALSE, valptr = value, ipos = count = 0; *valptr != '\0'; ipos++, valptr++)
|
||||
@ -2250,7 +2325,8 @@ int processParameters(const ConnectionClass *conn, const char *value,
|
||||
return CONVERT_ESCAPE_OVERFLOW;
|
||||
}
|
||||
#ifdef MULTIBYTE
|
||||
if (multibyte_char_check(*valptr) != 0)
|
||||
encoded_byte_check(&encstr, ipos);
|
||||
if (ENCODE_STATUS(encstr) != 0)
|
||||
{
|
||||
result[count++] = *valptr;
|
||||
continue;
|
||||
@ -2468,7 +2544,7 @@ parse_datetime(char *buf, SIMPLE_TIME *st)
|
||||
|
||||
/* Change linefeed to carriage-return/linefeed */
|
||||
int
|
||||
convert_linefeeds(const char *si, char *dst, size_t max, BOOL *changed)
|
||||
convert_linefeeds(const char *si, char *dst, size_t max, BOOL convlf, BOOL *changed)
|
||||
{
|
||||
size_t i = 0,
|
||||
out = 0;
|
||||
@ -2478,7 +2554,7 @@ convert_linefeeds(const char *si, char *dst, size_t max, BOOL *changed)
|
||||
*changed = FALSE;
|
||||
for (i = 0; si[i] && out < max - 1; i++)
|
||||
{
|
||||
if (si[i] == '\n')
|
||||
if (convlf && si[i] == '\n')
|
||||
{
|
||||
/* Only add the carriage-return if needed */
|
||||
if (i > 0 && si[i - 1] == '\r')
|
||||
@ -2518,12 +2594,15 @@ convert_linefeeds(const char *si, char *dst, size_t max, BOOL *changed)
|
||||
* Plus, escape any special characters.
|
||||
*/
|
||||
int
|
||||
convert_special_chars(const char *si, char *dst, int used)
|
||||
convert_special_chars(const char *si, char *dst, int used, BOOL convlf, int ccsc)
|
||||
{
|
||||
size_t i = 0,
|
||||
out = 0,
|
||||
max;
|
||||
char *p = NULL;
|
||||
#ifdef MULTIBYTE
|
||||
encoded_str encstr;
|
||||
#endif
|
||||
|
||||
|
||||
if (used == SQL_NTS)
|
||||
@ -2536,13 +2615,14 @@ convert_special_chars(const char *si, char *dst, int used)
|
||||
p[0] = '\0';
|
||||
}
|
||||
#ifdef MULTIBYTE
|
||||
multibyte_init();
|
||||
encoded_str_constr(&encstr, ccsc, si);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < max && si[i]; i++)
|
||||
{
|
||||
#ifdef MULTIBYTE
|
||||
if (multibyte_char_check(si[i]) != 0)
|
||||
encoded_nextchar(&encstr);
|
||||
if (ENCODE_STATUS(encstr) != 0)
|
||||
{
|
||||
if (p)
|
||||
p[out] = si[i];
|
||||
@ -2550,7 +2630,7 @@ convert_special_chars(const char *si, char *dst, int used)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (si[i] == '\r' && si[i + 1] == '\n')
|
||||
if (convlf && si[i] == '\r' && si[i + 1] == '\n')
|
||||
continue;
|
||||
else if (si[i] == '\'' || si[i] == '\\')
|
||||
{
|
||||
|
@ -21,7 +21,7 @@
|
||||
/* convert_escape results */
|
||||
#define CONVERT_ESCAPE_OK 0
|
||||
#define CONVERT_ESCAPE_OVERFLOW 1
|
||||
#define CONVERT_ESCAPE_ERROR 2
|
||||
#define CONVERT_ESCAPE_ERROR -1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -43,8 +43,8 @@ int convert_escape(const char *value, StatementClass *stmt,
|
||||
int *npos, int *stsize, const char **val_resume);
|
||||
BOOL convert_money(const char *s, char *sout, size_t soutmax);
|
||||
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(const char *si, char *dst, int used);
|
||||
int convert_linefeeds(const char *s, char *dst, size_t max, BOOL convlf, BOOL *changed);
|
||||
int convert_special_chars(const char *si, char *dst, int used, BOOL convlf,int ccsc);
|
||||
|
||||
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);
|
||||
|
@ -123,7 +123,7 @@ driver_optionsDraw(HWND hdlg, const ConnInfo *ci, int src, BOOL enable)
|
||||
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);
|
||||
/* 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);
|
||||
@ -332,6 +332,8 @@ ds_optionsProc(HWND hdlg,
|
||||
CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning));
|
||||
CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables));
|
||||
CheckDlgButton(hdlg, DS_DISALLOWPREMATURE, ci->disallow_premature);
|
||||
CheckDlgButton(hdlg, DS_LFCONVERSION, ci->lf_conversion);
|
||||
CheckDlgButton(hdlg, DS_TRUEISMINUS1, ci->true_is_minus1);
|
||||
|
||||
EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column));
|
||||
|
||||
@ -367,6 +369,8 @@ ds_optionsProc(HWND hdlg,
|
||||
|
||||
sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING));
|
||||
ci->disallow_premature = IsDlgButtonChecked(hdlg, DS_DISALLOWPREMATURE);
|
||||
ci->lf_conversion = IsDlgButtonChecked(hdlg, DS_LFCONVERSION);
|
||||
ci->true_is_minus1 = IsDlgButtonChecked(hdlg, DS_TRUEISMINUS1);
|
||||
|
||||
/* OID Options */
|
||||
sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX));
|
||||
@ -525,60 +529,186 @@ makeConnectString(char *connect_string, const ConnInfo *ci, UWORD len)
|
||||
hlen = strlen(connect_string);
|
||||
if (!abbrev)
|
||||
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",
|
||||
";%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d",
|
||||
INI_READONLY,
|
||||
ci->onlyread,
|
||||
INI_PROTOCOL,
|
||||
ci->protocol,
|
||||
INI_FAKEOIDINDEX,
|
||||
ci->fake_oid_index,
|
||||
INI_SHOWOIDCOLUMN,
|
||||
ci->show_oid_column,
|
||||
INI_ROWVERSIONING,
|
||||
ci->row_versioning,
|
||||
INI_SHOWSYSTEMTABLES,
|
||||
ci->show_system_tables,
|
||||
INI_CONNSETTINGS,
|
||||
encoded_conn_settings,
|
||||
INI_FETCH,
|
||||
ci->drivers.fetch_max,
|
||||
INI_SOCKET,
|
||||
ci->drivers.socket_buffersize,
|
||||
INI_UNKNOWNSIZES,
|
||||
ci->drivers.unknown_sizes,
|
||||
INI_MAXVARCHARSIZE,
|
||||
ci->drivers.max_varchar_size,
|
||||
INI_MAXLONGVARCHARSIZE,
|
||||
ci->drivers.max_longvarchar_size,
|
||||
INI_DEBUG,
|
||||
ci->drivers.debug,
|
||||
INI_COMMLOG,
|
||||
ci->drivers.commlog,
|
||||
INI_OPTIMIZER,
|
||||
ci->drivers.disable_optimizer,
|
||||
INI_KSQO,
|
||||
ci->drivers.ksqo,
|
||||
INI_USEDECLAREFETCH,
|
||||
ci->drivers.use_declarefetch,
|
||||
INI_TEXTASLONGVARCHAR,
|
||||
ci->drivers.text_as_longvarchar,
|
||||
INI_UNKNOWNSASLONGVARCHAR,
|
||||
ci->drivers.unknowns_as_longvarchar,
|
||||
INI_BOOLSASCHAR,
|
||||
ci->drivers.bools_as_char,
|
||||
INI_PARSE,
|
||||
ci->drivers.parse,
|
||||
INI_CANCELASFREESTMT,
|
||||
ci->drivers.cancel_as_freestmt,
|
||||
ci->drivers.extra_systable_prefixes);
|
||||
INI_EXTRASYSTABLEPREFIXES,
|
||||
ci->drivers.extra_systable_prefixes,
|
||||
INI_LFCONVERSION,
|
||||
ci->lf_conversion,
|
||||
INI_UPDATABLECURSORS,
|
||||
ci->updatable_cursors,
|
||||
INI_DISALLOWPREMATURE,
|
||||
ci->disallow_premature,
|
||||
INI_TRUEISMINUS1,
|
||||
ci->true_is_minus1);
|
||||
/* Abbrebiation is needed ? */
|
||||
if (abbrev || strlen(connect_string) >= len)
|
||||
{
|
||||
unsigned long flag = 0;
|
||||
if (ci->disallow_premature)
|
||||
flag |= BIT_DISALLOWPREMATURE;
|
||||
if (ci->updatable_cursors)
|
||||
flag |= BIT_UPDATABLECURSORS;
|
||||
if (ci->lf_conversion)
|
||||
flag |= BIT_LFCONVERSION;
|
||||
if (ci->drivers.unique_index)
|
||||
flag |= BIT_UNIQUEINDEX;
|
||||
if (strncmp(ci->protocol, PG64, strlen(PG64)) == 0)
|
||||
flag |= BIT_PROTOCOL_64;
|
||||
else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0)
|
||||
flag |= BIT_PROTOCOL_63;
|
||||
switch (ci->drivers.unknown_sizes)
|
||||
{
|
||||
case UNKNOWNS_AS_DONTKNOW:
|
||||
flag |= BIT_UNKNOWN_DONTKNOW;
|
||||
break;
|
||||
case UNKNOWNS_AS_MAX:
|
||||
flag |= BIT_UNKNOWN_ASMAX;
|
||||
break;
|
||||
}
|
||||
if (ci->drivers.disable_optimizer)
|
||||
flag |= BIT_OPTIMIZER;
|
||||
if (ci->drivers.ksqo)
|
||||
flag |= BIT_KSQO;
|
||||
if (ci->drivers.commlog)
|
||||
flag |= BIT_COMMLOG;
|
||||
if (ci->drivers.debug)
|
||||
flag |= BIT_DEBUG;
|
||||
if (ci->drivers.parse)
|
||||
flag |= BIT_PARSE;
|
||||
if (ci->drivers.cancel_as_freestmt)
|
||||
flag |= BIT_CANCELASFREESTMT;
|
||||
if (ci->drivers.use_declarefetch)
|
||||
flag |= BIT_USEDECLAREFETCH;
|
||||
if (ci->onlyread[0] == '1')
|
||||
flag |= BIT_READONLY;
|
||||
if (ci->drivers.text_as_longvarchar)
|
||||
flag |= BIT_TEXTASLONGVARCHAR;
|
||||
if (ci->drivers.unknowns_as_longvarchar)
|
||||
flag |= BIT_UNKNOWNSASLONGVARCHAR;
|
||||
if (ci->drivers.bools_as_char)
|
||||
flag |= BIT_BOOLSASCHAR;
|
||||
if (ci->row_versioning[0] == '1')
|
||||
flag |= BIT_ROWVERSIONING;
|
||||
if (ci->show_system_tables[0] == '1')
|
||||
flag |= BIT_SHOWSYSTEMTABLES;
|
||||
if (ci->show_oid_column[0] == '1')
|
||||
flag |= BIT_SHOWOIDCOLUMN;
|
||||
if (ci->fake_oid_index[0] == '1')
|
||||
flag |= BIT_FAKEOIDINDEX;
|
||||
if (ci->true_is_minus1)
|
||||
flag |= BIT_TRUEISMINUS1;
|
||||
|
||||
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,
|
||||
";A6=%s;A7=%d;A8=%d;B0=%d;B1=%d;C2=%s;CX=%02x%x",
|
||||
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);
|
||||
ci->drivers.extra_systable_prefixes,
|
||||
EFFECTIVE_BIT_COUNT,
|
||||
flag);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unfoldCXAttribute(ConnInfo *ci, const char *value)
|
||||
{
|
||||
int count;
|
||||
unsigned long flag;
|
||||
|
||||
if (strlen(value) < 2)
|
||||
{
|
||||
count = 3;
|
||||
sscanf(value, "%x", &flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
char cnt[8];
|
||||
memcpy(cnt, value, 2);
|
||||
cnt[2] = '\0';
|
||||
sscanf(cnt, "%x", &count);
|
||||
sscanf(value + 2, "%x", &flag);
|
||||
}
|
||||
ci->disallow_premature = (char)((flag & BIT_DISALLOWPREMATURE) != 0);
|
||||
ci->updatable_cursors = (char)((flag & BIT_UPDATABLECURSORS) != 0);
|
||||
ci->lf_conversion = (char)((flag & BIT_LFCONVERSION) != 0);
|
||||
if (count < 4)
|
||||
return;
|
||||
ci->drivers.unique_index = (char)((flag & BIT_UNIQUEINDEX) != 0);
|
||||
if ((flag & BIT_PROTOCOL_64) != 0)
|
||||
strcpy(ci->protocol, PG64);
|
||||
else if ((flag & BIT_PROTOCOL_63) != 0)
|
||||
strcpy(ci->protocol, PG63);
|
||||
else
|
||||
strcpy(ci->protocol, PG62);
|
||||
if ((flag & BIT_UNKNOWN_DONTKNOW) != 0)
|
||||
ci->drivers.unknown_sizes = UNKNOWNS_AS_DONTKNOW;
|
||||
else if ((flag & BIT_UNKNOWN_ASMAX) != 0)
|
||||
ci->drivers.unknown_sizes = UNKNOWNS_AS_MAX;
|
||||
else
|
||||
ci->drivers.unknown_sizes = UNKNOWNS_AS_LONGEST;
|
||||
ci->drivers.disable_optimizer = (char)((flag & BIT_OPTIMIZER) != 0);
|
||||
ci->drivers.ksqo = (char)((flag & BIT_KSQO) != 0);
|
||||
ci->drivers.commlog = (char)((flag & BIT_COMMLOG) != 0);
|
||||
ci->drivers.debug = (char)((flag & BIT_DEBUG) != 0);
|
||||
ci->drivers.parse = (char)((flag & BIT_PARSE) != 0);
|
||||
ci->drivers.cancel_as_freestmt = (char)((flag & BIT_CANCELASFREESTMT) != 0);
|
||||
ci->drivers.use_declarefetch = (char)((flag & BIT_USEDECLAREFETCH) != 0);
|
||||
sprintf(ci->onlyread, "%d", (char)((flag & BIT_READONLY) != 0));
|
||||
ci->drivers.text_as_longvarchar = (char)((flag & BIT_TEXTASLONGVARCHAR) !=0);
|
||||
ci->drivers.unknowns_as_longvarchar = (char)((flag & BIT_UNKNOWNSASLONGVARCHAR) !=0);
|
||||
ci->drivers.bools_as_char = (char)((flag & BIT_BOOLSASCHAR) != 0);
|
||||
sprintf(ci->row_versioning, "%d", (char)((flag & BIT_ROWVERSIONING) != 0));
|
||||
sprintf(ci->show_system_tables, "%d", (char)((flag & BIT_SHOWSYSTEMTABLES) != 0));
|
||||
sprintf(ci->show_oid_column, "%d", (char)((flag & BIT_SHOWOIDCOLUMN) != 0));
|
||||
sprintf(ci->fake_oid_index, "%d", (char)((flag & BIT_FAKEOIDINDEX) != 0));
|
||||
ci->true_is_minus1 = (char)((flag & BIT_TRUEISMINUS1) != 0);
|
||||
}
|
||||
void
|
||||
copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
|
||||
{
|
||||
@ -630,6 +760,12 @@ copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
|
||||
ci->disallow_premature = atoi(value);
|
||||
else if (stricmp(attribute, INI_UPDATABLECURSORS) == 0 || stricmp(attribute, "C4") == 0)
|
||||
ci->updatable_cursors = atoi(value);
|
||||
else if (stricmp(attribute, INI_LFCONVERSION) == 0)
|
||||
ci->lf_conversion = atoi(value);
|
||||
else if (stricmp(attribute, INI_TRUEISMINUS1) == 0)
|
||||
ci->true_is_minus1 = atoi(value);
|
||||
else if (stricmp(attribute, "CX") == 0)
|
||||
unfoldCXAttribute(ci, value);
|
||||
|
||||
mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature);
|
||||
}
|
||||
@ -720,6 +856,15 @@ getDSNdefaults(ConnInfo *ci)
|
||||
|
||||
if (ci->row_versioning[0] == '\0')
|
||||
sprintf(ci->row_versioning, "%d", DEFAULT_ROWVERSIONING);
|
||||
|
||||
if (ci->disallow_premature < 0)
|
||||
ci->disallow_premature = DEFAULT_DISALLOWPREMATURE;
|
||||
if (ci->updatable_cursors < 0)
|
||||
ci->updatable_cursors = DEFAULT_UPDATABLECURSORS;
|
||||
if (ci->lf_conversion < 0)
|
||||
ci->lf_conversion = DEFAULT_LFCONVERSION;
|
||||
if (ci->true_is_minus1 < 0)
|
||||
ci->true_is_minus1 = DEFAULT_TRUEISMINUS1;
|
||||
}
|
||||
|
||||
|
||||
@ -797,16 +942,32 @@ getDSNinfo(ConnInfo *ci, char overwrite)
|
||||
if (ci->translation_option[0] == '\0' || overwrite)
|
||||
SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI);
|
||||
|
||||
if (ci->disallow_premature == 0 || overwrite)
|
||||
if (ci->disallow_premature < 0 || overwrite)
|
||||
{
|
||||
SQLGetPrivateProfileString(DSN, INI_DISALLOWPREMATURE, "", temp, sizeof(temp), ODBC_INI);
|
||||
ci->disallow_premature = atoi(temp);
|
||||
if (temp[0])
|
||||
ci->disallow_premature = atoi(temp);
|
||||
}
|
||||
|
||||
if (ci->updatable_cursors == 0 || overwrite)
|
||||
if (ci->updatable_cursors < 0 || overwrite)
|
||||
{
|
||||
SQLGetPrivateProfileString(DSN, INI_UPDATABLECURSORS, "", temp, sizeof(temp), ODBC_INI);
|
||||
ci->updatable_cursors = atoi(temp);
|
||||
if (temp[0])
|
||||
ci->updatable_cursors = atoi(temp);
|
||||
}
|
||||
|
||||
if (ci->lf_conversion < 0 || overwrite)
|
||||
{
|
||||
SQLGetPrivateProfileString(DSN, INI_LFCONVERSION, "", temp, sizeof(temp), ODBC_INI);
|
||||
if (temp[0])
|
||||
ci->lf_conversion = atoi(temp);
|
||||
}
|
||||
|
||||
if (ci->true_is_minus1 < 0 || overwrite)
|
||||
{
|
||||
SQLGetPrivateProfileString(DSN, INI_TRUEISMINUS1, "", temp, sizeof(temp), ODBC_INI);
|
||||
if (temp[0])
|
||||
ci->true_is_minus1 = atoi(temp);
|
||||
}
|
||||
|
||||
/* Allow override of odbcinst.ini parameters here */
|
||||
@ -927,6 +1088,16 @@ writeDSNinfo(const ConnInfo *ci)
|
||||
INI_UPDATABLECURSORS,
|
||||
temp,
|
||||
ODBC_INI);
|
||||
sprintf(temp, "%d", ci->lf_conversion);
|
||||
SQLWritePrivateProfileString(DSN,
|
||||
INI_LFCONVERSION,
|
||||
temp,
|
||||
ODBC_INI);
|
||||
sprintf(temp, "%d", ci->true_is_minus1);
|
||||
SQLWritePrivateProfileString(DSN,
|
||||
INI_TRUEISMINUS1,
|
||||
temp,
|
||||
ODBC_INI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,6 +89,35 @@
|
||||
#define INI_TRANSLATIONOPTION "TranslationOption"
|
||||
#define INI_DISALLOWPREMATURE "DisallowPremature"
|
||||
#define INI_UPDATABLECURSORS "UpdatableCursors"
|
||||
#define INI_LFCONVERSION "LFConversion"
|
||||
#define INI_TRUEISMINUS1 "TrueIsMinus1"
|
||||
/* Bit representaion for abbreviated connection strings */
|
||||
#define BIT_LFCONVERSION (1L)
|
||||
#define BIT_UPDATABLECURSORS (1L<<1)
|
||||
#define BIT_DISALLOWPREMATURE (1L<<2)
|
||||
#define BIT_UNIQUEINDEX (1L<<3)
|
||||
#define BIT_PROTOCOL_63 (1L<<4)
|
||||
#define BIT_PROTOCOL_64 (1L<<5)
|
||||
#define BIT_UNKNOWN_DONTKNOW (1L<<6)
|
||||
#define BIT_UNKNOWN_ASMAX (1L<<7)
|
||||
#define BIT_OPTIMIZER (1L<<8)
|
||||
#define BIT_KSQO (1L<<9)
|
||||
#define BIT_COMMLOG (1L<<10)
|
||||
#define BIT_DEBUG (1L<<11)
|
||||
#define BIT_PARSE (1L<<12)
|
||||
#define BIT_CANCELASFREESTMT (1L<<13)
|
||||
#define BIT_USEDECLAREFETCH (1L<<14)
|
||||
#define BIT_READONLY (1L<<15)
|
||||
#define BIT_TEXTASLONGVARCHAR (1L<<16)
|
||||
#define BIT_UNKNOWNSASLONGVARCHAR (1L<<17)
|
||||
#define BIT_BOOLSASCHAR (1L<<18)
|
||||
#define BIT_ROWVERSIONING (1L<<19)
|
||||
#define BIT_SHOWSYSTEMTABLES (1L<<20)
|
||||
#define BIT_SHOWOIDCOLUMN (1L<<21)
|
||||
#define BIT_FAKEOIDINDEX (1L<<22)
|
||||
#define BIT_TRUEISMINUS1 (1L<<23)
|
||||
|
||||
#define EFFECTIVE_BIT_COUNT 24
|
||||
|
||||
|
||||
/* Connection Defaults */
|
||||
@ -119,6 +148,19 @@
|
||||
|
||||
#define DEFAULT_EXTRASYSTABLEPREFIXES "dd_;"
|
||||
|
||||
#define DEFAULT_DISALLOWPREMATURE 0
|
||||
#define DEFAULT_TRUEISMINUS1 0
|
||||
#ifdef DRIVER_CURSOR_IMPLEMENT
|
||||
#define DEFAULT_UPDATABLECURSORS 1
|
||||
#else
|
||||
#define DEFAULT_UPDATABLECURSORS 0
|
||||
#endif /* DRIVER_CURSOR_IMPLEMENT */
|
||||
#ifdef WIN32
|
||||
#define DEFAULT_LFCONVERSION 1
|
||||
#else
|
||||
#define DEFAULT_LFCONVERSION 0
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* prototypes */
|
||||
void getCommonDefaults(const char *section, const char *filename, ConnInfo *ci);
|
||||
|
||||
|
@ -242,7 +242,7 @@ dialog:
|
||||
qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut);
|
||||
|
||||
|
||||
mylog("PGAPI_DRiverConnect: returning %d\n", result);
|
||||
mylog("PGAPI_DriverConnect: returning %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -351,10 +351,7 @@ dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
|
||||
*equals;
|
||||
char *strtok_arg;
|
||||
|
||||
memset(ci, 0, sizeof(ConnInfo));
|
||||
#ifdef DRIVER_CURSOR_IMPLEMENT
|
||||
ci->updatable_cursors = 1;
|
||||
#endif /* DRIVER_CURSOR_IMPLEMENT */
|
||||
CC_conninfo_init(ci);
|
||||
|
||||
our_connect_string = strdup(connect_string);
|
||||
strtok_arg = our_connect_string;
|
||||
|
@ -78,6 +78,407 @@ PGAPI_FreeEnv(HENV henv)
|
||||
}
|
||||
|
||||
|
||||
#define DRVMNGRDIV 511
|
||||
/* Returns the next SQL error information. */
|
||||
RETCODE SQL_API
|
||||
PGAPI_StmtError( HSTMT hstmt,
|
||||
SWORD RecNumber,
|
||||
UCHAR FAR * szSqlState,
|
||||
SDWORD FAR * pfNativeError,
|
||||
UCHAR FAR * szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR * pcbErrorMsg,
|
||||
UWORD flag)
|
||||
{
|
||||
/* CC: return an error of a hstmt */
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char *msg;
|
||||
int status;
|
||||
BOOL once_again = FALSE,
|
||||
partial_ok = (flag & PODBC_ALLOW_PARTIAL_EXTRACT != 0),
|
||||
clear_str = (flag & PODBC_ERROR_CLEAR != 0);
|
||||
SWORD msglen, stapos, wrtlen, pcblen;
|
||||
|
||||
mylog("**** PGAPI_StmtError: hstmt=%u <%d>\n", hstmt, cbErrorMsgMax);
|
||||
|
||||
if (cbErrorMsgMax < 0)
|
||||
return SQL_ERROR;
|
||||
|
||||
if (!SC_get_error(stmt, &status, &msg) || NULL == msg || !msg[0])
|
||||
{
|
||||
mylog("SC_Get_error returned nothing.\n");
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
msglen = (SWORD) strlen(msg);
|
||||
/*
|
||||
* Even though an application specifies a larger error message
|
||||
* buffer, the driver manager changes it silently.
|
||||
* Therefore we divide the error message into ...
|
||||
*/
|
||||
if (stmt->error_recsize < 0)
|
||||
{
|
||||
if (cbErrorMsgMax > 0)
|
||||
stmt->error_recsize = cbErrorMsgMax - 1; /* apply the first request */
|
||||
else
|
||||
stmt->error_recsize = DRVMNGRDIV;
|
||||
}
|
||||
if (RecNumber < 0)
|
||||
{
|
||||
if (0 == stmt->errorpos)
|
||||
RecNumber = 1;
|
||||
else
|
||||
RecNumber = 2 + (stmt->errorpos - 1) / stmt->error_recsize;
|
||||
}
|
||||
stapos = (RecNumber - 1) * stmt->error_recsize;
|
||||
if (stapos > msglen)
|
||||
return SQL_NO_DATA_FOUND;
|
||||
pcblen = wrtlen = msglen - stapos;
|
||||
if (pcblen > stmt->error_recsize)
|
||||
pcblen = stmt->error_recsize;
|
||||
if (0 == cbErrorMsgMax)
|
||||
wrtlen = 0;
|
||||
else if (wrtlen >= cbErrorMsgMax)
|
||||
{
|
||||
if (partial_ok)
|
||||
wrtlen = cbErrorMsgMax - 1;
|
||||
else if (cbErrorMsgMax <= stmt->error_recsize)
|
||||
wrtlen = 0;
|
||||
else
|
||||
wrtlen = stmt->error_recsize;
|
||||
}
|
||||
if (wrtlen > pcblen)
|
||||
wrtlen = pcblen;
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = pcblen;
|
||||
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
{
|
||||
memcpy(szErrorMsg, msg + stapos, wrtlen);
|
||||
szErrorMsg[wrtlen] = '\0';
|
||||
}
|
||||
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
|
||||
switch (status)
|
||||
{
|
||||
/* now determine the SQLSTATE to be returned */
|
||||
case STMT_ROW_VERSION_CHANGED:
|
||||
strcpy(szSqlState, "01001");
|
||||
/* data truncated */
|
||||
break;
|
||||
case STMT_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case STMT_INFO_ONLY:
|
||||
strcpy(szSqlState, "00000");
|
||||
/* just information that is returned, no error */
|
||||
break;
|
||||
case STMT_BAD_ERROR:
|
||||
strcpy(szSqlState, "08S01");
|
||||
/* communication link failure */
|
||||
break;
|
||||
case STMT_CREATE_TABLE_ERROR:
|
||||
strcpy(szSqlState, "S0001");
|
||||
/* table already exists */
|
||||
break;
|
||||
case STMT_STATUS_ERROR:
|
||||
case STMT_SEQUENCE_ERROR:
|
||||
strcpy(szSqlState, "S1010");
|
||||
/* Function sequence error */
|
||||
break;
|
||||
case STMT_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case STMT_COLNUM_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
/* invalid column number */
|
||||
break;
|
||||
case STMT_NO_STMTSTRING:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* having no stmtstring is also a malloc problem */
|
||||
break;
|
||||
case STMT_ERROR_TAKEN_FROM_BACKEND:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_INTERNAL_ERROR:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_ROW_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "S1107");
|
||||
break;
|
||||
|
||||
case STMT_OPERATION_CANCELLED:
|
||||
strcpy(szSqlState, "S1008");
|
||||
break;
|
||||
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00"); /* == 'driver not
|
||||
* capable' */
|
||||
break;
|
||||
case STMT_OPTION_OUT_OF_RANGE_ERROR:
|
||||
strcpy(szSqlState, "S1092");
|
||||
break;
|
||||
case STMT_BAD_PARAMETER_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1093");
|
||||
break;
|
||||
case STMT_INVALID_COLUMN_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
break;
|
||||
case STMT_RESTRICTED_DATA_TYPE_ERROR:
|
||||
strcpy(szSqlState, "07006");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_STATE_ERROR:
|
||||
strcpy(szSqlState, "24000");
|
||||
break;
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_POS_BEFORE_RECORDSET:
|
||||
strcpy(szSqlState, "01S06");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_NAME:
|
||||
strcpy(szSqlState, "34000");
|
||||
break;
|
||||
case STMT_NO_CURSOR_NAME:
|
||||
strcpy(szSqlState, "S1015");
|
||||
break;
|
||||
case STMT_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_POSITION:
|
||||
strcpy(szSqlState, "S1109");
|
||||
break;
|
||||
case STMT_RETURN_NULL_WITHOUT_INDICATOR:
|
||||
strcpy(szSqlState, "22002");
|
||||
break;
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
case STMT_OPERATION_INVALID:
|
||||
strcpy(szSqlState, "S1011");
|
||||
break;
|
||||
case STMT_INVALID_OPTION_IDENTIFIER:
|
||||
strcpy(szSqlState, "HY092");
|
||||
break;
|
||||
case STMT_EXEC_ERROR:
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* also a general error */
|
||||
break;
|
||||
}
|
||||
mylog(" szSqlState = '%s',len=%d, szError='%s'\n", szSqlState, pcblen, szErrorMsg);
|
||||
if (clear_str)
|
||||
{
|
||||
stmt->errorpos = stapos + wrtlen;
|
||||
if (stmt->errorpos >= msglen)
|
||||
SC_clear_error(stmt);
|
||||
}
|
||||
if (wrtlen == 0)
|
||||
return SQL_SUCCESS_WITH_INFO;
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
RETCODE SQL_API
|
||||
PGAPI_ConnectError( HDBC hdbc,
|
||||
SWORD RecNumber,
|
||||
UCHAR FAR * szSqlState,
|
||||
SDWORD FAR * pfNativeError,
|
||||
UCHAR FAR * szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR * pcbErrorMsg,
|
||||
UWORD flag)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
char *msg;
|
||||
int status;
|
||||
BOOL once_again = FALSE;
|
||||
SWORD msglen;
|
||||
|
||||
if (RecNumber != 1)
|
||||
return SQL_NO_DATA_FOUND;
|
||||
if (cbErrorMsgMax < 0)
|
||||
return SQL_ERROR;
|
||||
if (!CC_get_error(conn, &status, &msg) || NULL == msg)
|
||||
{
|
||||
mylog("CC_Get_error returned nothing.\n");
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
|
||||
msglen = strlen(msg);
|
||||
if (NULL != pcbErrorMsg)
|
||||
{
|
||||
*pcbErrorMsg = msglen;
|
||||
if (cbErrorMsgMax == 0)
|
||||
once_again = TRUE;
|
||||
else if (msglen >= cbErrorMsgMax)
|
||||
*pcbErrorMsg = cbErrorMsgMax - 1;
|
||||
}
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
switch (status)
|
||||
{
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
case CONN_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_TRUNCATED:
|
||||
case CONN_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case CONN_INIREAD_ERROR:
|
||||
strcpy(szSqlState, "IM002");
|
||||
/* data source not found */
|
||||
break;
|
||||
case CONN_OPENDB_ERROR:
|
||||
strcpy(szSqlState, "08001");
|
||||
/* unable to connect to data source */
|
||||
break;
|
||||
case CONN_INVALID_AUTHENTICATION:
|
||||
case CONN_AUTH_TYPE_UNSUPPORTED:
|
||||
strcpy(szSqlState, "28000");
|
||||
break;
|
||||
case CONN_STMT_ALLOC_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case CONN_IN_USE:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case CONN_UNSUPPORTED_OPTION:
|
||||
strcpy(szSqlState, "IM001");
|
||||
/* driver does not support this function */
|
||||
case CONN_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case CONN_TRANSACT_IN_PROGRES:
|
||||
strcpy(szSqlState, "S1010");
|
||||
|
||||
/*
|
||||
* when the user tries to switch commit mode in a
|
||||
* transaction
|
||||
*/
|
||||
/* -> function sequence error */
|
||||
break;
|
||||
case CONN_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
case CONN_NOT_IMPLEMENTED_ERROR:
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00");
|
||||
break;
|
||||
case STMT_RETURN_NULL_WITHOUT_INDICATOR:
|
||||
strcpy(szSqlState, "22002");
|
||||
break;
|
||||
case CONN_VALUE_OUT_OF_RANGE:
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
|
||||
if (once_again)
|
||||
{
|
||||
conn->errornumber = status;
|
||||
return SQL_SUCCESS_WITH_INFO;
|
||||
}
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
RETCODE SQL_API
|
||||
PGAPI_EnvError( HENV henv,
|
||||
SWORD RecNumber,
|
||||
UCHAR FAR * szSqlState,
|
||||
SDWORD FAR * pfNativeError,
|
||||
UCHAR FAR * szErrorMsg,
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR * pcbErrorMsg,
|
||||
UWORD flag)
|
||||
{
|
||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||
char *msg;
|
||||
int status;
|
||||
|
||||
if (RecNumber != 1)
|
||||
return SQL_NO_DATA_FOUND;
|
||||
if (cbErrorMsgMax < 0)
|
||||
return SQL_ERROR;
|
||||
if (!EN_get_error(env, &status, &msg) || NULL == msg)
|
||||
{
|
||||
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (szSqlState)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ENV_ALLOC_ERROR:
|
||||
/* memory allocation failure */
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the next SQL error information. */
|
||||
RETCODE SQL_API
|
||||
PGAPI_Error(
|
||||
@ -90,396 +491,37 @@ PGAPI_Error(
|
||||
SWORD cbErrorMsgMax,
|
||||
SWORD FAR * pcbErrorMsg)
|
||||
{
|
||||
char *msg;
|
||||
int status;
|
||||
BOOL once_again = FALSE;
|
||||
SWORD msglen;
|
||||
RETCODE ret;
|
||||
UWORD flag = PODBC_ALLOW_PARTIAL_EXTRACT | PODBC_ERROR_CLEAR;
|
||||
|
||||
mylog("**** PGAPI_Error: henv=%u, hdbc=%u, hstmt=%u <%d>\n", henv, hdbc, hstmt, cbErrorMsgMax);
|
||||
mylog("**** PGAPI_Error: henv=%u, hdbc=%u hstmt=%d\n", henv, hdbc, hstmt);
|
||||
|
||||
if (cbErrorMsgMax < 0)
|
||||
return SQL_ERROR;
|
||||
if (SQL_NULL_HSTMT != hstmt)
|
||||
{
|
||||
/* CC: return an error of a hstmt */
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
if (SC_get_error(stmt, &status, &msg))
|
||||
{
|
||||
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg)
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
msglen = (SWORD) strlen(msg);
|
||||
if (NULL != pcbErrorMsg)
|
||||
{
|
||||
*pcbErrorMsg = msglen;
|
||||
if (cbErrorMsgMax == 0)
|
||||
once_again = TRUE;
|
||||
else if (msglen >= cbErrorMsgMax)
|
||||
{
|
||||
once_again = TRUE;
|
||||
*pcbErrorMsg = cbErrorMsgMax - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
|
||||
switch (status)
|
||||
{
|
||||
/* now determine the SQLSTATE to be returned */
|
||||
case STMT_ROW_VERSION_CHANGED:
|
||||
strcpy(szSqlState, "01001");
|
||||
/* data truncated */
|
||||
break;
|
||||
case STMT_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case STMT_INFO_ONLY:
|
||||
strcpy(szSqlState, "00000");
|
||||
/* just information that is returned, no error */
|
||||
break;
|
||||
case STMT_BAD_ERROR:
|
||||
strcpy(szSqlState, "08S01");
|
||||
/* communication link failure */
|
||||
break;
|
||||
case STMT_CREATE_TABLE_ERROR:
|
||||
strcpy(szSqlState, "S0001");
|
||||
/* table already exists */
|
||||
break;
|
||||
case STMT_STATUS_ERROR:
|
||||
case STMT_SEQUENCE_ERROR:
|
||||
strcpy(szSqlState, "S1010");
|
||||
/* Function sequence error */
|
||||
break;
|
||||
case STMT_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case STMT_COLNUM_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
/* invalid column number */
|
||||
break;
|
||||
case STMT_NO_STMTSTRING:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* having no stmtstring is also a malloc problem */
|
||||
break;
|
||||
case STMT_ERROR_TAKEN_FROM_BACKEND:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_INTERNAL_ERROR:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case STMT_ROW_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "S1107");
|
||||
break;
|
||||
|
||||
case STMT_OPERATION_CANCELLED:
|
||||
strcpy(szSqlState, "S1008");
|
||||
break;
|
||||
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00"); /* == 'driver not
|
||||
* capable' */
|
||||
break;
|
||||
case STMT_OPTION_OUT_OF_RANGE_ERROR:
|
||||
strcpy(szSqlState, "S1092");
|
||||
break;
|
||||
case STMT_BAD_PARAMETER_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1093");
|
||||
break;
|
||||
case STMT_INVALID_COLUMN_NUMBER_ERROR:
|
||||
strcpy(szSqlState, "S1002");
|
||||
break;
|
||||
case STMT_RESTRICTED_DATA_TYPE_ERROR:
|
||||
strcpy(szSqlState, "07006");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_STATE_ERROR:
|
||||
strcpy(szSqlState, "24000");
|
||||
break;
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_POS_BEFORE_RECORDSET:
|
||||
strcpy(szSqlState, "01S06");
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_NAME:
|
||||
strcpy(szSqlState, "34000");
|
||||
break;
|
||||
case STMT_NO_CURSOR_NAME:
|
||||
strcpy(szSqlState, "S1015");
|
||||
break;
|
||||
case STMT_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case STMT_INVALID_CURSOR_POSITION:
|
||||
strcpy(szSqlState, "S1109");
|
||||
break;
|
||||
case STMT_RETURN_NULL_WITHOUT_INDICATOR:
|
||||
strcpy(szSqlState, "22002");
|
||||
break;
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
case STMT_OPERATION_INVALID:
|
||||
strcpy(szSqlState, "S1011");
|
||||
break;
|
||||
case STMT_INVALID_OPTION_IDENTIFIER:
|
||||
strcpy(szSqlState, "HY092");
|
||||
break;
|
||||
case STMT_EXEC_ERROR:
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* also a general error */
|
||||
break;
|
||||
}
|
||||
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
mylog(" returning NO_DATA_FOUND\n");
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
if (once_again)
|
||||
{
|
||||
int outlen;
|
||||
|
||||
stmt->errornumber = status;
|
||||
if (cbErrorMsgMax > 0)
|
||||
outlen = *pcbErrorMsg;
|
||||
else
|
||||
outlen = 0;
|
||||
if (!stmt->errormsg_malloced || !stmt->errormsg)
|
||||
{
|
||||
stmt->errormsg = malloc(msglen - outlen + 1);
|
||||
stmt->errormsg_malloced = TRUE;
|
||||
}
|
||||
memmove(stmt->errormsg, msg + outlen, msglen - outlen + 1);
|
||||
}
|
||||
else if (stmt->errormsg_malloced)
|
||||
SC_clear_error(stmt);
|
||||
if (cbErrorMsgMax == 0)
|
||||
return SQL_SUCCESS_WITH_INFO;
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
ret = PGAPI_StmtError(hstmt, -1, szSqlState, pfNativeError,
|
||||
szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag);
|
||||
else if (SQL_NULL_HDBC != hdbc)
|
||||
ret = PGAPI_ConnectError(hdbc, -1, szSqlState, pfNativeError,
|
||||
szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag);
|
||||
else if (SQL_NULL_HENV != hdbc)
|
||||
ret = PGAPI_EnvError(henv, -1, szSqlState, pfNativeError,
|
||||
szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag);
|
||||
else
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
mylog("calling CC_get_error\n");
|
||||
if (CC_get_error(conn, &status, &msg))
|
||||
{
|
||||
mylog("CC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg)
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
msglen = strlen(msg);
|
||||
if (NULL != pcbErrorMsg)
|
||||
{
|
||||
*pcbErrorMsg = msglen;
|
||||
if (cbErrorMsgMax == 0)
|
||||
once_again = TRUE;
|
||||
else if (msglen >= cbErrorMsgMax)
|
||||
*pcbErrorMsg = cbErrorMsgMax - 1;
|
||||
}
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (NULL != szSqlState)
|
||||
switch (status)
|
||||
{
|
||||
case STMT_OPTION_VALUE_CHANGED:
|
||||
case CONN_OPTION_VALUE_CHANGED:
|
||||
strcpy(szSqlState, "01S02");
|
||||
break;
|
||||
case STMT_TRUNCATED:
|
||||
case CONN_TRUNCATED:
|
||||
strcpy(szSqlState, "01004");
|
||||
/* data truncated */
|
||||
break;
|
||||
case CONN_INIREAD_ERROR:
|
||||
strcpy(szSqlState, "IM002");
|
||||
/* data source not found */
|
||||
break;
|
||||
case CONN_OPENDB_ERROR:
|
||||
strcpy(szSqlState, "08001");
|
||||
/* unable to connect to data source */
|
||||
break;
|
||||
case CONN_INVALID_AUTHENTICATION:
|
||||
case CONN_AUTH_TYPE_UNSUPPORTED:
|
||||
strcpy(szSqlState, "28000");
|
||||
break;
|
||||
case CONN_STMT_ALLOC_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
/* memory allocation failure */
|
||||
break;
|
||||
case CONN_IN_USE:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
case CONN_UNSUPPORTED_OPTION:
|
||||
strcpy(szSqlState, "IM001");
|
||||
/* driver does not support this function */
|
||||
case CONN_INVALID_ARGUMENT_NO:
|
||||
strcpy(szSqlState, "S1009");
|
||||
/* invalid argument value */
|
||||
break;
|
||||
case CONN_TRANSACT_IN_PROGRES:
|
||||
strcpy(szSqlState, "S1010");
|
||||
|
||||
/*
|
||||
* when the user tries to switch commit mode in a
|
||||
* transaction
|
||||
*/
|
||||
/* -> function sequence error */
|
||||
break;
|
||||
case CONN_NO_MEMORY_ERROR:
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
case CONN_NOT_IMPLEMENTED_ERROR:
|
||||
case STMT_NOT_IMPLEMENTED_ERROR:
|
||||
strcpy(szSqlState, "S1C00");
|
||||
break;
|
||||
case STMT_RETURN_NULL_WITHOUT_INDICATOR:
|
||||
strcpy(szSqlState, "22002");
|
||||
break;
|
||||
case CONN_VALUE_OUT_OF_RANGE:
|
||||
case STMT_VALUE_OUT_OF_RANGE:
|
||||
strcpy(szSqlState, "22003");
|
||||
break;
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog("CC_Get_error returned nothing.\n");
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
if (once_again)
|
||||
{
|
||||
conn->errornumber = status;
|
||||
return SQL_SUCCESS_WITH_INFO;
|
||||
}
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
ret = SQL_NO_DATA_FOUND;
|
||||
}
|
||||
else if (SQL_NULL_HENV != henv)
|
||||
{
|
||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||
|
||||
if (EN_get_error(env, &status, &msg))
|
||||
{
|
||||
mylog("EN_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg)
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = (SWORD) strlen(msg);
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
|
||||
if (NULL != pfNativeError)
|
||||
*pfNativeError = status;
|
||||
|
||||
if (szSqlState)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ENV_ALLOC_ERROR:
|
||||
/* memory allocation failure */
|
||||
strcpy(szSqlState, "S1001");
|
||||
break;
|
||||
default:
|
||||
strcpy(szSqlState, "S1000");
|
||||
/* general error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
if (NULL != szSqlState)
|
||||
strcpy(szSqlState, "00000");
|
||||
if (NULL != pcbErrorMsg)
|
||||
*pcbErrorMsg = 0;
|
||||
if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
|
||||
szErrorMsg[0] = '\0';
|
||||
|
||||
return SQL_NO_DATA_FOUND;
|
||||
mylog("**** PGAPI_Error exit code=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EnvironmentClass implementation
|
||||
*/
|
||||
@ -493,6 +535,7 @@ EN_Constructor(void)
|
||||
{
|
||||
rv->errormsg = 0;
|
||||
rv->errornumber = 0;
|
||||
rv->flag = 0;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -17,7 +17,8 @@
|
||||
struct EnvironmentClass_
|
||||
{
|
||||
char *errormsg;
|
||||
int errornumber;
|
||||
int errornumber;
|
||||
Int4 flag;
|
||||
};
|
||||
|
||||
/* Environment prototypes */
|
||||
@ -28,4 +29,10 @@ char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
|
||||
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
|
||||
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
|
||||
|
||||
#define EN_OV_ODBC2 1L
|
||||
#define EN_is_odbc2(env) ((env->flag & EN_OV_ODBC2) != 0)
|
||||
#define EN_is_odbc3(env) ((env->flag & EN_OV_ODBC2) == 0)
|
||||
#define EN_set_odbc2(env) (env->flag |= EN_OV_ODBC2)
|
||||
#define EN_set_odbc3(env) (env->flag &= EN_OV_ODBC2)
|
||||
|
||||
#endif
|
||||
|
@ -267,6 +267,7 @@ PGAPI_Execute(
|
||||
if (stmt->status == STMT_FINISHED)
|
||||
{
|
||||
mylog("%s: recycling statement (should have been done by app)...\n", func);
|
||||
/******** Is this really NEEDED ? ******/
|
||||
SC_recycle_statement(stmt);
|
||||
}
|
||||
|
||||
@ -291,6 +292,7 @@ PGAPI_Execute(
|
||||
{
|
||||
if (stmt->options.param_processed_ptr)
|
||||
*stmt->options.param_processed_ptr = 0;
|
||||
SC_recycle_statement(stmt);
|
||||
}
|
||||
|
||||
next_param_row:
|
||||
@ -434,26 +436,24 @@ next_param_row:
|
||||
}
|
||||
/* we are now in a transaction */
|
||||
CC_set_in_trans(conn);
|
||||
stmt->result = res = CC_send_query(conn, stmt->stmt_with_params, NULL);
|
||||
if (!res || QR_aborted(res))
|
||||
res = CC_send_query(conn, stmt->stmt_with_params, NULL, TRUE);
|
||||
if (!res)
|
||||
{
|
||||
CC_abort(conn);
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
stmt->errormsg = "Handle prepare error";
|
||||
return SQL_ERROR;
|
||||
}
|
||||
else
|
||||
SC_set_Result(stmt, res);
|
||||
if (CC_is_in_autocommit(conn))
|
||||
{
|
||||
if (CC_is_in_autocommit(conn))
|
||||
{
|
||||
if (issued_begin)
|
||||
CC_commit(conn);
|
||||
else if (!in_trans && begin_included)
|
||||
CC_set_no_trans(conn);
|
||||
}
|
||||
stmt->status = STMT_FINISHED;
|
||||
return SQL_SUCCESS;
|
||||
if (issued_begin)
|
||||
CC_commit(conn);
|
||||
else if (!in_trans && begin_included)
|
||||
CC_set_no_trans(conn);
|
||||
}
|
||||
stmt->status = STMT_FINISHED;
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
@ -518,7 +518,7 @@ PGAPI_Transact(
|
||||
{
|
||||
mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string);
|
||||
|
||||
res = CC_send_query(conn, stmt_string, NULL);
|
||||
res = CC_send_query(conn, stmt_string, NULL, TRUE);
|
||||
CC_set_no_trans(conn);
|
||||
|
||||
if (!res)
|
||||
@ -721,7 +721,7 @@ PGAPI_ParamData(
|
||||
/* commit transaction if needed */
|
||||
if (!ci->drivers.use_declarefetch && CC_is_in_autocommit(stmt->hdbc))
|
||||
{
|
||||
if (!CC_commit(stmt->hdbc))
|
||||
if (CC_commit(stmt->hdbc))
|
||||
{
|
||||
stmt->errormsg = "Could not commit (in-line) a transaction";
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
@ -902,6 +902,14 @@ PGAPI_PutData(
|
||||
}
|
||||
else
|
||||
{
|
||||
Int2 ctype = current_param->CType;
|
||||
if (ctype == SQL_C_DEFAULT)
|
||||
ctype = sqltype_to_default_ctype(current_param->SQLType);
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (SQL_NTS == cbValue && SQL_C_WCHAR == ctype)
|
||||
cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
/* for handling fields */
|
||||
if (cbValue == SQL_NTS)
|
||||
{
|
||||
@ -916,11 +924,11 @@ PGAPI_PutData(
|
||||
}
|
||||
else
|
||||
{
|
||||
Int2 ctype = current_param->CType;
|
||||
|
||||
if (ctype == SQL_C_DEFAULT)
|
||||
ctype = sqltype_to_default_ctype(current_param->SQLType);
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY || ctype == SQL_C_WCHAR)
|
||||
#else
|
||||
if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY)
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
{
|
||||
current_param->EXEC_buffer = malloc(cbValue + 1);
|
||||
if (!current_param->EXEC_buffer)
|
||||
@ -965,31 +973,31 @@ PGAPI_PutData(
|
||||
}
|
||||
else
|
||||
{
|
||||
Int2 ctype = current_param->CType;
|
||||
|
||||
if (ctype == SQL_C_DEFAULT)
|
||||
ctype = sqltype_to_default_ctype(current_param->SQLType);
|
||||
buffer = current_param->EXEC_buffer;
|
||||
|
||||
if (cbValue == SQL_NTS)
|
||||
if (old_pos = *current_param->EXEC_used, SQL_NTS == old_pos)
|
||||
{
|
||||
buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1);
|
||||
if (!buffer)
|
||||
{
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Out of memory in PGAPI_PutData (3)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
strcat(buffer, rgbValue);
|
||||
|
||||
mylog(" cbValue = SQL_NTS: strlen(buffer) = %d\n", strlen(buffer));
|
||||
|
||||
*current_param->EXEC_used = cbValue;
|
||||
|
||||
/* reassign buffer incase realloc moved it */
|
||||
current_param->EXEC_buffer = buffer;
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (SQL_C_WCHAR == ctype)
|
||||
old_pos = 2 * ucs2strlen((SQLWCHAR *) buffer);
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
old_pos = strlen(buffer);
|
||||
}
|
||||
else if (cbValue > 0)
|
||||
if (SQL_NTS == cbValue)
|
||||
{
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (SQL_C_WCHAR == ctype)
|
||||
cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
cbValue = strlen(rgbValue);
|
||||
}
|
||||
if (cbValue > 0)
|
||||
{
|
||||
old_pos = *current_param->EXEC_used;
|
||||
|
||||
*current_param->EXEC_used += cbValue;
|
||||
|
||||
mylog(" cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
{
|
||||
static char *func = "PGAPI_GetInfo30";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnInfo *ci = &(conn->connInfo);
|
||||
char *p = NULL;
|
||||
int len = 0,
|
||||
value = 0;
|
||||
@ -50,35 +51,60 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
| SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK
|
||||
| SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION
|
||||
| SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
|
||||
| SQL_CA1_POS_REFRESH
|
||||
/* | SQL_CA1_BULK_ADD
|
||||
| SQL_CA1_POS_REFRESH;
|
||||
if (ci->drivers.lie)
|
||||
value |=
|
||||
( SQL_CA1_BULK_ADD
|
||||
| SQL_CA1_BULK_UPDATE_BY_BOOKMARK
|
||||
| SQL_CA1_BULK_DELETE_BY_BOOKMARK
|
||||
| SQL_CA1_BULK_FETCH_BY_BOOKMARK */
|
||||
;
|
||||
| SQL_CA1_BULK_FETCH_BY_BOOKMARK
|
||||
|
||||
| SQL_CA1_LOCK_EXCLUSIVE
|
||||
| SQL_CA1_LOCK_UNLOCK
|
||||
| SQL_CA1_POSITIONED_UPDATE
|
||||
| SQL_CA1_POSITIONED_DELETE
|
||||
| SQL_CA1_SELECT_FOR_UPDATE
|
||||
);
|
||||
break;
|
||||
case SQL_KEYSET_CURSOR_ATTRIBUTES2:
|
||||
len = 4;
|
||||
value = SQL_CA2_OPT_ROWVER_CONCURRENCY |
|
||||
SQL_CA2_SENSITIVITY_ADDITIONS |
|
||||
SQL_CA2_SENSITIVITY_DELETIONS |
|
||||
SQL_CA2_SENSITIVITY_UPDATES;
|
||||
value = SQL_CA2_OPT_ROWVER_CONCURRENCY
|
||||
| SQL_CA2_SENSITIVITY_ADDITIONS
|
||||
| SQL_CA2_SENSITIVITY_DELETIONS
|
||||
| SQL_CA2_SENSITIVITY_UPDATES;
|
||||
if (ci->drivers.lie)
|
||||
value |=
|
||||
( SQL_CA2_READ_ONLY_CONCURRENCY
|
||||
| SQL_CA2_LOCK_CONCURRENCY
|
||||
| SQL_CA2_OPT_VALUES_CONCURRENCY
|
||||
| SQL_CA2_MAX_ROWS_SELECT
|
||||
| SQL_CA2_MAX_ROWS_INSERT
|
||||
| SQL_CA2_MAX_ROWS_DELETE
|
||||
| SQL_CA2_MAX_ROWS_UPDATE
|
||||
| SQL_CA2_MAX_ROWS_CATALOG
|
||||
| SQL_CA2_MAX_ROWS_AFFECTS_ALL
|
||||
| SQL_CA2_CRC_EXACT
|
||||
| SQL_CA2_CRC_APPROXIMATE
|
||||
| SQL_CA2_SIMULATE_NON_UNIQUE
|
||||
| SQL_CA2_SIMULATE_TRY_UNIQUE
|
||||
| SQL_CA2_SIMULATE_UNIQUE
|
||||
);
|
||||
break;
|
||||
|
||||
case SQL_STATIC_CURSOR_ATTRIBUTES1:
|
||||
len = 4;
|
||||
value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
|
||||
SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK |
|
||||
SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
|
||||
SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE |
|
||||
SQL_CA1_POS_REFRESH;
|
||||
value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE
|
||||
| SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK
|
||||
| SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION
|
||||
| SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
|
||||
| SQL_CA1_POS_REFRESH;
|
||||
break;
|
||||
case SQL_STATIC_CURSOR_ATTRIBUTES2:
|
||||
len = 4;
|
||||
value = SQL_CA2_OPT_ROWVER_CONCURRENCY |
|
||||
SQL_CA2_SENSITIVITY_ADDITIONS |
|
||||
SQL_CA2_SENSITIVITY_DELETIONS |
|
||||
SQL_CA2_SENSITIVITY_UPDATES;
|
||||
value = SQL_CA2_OPT_ROWVER_CONCURRENCY
|
||||
| SQL_CA2_SENSITIVITY_ADDITIONS
|
||||
| SQL_CA2_SENSITIVITY_DELETIONS
|
||||
| SQL_CA2_SENSITIVITY_UPDATES;
|
||||
break;
|
||||
|
||||
case SQL_ODBC_INTERFACE_CONFORMANCE:
|
||||
@ -103,11 +129,11 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
break;
|
||||
case SQL_BATCH_ROW_COUNT:
|
||||
len = 4;
|
||||
value = SQL_BRC_ROLLED_UP | SQL_BRC_EXPLICIT;
|
||||
value = SQL_BRC_EXPLICIT;
|
||||
break;
|
||||
case SQL_BATCH_SUPPORT:
|
||||
len = 4;
|
||||
value = SQL_BS_ROW_COUNT_EXPLICIT;
|
||||
value = SQL_BS_SELECT_EXPLICIT | SQL_BS_ROW_COUNT_EXPLICIT;
|
||||
break;
|
||||
case SQL_CATALOG_NAME:
|
||||
len = 0;
|
||||
@ -194,7 +220,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
len = 4;
|
||||
value = SQL_DT_DROP_TABLE;
|
||||
if (PG_VERSION_GT(conn, 7.2)) /* hopefully */
|
||||
value |= SQL_DT_RESTRICT | SQL_DT_CASCADE;
|
||||
value |= (SQL_DT_RESTRICT | SQL_DT_CASCADE);
|
||||
break;
|
||||
case SQL_DROP_TRANSLATION:
|
||||
len = 4;
|
||||
@ -204,7 +230,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
len = 4;
|
||||
value = SQL_DV_DROP_VIEW;
|
||||
if (PG_VERSION_GT(conn, 7.2)) /* hopefully */
|
||||
value |= SQL_DV_RESTRICT | SQL_DV_CASCADE;
|
||||
value |= (SQL_DV_RESTRICT | SQL_DV_CASCADE);
|
||||
break;
|
||||
case SQL_INDEX_KEYWORDS:
|
||||
len = 4;
|
||||
@ -227,11 +253,11 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
break;
|
||||
case SQL_PARAM_ARRAY_ROW_COUNTS:
|
||||
len = 4;
|
||||
value = SQL_PARC_NO_BATCH;
|
||||
value = SQL_PARC_BATCH;
|
||||
break;
|
||||
case SQL_PARAM_ARRAY_SELECTS:
|
||||
len = 4;
|
||||
value = SQL_PAS_NO_SELECT;
|
||||
value = SQL_PAS_BATCH;
|
||||
break;
|
||||
case SQL_SQL_CONFORMANCE:
|
||||
len = 4;
|
||||
@ -316,6 +342,7 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
return SQL_ERROR;
|
||||
}
|
||||
result = SQL_SUCCESS;
|
||||
mylog("%s: p='%s', len=%d, value=%d, cbMax=%d\n", func, p ? p : "<NULL>", len, value, cbInfoValueMax);
|
||||
if (p)
|
||||
{
|
||||
/* char/binary data */
|
||||
@ -323,6 +350,14 @@ PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
|
||||
|
||||
if (rgbInfoValue)
|
||||
{
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (conn->unicode)
|
||||
{
|
||||
len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2);
|
||||
len *= 2;
|
||||
}
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax);
|
||||
|
||||
if (len >= cbInfoValueMax)
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "psqlodbc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#define MYLOGDIR "c:"
|
||||
#endif
|
||||
extern void mylog(char *fmt,...);
|
||||
#define inolog mylog /* for really temporary debug */
|
||||
|
||||
#else
|
||||
#ifndef WIN32
|
||||
|
@ -16,13 +16,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int PG_CCST; /* Client Charcter Status */
|
||||
|
||||
int PG_SCSC; /* Server Charcter Set (code) */
|
||||
int PG_CCSC; /* Client Charcter Set (code) */
|
||||
unsigned char *PG_SCSS; /* Server Charcter Set (string) */
|
||||
unsigned char *PG_CCSS; /* Client Charcter Set (string) */
|
||||
|
||||
pg_CS CS_Table[] =
|
||||
{
|
||||
{ "SQL_ASCII", SQL_ASCII },
|
||||
@ -78,19 +71,29 @@ pg_ismb(int characterset_code)
|
||||
int
|
||||
pg_CS_code(const unsigned char *characterset_string)
|
||||
{
|
||||
int i = 0, c;
|
||||
int i = 0, c = -1;
|
||||
unsigned len = 0;
|
||||
for(i = 0; CS_Table[i].code != OTHER; i++)
|
||||
{
|
||||
if (strstr(characterset_string,CS_Table[i].name))
|
||||
c = CS_Table[i].code;
|
||||
{
|
||||
if(strlen(CS_Table[i].name) >= len)
|
||||
{
|
||||
len = strlen(CS_Table[i].name);
|
||||
c = CS_Table[i].code;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (c < 0)
|
||||
c = i;
|
||||
return (c);
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
pg_CS_name(const int characterset_code)
|
||||
pg_CS_name(int characterset_code)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
for (i = 0; CS_Table[i].code != OTHER; i++)
|
||||
{
|
||||
if (CS_Table[i].code == characterset_code)
|
||||
@ -242,7 +245,7 @@ pg_CS_stat(int stat,unsigned int character,int characterset_code)
|
||||
|
||||
|
||||
unsigned char *
|
||||
pg_mbschr(const unsigned char *string, unsigned int character)
|
||||
pg_mbschr(int csc, const unsigned char *string, unsigned int character)
|
||||
{
|
||||
int mb_st = 0;
|
||||
unsigned char *s;
|
||||
@ -250,7 +253,7 @@ pg_mbschr(const unsigned char *string, unsigned int character)
|
||||
|
||||
for(;;)
|
||||
{
|
||||
mb_st = pg_CS_stat(mb_st, (unsigned char) *s,PG_CCSC);
|
||||
mb_st = pg_CS_stat(mb_st, (unsigned char) *s, csc);
|
||||
if (mb_st == 0 && (*s == character || *s == 0))
|
||||
break;
|
||||
else
|
||||
@ -260,13 +263,13 @@ pg_mbschr(const unsigned char *string, unsigned int character)
|
||||
}
|
||||
|
||||
int
|
||||
pg_mbslen(const unsigned char *string)
|
||||
pg_mbslen(int csc, const unsigned char *string)
|
||||
{
|
||||
unsigned char *s;
|
||||
int len, cs_stat;
|
||||
for (len = 0, cs_stat = 0, s = (unsigned char *) string; *s != 0; s++)
|
||||
{
|
||||
cs_stat = pg_CS_stat(cs_stat,(unsigned int) *s, PG_CCSC);
|
||||
cs_stat = pg_CS_stat(cs_stat,(unsigned int) *s, csc);
|
||||
if (cs_stat < 2)
|
||||
len++;
|
||||
}
|
||||
@ -274,12 +277,12 @@ pg_mbslen(const unsigned char *string)
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
pg_mbsinc(const unsigned char *current )
|
||||
pg_mbsinc(int csc, const unsigned char *current )
|
||||
{
|
||||
int mb_stat = 0;
|
||||
if (*current != 0)
|
||||
{
|
||||
mb_stat = (int) pg_CS_stat(mb_stat, *current, PG_CCSC);
|
||||
mb_stat = (int) pg_CS_stat(mb_stat, *current, csc);
|
||||
if (mb_stat == 0)
|
||||
mb_stat = 1;
|
||||
return ((unsigned char *) current + mb_stat);
|
||||
@ -288,43 +291,100 @@ pg_mbsinc(const unsigned char *current )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
CC_lookup_cs_new(ConnectionClass *self)
|
||||
{
|
||||
char *encstr = NULL;
|
||||
QResultClass *res;
|
||||
|
||||
res = CC_send_query(self, "select pg_client_encoding()", NULL, TRUE);
|
||||
if (res)
|
||||
{
|
||||
char *enc = QR_get_value_backend_row(res, 0, 0);
|
||||
|
||||
if (enc)
|
||||
encstr = strdup(enc);
|
||||
QR_Destructor(res);
|
||||
}
|
||||
return encstr;
|
||||
}
|
||||
static char *
|
||||
CC_lookup_cs_old(ConnectionClass *self)
|
||||
{
|
||||
char *encstr = NULL;
|
||||
HSTMT hstmt;
|
||||
RETCODE result;
|
||||
|
||||
result = PGAPI_AllocStmt(self, &hstmt);
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
|
||||
return encstr;
|
||||
|
||||
result = PGAPI_ExecDirect(hstmt, "Show Client_Encoding", SQL_NTS);
|
||||
if (result == SQL_SUCCESS_WITH_INFO)
|
||||
{
|
||||
char sqlState[8], errormsg[128], enc[32];
|
||||
|
||||
if (PGAPI_Error(NULL, NULL, hstmt, sqlState, NULL, errormsg,
|
||||
sizeof(errormsg), NULL) == SQL_SUCCESS &&
|
||||
sscanf(errormsg, "%*s %*s %*s %*s %*s %s", enc) > 0)
|
||||
encstr = strdup(enc);
|
||||
}
|
||||
PGAPI_FreeStmt(hstmt, SQL_DROP);
|
||||
return encstr;
|
||||
}
|
||||
|
||||
void
|
||||
CC_lookup_characterset(ConnectionClass *self)
|
||||
{
|
||||
HSTMT hstmt;
|
||||
StatementClass *stmt;
|
||||
RETCODE result;
|
||||
char *encstr;
|
||||
static char *func = "CC_lookup_characterset";
|
||||
|
||||
mylog("%s: entering...\n", func);
|
||||
PG_SCSS = malloc(MAX_CHARACTERSET_NAME);
|
||||
PG_CCSS = malloc(MAX_CHARACTERSET_NAME);
|
||||
|
||||
result = PGAPI_AllocStmt(self, &hstmt);
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
|
||||
return;
|
||||
stmt = (StatementClass *) hstmt;
|
||||
|
||||
result = PGAPI_ExecDirect(hstmt, "Show Client_Encoding", SQL_NTS);
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
|
||||
if (PG_VERSION_LT(self, 7.2))
|
||||
encstr = CC_lookup_cs_old(self);
|
||||
else
|
||||
encstr = CC_lookup_cs_new(self);
|
||||
if (self->client_encoding)
|
||||
free(self->client_encoding);
|
||||
if (encstr)
|
||||
{
|
||||
PGAPI_FreeStmt(hstmt, SQL_DROP);
|
||||
return;
|
||||
self->client_encoding = encstr;
|
||||
self->ccsc = pg_CS_code(encstr);
|
||||
qlog(" [ Client encoding = '%s' (code = %d) ]\n", self->client_encoding, self->ccsc);
|
||||
if (stricmp(pg_CS_name(self->ccsc), encstr))
|
||||
{
|
||||
qlog(" Client encoding = '%s' and %s\n", self->client_encoding, pg_CS_name(self->ccsc));
|
||||
self->errornumber = CONN_VALUE_OUT_OF_RANGE;
|
||||
self->errormsg = "client encoding mismatch";
|
||||
}
|
||||
}
|
||||
result = PGAPI_AllocStmt(self, &hstmt);
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
|
||||
return;
|
||||
stmt = (StatementClass *) hstmt;
|
||||
|
||||
result = PGAPI_ExecDirect(hstmt, "Show Server_Encoding", SQL_NTS);
|
||||
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
|
||||
else
|
||||
{
|
||||
PGAPI_FreeStmt(hstmt, SQL_DROP);
|
||||
return;
|
||||
self->ccsc = SQL_ASCII;
|
||||
self->client_encoding = NULL;
|
||||
}
|
||||
|
||||
strcpy(PG_SCSS , pg_CS_name(PG_SCSC = pg_CS_code(PG_SCSS)));
|
||||
strcpy(PG_CCSS , pg_CS_name(PG_CCSC = pg_CS_code(PG_CCSS)));
|
||||
|
||||
qlog(" [ Server encoding = '%s' (code = %d), Client encoding = '%s' (code = %d) ]\n", PG_SCSS, PG_SCSC, PG_CCSS, PG_CCSC);
|
||||
}
|
||||
|
||||
void encoded_str_constr(encoded_str *encstr, int ccsc, const char *str)
|
||||
{
|
||||
encstr->ccsc = ccsc;
|
||||
encstr->encstr = str;
|
||||
encstr->pos = -1;
|
||||
encstr->ccst = 0;
|
||||
}
|
||||
int encoded_nextchar(encoded_str *encstr)
|
||||
{
|
||||
int chr;
|
||||
|
||||
chr = encstr->encstr[++encstr->pos];
|
||||
encstr->ccst = pg_CS_stat(encstr->ccst, (unsigned int) chr, encstr->ccsc);
|
||||
return chr;
|
||||
}
|
||||
int encoded_byte_check(encoded_str *encstr, int abspos)
|
||||
{
|
||||
int chr;
|
||||
|
||||
chr = encstr->encstr[encstr->pos = abspos];
|
||||
encstr->ccst = pg_CS_stat(encstr->ccst, (unsigned int) chr, encstr->ccsc);
|
||||
return chr;
|
||||
}
|
||||
|
@ -4,13 +4,14 @@
|
||||
*
|
||||
*/
|
||||
#include "psqlodbc.h"
|
||||
#include "qresult.h"
|
||||
|
||||
/* PostgreSQL client encoding */
|
||||
#define SQL_ASCII 0 /* SQL/ASCII */
|
||||
#define EUC_JP 1 /* EUC for Japanese */
|
||||
#define EUC_CN 2 /* EUC for Chinese */
|
||||
#define EUC_KR 3 /* EUC for Korean */
|
||||
#define EUC_TW 4 /* EUC for Taiwan */
|
||||
#define EUC_TW 4 /* EUC for Taiwan */
|
||||
#define JOHAB 5
|
||||
#define UTF8 6 /* Unicode UTF-8 */
|
||||
#define MULE_INTERNAL 7 /* Mule internal code */
|
||||
@ -22,66 +23,67 @@
|
||||
#define LATIN6 13 /* ISO-8859 Latin 6 */
|
||||
#define LATIN7 14 /* ISO-8859 Latin 7 */
|
||||
#define LATIN8 15 /* ISO-8859 Latin 8 */
|
||||
#define LATIN9 16 /* ISO-8859 Latin 9 */
|
||||
#define LATIN10 17 /* ISO-8859 Latin 10 */
|
||||
#define WIN1256 18 /* Arabic Windows */
|
||||
#define TCVN 19 /* Vietnamese Windows */
|
||||
#define WIN874 20 /* Thai Windows */
|
||||
#define KOI8R 21 /* KOI8-R/U */
|
||||
#define LATIN9 16 /* ISO-8859 Latin 9 */
|
||||
#define LATIN10 17 /* ISO-8859 Latin 10 */
|
||||
#define WIN1256 18 /* Arabic Windows */
|
||||
#define TCVN 19 /* Vietnamese Windows */
|
||||
#define WIN874 20 /* Thai Windows */
|
||||
#define KOI8R 21 /* KOI8-R/U */
|
||||
#define WIN1251 22 /* windows-1251 */
|
||||
#define ALT 23 /* Alternativny Variant (MS-DOS CP866) */
|
||||
#define ISO_8859_5 24 /* ISO-8859-5 */
|
||||
#define ISO_8859_6 25 /* ISO-8859-6 */
|
||||
#define ISO_8859_7 26 /* ISO-8859-7 */
|
||||
#define ISO_8859_8 27 /* ISO-8859-8 */
|
||||
|
||||
#define SJIS 28 /* Shift JIS */
|
||||
#define BIG5 29 /* Big5 */
|
||||
#define GBK 30 /* GBK */
|
||||
#define UHC 31 /* UHC */
|
||||
#define WIN1250 32 /* windows-1250 */
|
||||
#define OTHER -1
|
||||
|
||||
#define MAX_CHARACTERSET_NAME 24
|
||||
#define MAX_CHARACTER_LEN 6
|
||||
#define ISO_8859_5 24 /* ISO-8859-5 */
|
||||
#define ISO_8859_6 25 /* ISO-8859-6 */
|
||||
#define ISO_8859_7 26 /* ISO-8859-7 */
|
||||
#define ISO_8859_8 27 /* ISO-8859-8 */
|
||||
|
||||
/* OLD Type */
|
||||
#define SJIS 28 /* Shift JIS */
|
||||
#define BIG5 29 /* Big5 */
|
||||
#define GBK 30 /* GBK */
|
||||
#define UHC 31 /* UHC */
|
||||
#define WIN1250 32 /* windows-1250 */
|
||||
#define OTHER -1
|
||||
|
||||
#define MAX_CHARACTERSET_NAME 24
|
||||
#define MAX_CHARACTER_LEN 6
|
||||
|
||||
/* OLD Type */
|
||||
// extern int multibyte_client_encoding; /* Multibyte client encoding. */
|
||||
// extern int multibyte_status; /* Multibyte charcter status. */
|
||||
//
|
||||
// void multibyte_init(void);
|
||||
// unsigned char *check_client_encoding(unsigned char *sql_string);
|
||||
// int multibyte_char_check(unsigned char s);
|
||||
// unsigned char *multibyte_strchr(const unsigned char *string, unsigned int c);
|
||||
|
||||
/* New Type */
|
||||
|
||||
extern int PG_CCST; /* Client Character StaTus */
|
||||
|
||||
extern int PG_SCSC; /* Server Character Set (Code) */
|
||||
extern int PG_CCSC; /* Client Character Set (Code) */
|
||||
extern unsigned char *PG_SCSS; /* Server Character Set (String) */
|
||||
extern unsigned char *PG_CCSS; /* Client Character Set (String) */
|
||||
|
||||
extern void CC_lookup_characterset(ConnectionClass *self);
|
||||
|
||||
extern int pg_CS_stat(int stat,unsigned int charcter,int characterset_code);
|
||||
extern int pg_CS_code(const unsigned char *stat_string);
|
||||
extern unsigned char *pg_CS_name(const int code);
|
||||
|
||||
typedef struct pg_CS
|
||||
{
|
||||
unsigned char *name;
|
||||
int code;
|
||||
}pg_CS;
|
||||
extern pg_CS CS_Table[];
|
||||
|
||||
extern int pg_mbslen(const unsigned char *string);
|
||||
extern unsigned char *pg_mbschr(const unsigned char *string, unsigned int character);
|
||||
extern unsigned char *pg_mbsinc( const unsigned char *current );
|
||||
|
||||
/* Old Type Compatible */
|
||||
#define multibyte_init() (PG_CCST = 0)
|
||||
#define multibyte_char_check(X) pg_CS_stat(PG_CCST, (unsigned int) X, PG_CCSC)
|
||||
#define multibyte_strchr(X,Y) pg_mbschr(X,Y)
|
||||
#define check_client_encoding(X) pg_CS_name(PG_CCSC = pg_CS_code(X))
|
||||
// unsigned char *multibyte_strchr(const unsigned char *string, unsigned int c);
|
||||
|
||||
/* New Type */
|
||||
|
||||
extern void CC_lookup_characterset(ConnectionClass *self);
|
||||
|
||||
extern int pg_CS_stat(int stat,unsigned int charcter,int characterset_code);
|
||||
extern int pg_CS_code(const unsigned char *stat_string);
|
||||
extern unsigned char *pg_CS_name(int code);
|
||||
|
||||
typedef struct pg_CS
|
||||
{
|
||||
unsigned char *name;
|
||||
int code;
|
||||
}pg_CS;
|
||||
extern int pg_mbslen(int ccsc, const unsigned char *string);
|
||||
extern unsigned char *pg_mbschr(int ccsc, const unsigned char *string, unsigned int character);
|
||||
extern unsigned char *pg_mbsinc(int ccsc, const unsigned char *current );
|
||||
|
||||
/* Old Type Compatible */
|
||||
typedef struct
|
||||
{
|
||||
int ccsc;
|
||||
const char *encstr;
|
||||
int pos;
|
||||
int ccst;
|
||||
} encoded_str;
|
||||
#define ENCODE_STATUS(enc) ((enc).ccst)
|
||||
|
||||
void encoded_str_constr(encoded_str *encstr, int ccsc, const char *str);
|
||||
#define make_encoded_str(encstr, conn, str) encoded_str_constr(encstr, conn->ccsc, str)
|
||||
extern int encoded_nextchar(encoded_str *encstr);
|
||||
extern int encoded_byte_check(encoded_str *encstr, int abspos);
|
||||
#define check_client_encoding(X) pg_CS_name(pg_CS_code(X))
|
||||
|
@ -174,7 +174,8 @@ SQLError(HENV EnvironmentHandle,
|
||||
{
|
||||
mylog("[SQLError]");
|
||||
return PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle,
|
||||
Sqlstate, NativeError, MessageText, BufferLength, TextLength);
|
||||
Sqlstate, NativeError, MessageText, BufferLength,
|
||||
TextLength);
|
||||
}
|
||||
|
||||
RETCODE SQL_API
|
||||
@ -281,23 +282,31 @@ SQLGetInfo(HDBC ConnectionHandle,
|
||||
SQLUSMALLINT InfoType, PTR InfoValue,
|
||||
SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
|
||||
{
|
||||
#if (ODBCVER >= 0x0300)
|
||||
RETCODE ret;
|
||||
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
|
||||
|
||||
CC_clear_error(conn);
|
||||
#if (ODBCVER >= 0x0300)
|
||||
mylog("[SQLGetInfo(30)]");
|
||||
if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength)) == SQL_ERROR)
|
||||
{
|
||||
if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300)
|
||||
return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
|
||||
{
|
||||
CC_clear_error(conn);
|
||||
ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
if (SQL_ERROR == ret)
|
||||
CC_log_error("SQLGetInfo30", "", conn);
|
||||
#else
|
||||
mylog("[SQLGetInfo]");
|
||||
return PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength);
|
||||
if (ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength), SQL_ERROR == ret)
|
||||
CC_log_error("PGAPI_GetInfo", "", conn);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
RETCODE SQL_API
|
||||
@ -638,7 +647,7 @@ SQLTablePrivileges(
|
||||
{
|
||||
mylog("[SQLTablePrivileges]");
|
||||
return PGAPI_TablePrivileges(hstmt, szCatalogName, cbCatalogName,
|
||||
szSchemaName, cbSchemaName, szTableName, cbTableName);
|
||||
szSchemaName, cbSchemaName, szTableName, cbTableName, 0);
|
||||
}
|
||||
|
||||
RETCODE SQL_API
|
||||
|
@ -25,22 +25,27 @@ RETCODE SQL_API SQLErrorW(HENV EnvironmentHandle,
|
||||
SQLSMALLINT *TextLength)
|
||||
{
|
||||
RETCODE ret;
|
||||
SWORD tlen;
|
||||
SWORD tlen, buflen;
|
||||
char *qst = NULL, *mtxt = NULL;
|
||||
|
||||
mylog("[SQLErrorW]");
|
||||
if (Sqlstate)
|
||||
qst = malloc(8);
|
||||
if (MessageText)
|
||||
mtxt = malloc(BufferLength);
|
||||
buflen = 0;
|
||||
if (MessageText && BufferLength > 0)
|
||||
{
|
||||
buflen = BufferLength * 3 + 1;
|
||||
mtxt = malloc(buflen);
|
||||
}
|
||||
ret = PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle,
|
||||
qst, NativeError, mtxt, BufferLength, &tlen);
|
||||
qst, NativeError, mtxt, buflen, &tlen);
|
||||
if (qst)
|
||||
utf8_to_ucs2(qst, strlen(qst), Sqlstate, 5);
|
||||
if (TextLength)
|
||||
*TextLength = utf8_to_ucs2(mtxt, tlen, MessageText, BufferLength);
|
||||
free(qst);
|
||||
free(mtxt);
|
||||
if (mtxt)
|
||||
free(mtxt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -56,6 +61,7 @@ RETCODE SQL_API SQLSetConnectOptionW(HDBC ConnectionHandle,
|
||||
SQLUSMALLINT Option, SQLUINTEGER Value)
|
||||
{
|
||||
mylog("[SQLSetConnectionOptionW]");
|
||||
if (!ConnectionHandle) return SQL_ERROR;
|
||||
((ConnectionClass *) ConnectionHandle)->unicode = 1;
|
||||
return PGAPI_SetConnectOption(ConnectionHandle, Option, Value);
|
||||
}
|
||||
|
@ -144,9 +144,7 @@ SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return SQL_ERROR; /* SQLSTATE HY092 ("Invalid
|
||||
* attribute/option identifier") */
|
||||
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
/* SQLExtendedFetch -> SQLFetchScroll */
|
||||
@ -246,39 +244,9 @@ SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||
SQLINTEGER *NativeError, SQLCHAR *MessageText,
|
||||
SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
|
||||
{
|
||||
RETCODE ret;
|
||||
|
||||
mylog("[[SQLGetDiagRec]]\n");
|
||||
switch (HandleType)
|
||||
{
|
||||
case SQL_HANDLE_ENV:
|
||||
ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError,
|
||||
MessageText, BufferLength, TextLength);
|
||||
break;
|
||||
case SQL_HANDLE_DBC:
|
||||
ret = PGAPI_Error(NULL, Handle, NULL, Sqlstate, NativeError,
|
||||
MessageText, BufferLength, TextLength);
|
||||
break;
|
||||
case SQL_HANDLE_STMT:
|
||||
ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError,
|
||||
MessageText, BufferLength, TextLength);
|
||||
break;
|
||||
default:
|
||||
ret = SQL_ERROR;
|
||||
}
|
||||
if (ret == SQL_SUCCESS_WITH_INFO &&
|
||||
BufferLength == 0 &&
|
||||
*TextLength)
|
||||
{
|
||||
SQLSMALLINT BufferLength = *TextLength + 4;
|
||||
SQLCHAR *MessageText = malloc(BufferLength);
|
||||
|
||||
ret = SQLGetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
|
||||
NativeError, MessageText, BufferLength,
|
||||
TextLength);
|
||||
free(MessageText);
|
||||
}
|
||||
return ret;
|
||||
return PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
|
||||
NativeError, MessageText, BufferLength, TextLength);
|
||||
}
|
||||
|
||||
/* new function */
|
||||
@ -299,7 +267,7 @@ SQLGetEnvAttr(HENV EnvironmentHandle,
|
||||
*((unsigned int *) Value) = SQL_CP_RELAXED_MATCH;
|
||||
break;
|
||||
case SQL_ATTR_ODBC_VERSION:
|
||||
*((unsigned int *) Value) = SQL_OV_ODBC3;
|
||||
*((unsigned int *) Value) = EN_is_odbc2(env) ? SQL_OV_ODBC2 : SQL_OV_ODBC3;
|
||||
break;
|
||||
case SQL_ATTR_OUTPUT_NTS:
|
||||
*((unsigned int *) Value) = SQL_TRUE;
|
||||
@ -456,6 +424,7 @@ ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
|
||||
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
|
||||
{
|
||||
RETCODE ret = SQL_SUCCESS;
|
||||
PTR tptr;
|
||||
switch (FieldIdentifier)
|
||||
{
|
||||
case SQL_DESC_ARRAY_SIZE:
|
||||
@ -470,8 +439,34 @@ ARDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
|
||||
case SQL_DESC_BIND_TYPE:
|
||||
stmt->options.bind_size = (SQLUINTEGER) Value;
|
||||
break;
|
||||
|
||||
case SQL_DESC_DATA_PTR:
|
||||
if (!RecNumber)
|
||||
stmt->bookmark.buffer = Value;
|
||||
else
|
||||
stmt->bindings[RecNumber - 1].buffer = Value;
|
||||
break;
|
||||
case SQL_DESC_INDICATOR_PTR:
|
||||
if (!RecNumber)
|
||||
tptr = stmt->bookmark.used;
|
||||
else
|
||||
tptr = stmt->bindings[RecNumber - 1].used;
|
||||
if (Value != tptr)
|
||||
{
|
||||
ret = SQL_ERROR;
|
||||
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR";
|
||||
}
|
||||
break;
|
||||
case SQL_DESC_OCTET_LENGTH_PTR:
|
||||
if (!RecNumber)
|
||||
stmt->bookmark.used = Value;
|
||||
else
|
||||
stmt->bindings[RecNumber - 1].used = Value;
|
||||
break;
|
||||
default:ret = SQL_ERROR;
|
||||
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
stmt->errormsg = "not implemedted yet";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -495,6 +490,26 @@ APDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
|
||||
case SQL_DESC_BIND_TYPE:
|
||||
stmt->options.param_bind_type = (SQLUINTEGER) Value;
|
||||
break;
|
||||
|
||||
case SQL_DESC_DATA_PTR:
|
||||
if (stmt->parameters_allocated < RecNumber)
|
||||
PGAPI_BindParameter(stmt, RecNumber, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
stmt->parameters[RecNumber - 1].buffer = Value;
|
||||
break;
|
||||
case SQL_DESC_INDICATOR_PTR:
|
||||
if (stmt->parameters_allocated < RecNumber ||
|
||||
Value != stmt->parameters[RecNumber - 1].used)
|
||||
{
|
||||
ret = SQL_ERROR;
|
||||
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
stmt->errormsg = "INDICATOR != OCTET_LENGTH_PTR";
|
||||
}
|
||||
break;
|
||||
case SQL_DESC_OCTET_LENGTH_PTR:
|
||||
if (stmt->parameters_allocated < RecNumber)
|
||||
PGAPI_BindParameter(stmt, RecNumber, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
stmt->parameters[RecNumber - 1].used = Value;
|
||||
break;
|
||||
default:ret = SQL_ERROR;
|
||||
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
}
|
||||
@ -549,6 +564,8 @@ SQLSetDescField(SQLHDESC DescriptorHandle,
|
||||
HSTMT hstmt;
|
||||
SQLUINTEGER descType;
|
||||
StatementClass *stmt;
|
||||
static const char *func = "SQLSetDescField";
|
||||
|
||||
mylog("[[SQLSetDescField]] h=%u rec=%d field=%d val=%x\n", DescriptorHandle, RecNumber, FieldIdentifier, Value);
|
||||
hstmt = statementHandleFromDescHandle(DescriptorHandle, &descType);
|
||||
mylog("stmt=%x type=%d\n", hstmt, descType);
|
||||
@ -569,8 +586,10 @@ SQLSetDescField(SQLHDESC DescriptorHandle,
|
||||
break;
|
||||
default:ret = SQL_ERROR;
|
||||
stmt->errornumber = STMT_INTERNAL_ERROR;
|
||||
mylog("Error not implemented\n");
|
||||
stmt->errormsg = "Error not implemented";
|
||||
}
|
||||
if (ret == SQL_ERROR)
|
||||
SC_log_error(func, "", stmt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -583,6 +602,8 @@ SQLSetDescRec(SQLHDESC DescriptorHandle,
|
||||
PTR Data, SQLINTEGER *StringLength,
|
||||
SQLINTEGER *Indicator)
|
||||
{
|
||||
const char *func = "SQLSetDescField";
|
||||
|
||||
mylog("[[SQLSetDescRec]]\n");
|
||||
mylog("Error not implemented\n");
|
||||
return SQL_ERROR;
|
||||
@ -608,7 +629,10 @@ SQLSetEnvAttr(HENV EnvironmentHandle,
|
||||
return SQL_SUCCESS;
|
||||
case SQL_ATTR_ODBC_VERSION:
|
||||
if ((SQLUINTEGER) Value == SQL_OV_ODBC2)
|
||||
return SQL_SUCCESS;
|
||||
EN_set_odbc2(env);
|
||||
else
|
||||
EN_set_odbc3(env);
|
||||
return SQL_SUCCESS;
|
||||
break;
|
||||
case SQL_ATTR_OUTPUT_NTS:
|
||||
if ((SQLUINTEGER) Value == SQL_TRUE)
|
||||
@ -652,44 +676,46 @@ SQLSetStmtAttr(HSTMT StatementHandle,
|
||||
* case SQL_ATTR_PREDICATE_PTR: case
|
||||
* SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
|
||||
*/
|
||||
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
|
||||
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
|
||||
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
|
||||
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
stmt->errormsg = "Unsupported statement option (Set)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
|
||||
stmt->options.param_offset_ptr = (SQLUINTEGER *) Value;
|
||||
break;
|
||||
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
|
||||
stmt->options.row_offset_ptr = (SQLUINTEGER *) Value;
|
||||
break;
|
||||
|
||||
case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
|
||||
stmt->options.bookmark_ptr = Value;
|
||||
break;
|
||||
case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
|
||||
stmt->options.param_offset_ptr = (SQLUINTEGER *) Value;
|
||||
break;
|
||||
case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
|
||||
stmt->options.param_bind_type = (SQLUINTEGER) Value;
|
||||
break;
|
||||
case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
|
||||
stmt->options.param_operation_ptr = Value;
|
||||
break;
|
||||
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
|
||||
stmt->options.param_status_ptr = (SQLUSMALLINT *) Value;
|
||||
break;
|
||||
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
|
||||
stmt->options.param_processed_ptr = (SQLUINTEGER *) Value;
|
||||
break;
|
||||
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
|
||||
stmt->options.paramset_size = (SQLUINTEGER) Value;
|
||||
break;
|
||||
case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
|
||||
stmt->options.row_offset_ptr = (SQLUINTEGER *) Value;
|
||||
break;
|
||||
case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
|
||||
stmt->options.row_operation_ptr = Value;
|
||||
break;
|
||||
case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
|
||||
stmt->options.rowStatusArray = (SQLUSMALLINT *) Value;
|
||||
|
||||
break;
|
||||
case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
|
||||
stmt->options.rowsFetched = (SQLUINTEGER *) Value;
|
||||
|
||||
break;
|
||||
case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
|
||||
stmt->options.rowset_size = (SQLUINTEGER) Value;
|
||||
|
||||
break;
|
||||
default:
|
||||
return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value);
|
||||
@ -704,7 +730,7 @@ SQLSetStmtAttr(HSTMT StatementHandle,
|
||||
RETCODE SQL_API
|
||||
PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnInfo *ci = &(conn->connInfo);
|
||||
|
||||
if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS)
|
||||
@ -755,17 +781,14 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */
|
||||
|
||||
/*
|
||||
* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50
|
||||
* deprecated
|
||||
*/
|
||||
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */
|
||||
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */
|
||||
if (ci->drivers.lie)
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implmented yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 not implemented yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 */
|
||||
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); 59 deprecated */
|
||||
@ -781,12 +804,11 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
|
||||
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */
|
||||
if (ci->drivers.lie)
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 not implmented yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 not implemeted yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES); /* 67 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); /* 69 deprecated */
|
||||
if (ci->drivers.lie)
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 not implemented yet */
|
||||
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); 69 deprecated */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 */
|
||||
/* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */ /* 71 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */
|
||||
|
||||
@ -801,7 +823,7 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
|
||||
if (ci->drivers.lie)
|
||||
{
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD); /* 1008 not implemented yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC); /* 1009 not implemented yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC); /* 1009 not implemented yet */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD); /* 1010 not implemented yet */
|
||||
}
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC); /* 1011 */
|
||||
@ -810,7 +832,9 @@ PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR * pfExists)
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 */
|
||||
if (ci->drivers.lie)
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */
|
||||
{
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */
|
||||
}
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR); /* 1019 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */
|
||||
SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */
|
||||
|
@ -85,22 +85,37 @@ RETCODE SQL_API SQLGetDiagRecW(SWORD fHandleType,
|
||||
SQLSMALLINT *pcbErrorMsg)
|
||||
{
|
||||
RETCODE ret;
|
||||
SWORD tlen;
|
||||
char *qst = NULL, *mtxt = NULL;
|
||||
SWORD buflen, tlen;
|
||||
char *qstr = NULL, *mtxt = NULL;
|
||||
|
||||
mylog("[SQLGetDiagRecW]");
|
||||
if (szSqlState)
|
||||
qst = malloc(8);
|
||||
if (szErrorMsg)
|
||||
mtxt = malloc(cbErrorMsgMax);
|
||||
ret = PGAPI_GetDiagRec(fHandleType, handle, iRecord, qst,
|
||||
pfNativeError, mtxt, cbErrorMsgMax, &tlen);
|
||||
if (qst)
|
||||
utf8_to_ucs2(qst, strlen(qst), szSqlState, 5);
|
||||
if (pcbErrorMsg)
|
||||
*pcbErrorMsg = utf8_to_ucs2(mtxt, tlen, szErrorMsg, cbErrorMsgMax);
|
||||
free(qst);
|
||||
free(mtxt);
|
||||
qstr = malloc(8);
|
||||
buflen = 0;
|
||||
if (szErrorMsg && cbErrorMsgMax > 0)
|
||||
{
|
||||
buflen = cbErrorMsgMax;
|
||||
mtxt = malloc(buflen);
|
||||
}
|
||||
ret = PGAPI_GetDiagRec(fHandleType, handle, iRecord, qstr,
|
||||
pfNativeError, mtxt, buflen, &tlen);
|
||||
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
|
||||
{
|
||||
if (qstr)
|
||||
utf8_to_ucs2(qstr, strlen(qstr), szSqlState, 6);
|
||||
if (mtxt && tlen <= cbErrorMsgMax)
|
||||
{
|
||||
tlen = utf8_to_ucs2(mtxt, tlen, szErrorMsg, cbErrorMsgMax);
|
||||
if (tlen >= cbErrorMsgMax)
|
||||
ret = SQL_SUCCESS_WITH_INFO;
|
||||
}
|
||||
if (pcbErrorMsg)
|
||||
*pcbErrorMsg = tlen;
|
||||
}
|
||||
if (qstr);
|
||||
free(qstr);
|
||||
if (mtxt)
|
||||
free(mtxt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
SQLPrepareW, SQLPrimaryKeysW, SQLProcedureColumnsW,
|
||||
SQLProceduresW, SQLSetCursorNameW,
|
||||
SQLSpecialColumnsW, SQLStatisticsW, SQLTablesW,
|
||||
SQLTablePrivilegesW
|
||||
SQLTablePrivilegesW, SQLGetTypeInfoW
|
||||
*-------
|
||||
*/
|
||||
|
||||
@ -102,7 +102,11 @@ RETCODE SQL_API SQLDriverConnectW(HDBC hdbc,
|
||||
ret = PGAPI_DriverConnect(hdbc, hwnd, szIn, (SWORD) inlen,
|
||||
szOut, cbConnStrOutMax, &olen, fDriverCompletion);
|
||||
if (ret != SQL_ERROR)
|
||||
*pcbConnStrOut = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
|
||||
{
|
||||
UInt4 outlen = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
|
||||
if (pcbConnStrOut)
|
||||
*pcbConnStrOut = outlen;
|
||||
}
|
||||
free(szOut);
|
||||
if (szIn);
|
||||
free(szIn);
|
||||
@ -129,7 +133,11 @@ RETCODE SQL_API SQLBrowseConnectW(
|
||||
ret = PGAPI_BrowseConnect(hdbc, szIn, (SWORD) inlen,
|
||||
szOut, cbConnStrOutMax, &olen);
|
||||
if (ret != SQL_ERROR)
|
||||
*pcbConnStrOut = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
|
||||
{
|
||||
UInt4 outlen = utf8_to_ucs2(szOut, olen, szConnStrOut, cbConnStrOutMax);
|
||||
if (pcbConnStrOut)
|
||||
*pcbConnStrOut = outlen;
|
||||
}
|
||||
free(szOut);
|
||||
if (szIn);
|
||||
free(szIn);
|
||||
@ -158,15 +166,28 @@ RETCODE SQL_API SQLDescribeColW(HSTMT StatementHandle,
|
||||
SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
|
||||
{
|
||||
RETCODE ret;
|
||||
SWORD nmlen;
|
||||
SWORD buflen, nmlen;
|
||||
char *clName;
|
||||
|
||||
mylog("[SQLDescribeColW]");
|
||||
clName = malloc(BufferLength);
|
||||
buflen = BufferLength * 3 + 1;
|
||||
clName = malloc(buflen);
|
||||
ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber,
|
||||
clName, BufferLength, &nmlen,
|
||||
DataType, ColumnSize, DecimalDigits, Nullable);
|
||||
*NameLength = utf8_to_ucs2(clName, nmlen, ColumnName, BufferLength);
|
||||
clName, buflen, &nmlen, DataType, ColumnSize,
|
||||
DecimalDigits, Nullable);
|
||||
if (ret == SQL_SUCCESS)
|
||||
{
|
||||
UInt4 nmcount = utf8_to_ucs2(clName, nmlen, ColumnName, BufferLength);
|
||||
if (nmcount > (UInt4) BufferLength)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) StatementHandle;
|
||||
ret = SQL_SUCCESS_WITH_INFO;
|
||||
stmt->errornumber = STMT_TRUNCATED;
|
||||
stmt->errormsg = "Column name too large";
|
||||
}
|
||||
if (NameLength)
|
||||
*NameLength = nmcount;
|
||||
}
|
||||
free(clName);
|
||||
return ret;
|
||||
}
|
||||
@ -192,13 +213,25 @@ RETCODE SQL_API SQLGetCursorNameW(HSTMT StatementHandle,
|
||||
{
|
||||
RETCODE ret;
|
||||
char *crName;
|
||||
SWORD clen;
|
||||
SWORD clen, buflen;
|
||||
|
||||
mylog("[SQLGetCursorNameW]");
|
||||
crName = malloc(BufferLength);
|
||||
ret = PGAPI_GetCursorName(StatementHandle, crName, BufferLength,
|
||||
&clen);
|
||||
*NameLength = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength);
|
||||
buflen = BufferLength * 3 + 1;
|
||||
crName = malloc(buflen);
|
||||
ret = PGAPI_GetCursorName(StatementHandle, crName, buflen, &clen);
|
||||
if (ret == SQL_SUCCESS)
|
||||
{
|
||||
UInt4 nmcount = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength);
|
||||
if (nmcount > (UInt4) BufferLength)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) StatementHandle;
|
||||
ret = SQL_SUCCESS_WITH_INFO;
|
||||
stmt->errornumber = STMT_TRUNCATED;
|
||||
stmt->errormsg = "Cursor name too large";
|
||||
}
|
||||
if (NameLength)
|
||||
*NameLength = utf8_to_ucs2(crName, (Int4) clen, CursorName, BufferLength);
|
||||
}
|
||||
free(crName);
|
||||
return ret;
|
||||
}
|
||||
@ -207,23 +240,33 @@ RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle,
|
||||
SQLUSMALLINT InfoType, PTR InfoValue,
|
||||
SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
|
||||
RETCODE ret;
|
||||
((ConnectionClass *) ConnectionHandle)->unicode = 1;
|
||||
|
||||
conn->unicode = 1;
|
||||
CC_clear_error(conn);
|
||||
#if (ODBCVER >= 0x0300)
|
||||
mylog("[SQLGetInfoW(30)]");
|
||||
if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength)) == SQL_ERROR)
|
||||
{
|
||||
if (((ConnectionClass *) ConnectionHandle)->driver_version >= 0x0300)
|
||||
return PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
|
||||
if (conn->driver_version >= 0x0300)
|
||||
{
|
||||
CC_clear_error(conn);
|
||||
ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
if (SQL_ERROR == ret)
|
||||
CC_log_error("SQLGetInfoW(30)", "", conn);
|
||||
#else
|
||||
mylog("[SQLGetInfoW]");
|
||||
return PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
|
||||
ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue,
|
||||
BufferLength, StringLength);
|
||||
if (SQL_ERROR == ret)
|
||||
CC_log_error("SQLGetInfoW", "", conn);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle,
|
||||
@ -428,17 +471,31 @@ RETCODE SQL_API SQLNativeSqlW(
|
||||
RETCODE ret;
|
||||
char *szIn, *szOut;
|
||||
UInt4 slen;
|
||||
SQLINTEGER olen;
|
||||
SQLINTEGER buflen, olen;
|
||||
|
||||
mylog("[SQLNativeSqlW]");
|
||||
((ConnectionClass *) hdbc)->unicode = 1;
|
||||
szIn = ucs2_to_utf8(szSqlStrIn, cbSqlStrIn, &slen);
|
||||
szOut = malloc(cbSqlStrMax);
|
||||
buflen = 3 * cbSqlStrMax + 1;
|
||||
szOut = malloc(buflen);
|
||||
ret = PGAPI_NativeSql(hdbc, szIn, (SQLINTEGER) slen,
|
||||
szOut, cbSqlStrMax, &olen);
|
||||
szOut, buflen, &olen);
|
||||
if (szIn);
|
||||
free(szIn);
|
||||
*pcbSqlStr = utf8_to_ucs2(szOut, olen, szSqlStr, cbSqlStrMax);
|
||||
if (ret == SQL_SUCCESS)
|
||||
{
|
||||
UInt4 szcount = utf8_to_ucs2(szOut, olen, szSqlStr, cbSqlStrMax);
|
||||
if (szcount > (UInt4) cbSqlStrMax)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
|
||||
ret = SQL_SUCCESS_WITH_INFO;
|
||||
conn->errornumber = CONN_TRUNCATED;
|
||||
conn->errormsg = "Sql string too large";
|
||||
}
|
||||
if (pcbSqlStr)
|
||||
*pcbSqlStr = szcount;
|
||||
}
|
||||
free(szOut);
|
||||
return ret;
|
||||
}
|
||||
@ -560,3 +617,10 @@ RETCODE SQL_API SQLTablePrivilegesW(
|
||||
free(tbName);
|
||||
return ret;
|
||||
}
|
||||
|
||||
RETCODE SQL_API SQLGetTypeInfoW(
|
||||
SQLHSTMT StatementHandle,
|
||||
SQLSMALLINT DataType)
|
||||
{
|
||||
return PGAPI_GetTypeInfo(StatementHandle, DataType);
|
||||
}
|
||||
|
@ -342,12 +342,13 @@ PGAPI_SetConnectOption(
|
||||
break;
|
||||
|
||||
case SQL_AUTOCOMMIT:
|
||||
if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_autocommit(conn))
|
||||
if (vParam == SQL_AUTOCOMMIT_ON && CC_is_in_trans(conn))
|
||||
break;
|
||||
else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_autocommit(conn))
|
||||
else if (vParam == SQL_AUTOCOMMIT_OFF && !CC_is_in_trans(conn))
|
||||
break;
|
||||
if (CC_is_in_trans(conn))
|
||||
CC_commit(conn);
|
||||
|
||||
mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
|
||||
|
||||
switch (vParam)
|
||||
@ -401,8 +402,21 @@ PGAPI_SetConnectOption(
|
||||
sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
|
||||
if (fOption == 30002 && vParam)
|
||||
{
|
||||
if (strcmp((char *) vParam, "Microsoft Jet") == 0)
|
||||
int cmp;
|
||||
#ifdef UNICODE_SUPPORT
|
||||
char *asPara;
|
||||
if (conn->unicode)
|
||||
{
|
||||
asPara = ucs2_to_utf8((SQLWCHAR *) vParam, -1, NULL);
|
||||
cmp = strcmp(asPara, "Microsoft Jet");
|
||||
free(asPara);
|
||||
}
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
cmp = strncmp((char *) vParam, "Microsoft Jet", 13);
|
||||
if (0 == cmp)
|
||||
{
|
||||
mylog("Microsoft Jet !!!!\n");
|
||||
conn->errornumber = 0;
|
||||
conn->ms_jet = 1;
|
||||
return SQL_SUCCESS;
|
||||
@ -456,7 +470,7 @@ PGAPI_GetConnectOption(
|
||||
|
||||
case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
|
||||
if (pvParam)
|
||||
strcpy(pvParam, "");
|
||||
((char *) pvParam)[0] = ((char *) pvParam)[1] = '\0';
|
||||
|
||||
break;
|
||||
|
||||
@ -557,7 +571,7 @@ PGAPI_GetStmtOption(
|
||||
case SQL_GET_BOOKMARK:
|
||||
case SQL_ROW_NUMBER:
|
||||
|
||||
res = stmt->result;
|
||||
res = SC_get_Curres(stmt);
|
||||
|
||||
if (stmt->manual_result || !ci->drivers.use_declarefetch)
|
||||
{
|
||||
|
@ -42,18 +42,29 @@
|
||||
#define TAB_INCR 8
|
||||
#define COL_INCR 16
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
char *getNextToken(int ccsc, char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric);
|
||||
#else
|
||||
char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric);
|
||||
#endif /* MULTIBYTE */
|
||||
void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k);
|
||||
char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi);
|
||||
|
||||
|
||||
char *
|
||||
getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric)
|
||||
getNextToken(
|
||||
#ifdef MULTIBYTE
|
||||
int ccsc, /* client encoding */
|
||||
#endif /* MULTIBYTE */
|
||||
char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric)
|
||||
{
|
||||
int i = 0;
|
||||
int out = 0;
|
||||
char qc,
|
||||
in_escape = FALSE;
|
||||
#ifdef MULTIBYTE
|
||||
encoded_str encstr;
|
||||
#endif
|
||||
|
||||
if (smax <= 1)
|
||||
return NULL;
|
||||
@ -80,17 +91,22 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
|
||||
if (numeric)
|
||||
*numeric = FALSE;
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
encoded_str_constr(&encstr, ccsc, &s[i]);
|
||||
#endif
|
||||
/* get the next token */
|
||||
while (!isspace((unsigned char) s[i]) && s[i] != ',' &&
|
||||
s[i] != '\0' && out != smax)
|
||||
while (s[i] != '\0' && out < smax)
|
||||
{
|
||||
#ifdef MULTIBYTE
|
||||
if (multibyte_char_check(s[i]) != 0)
|
||||
encoded_nextchar(&encstr);
|
||||
if (ENCODE_STATUS(encstr) != 0)
|
||||
{
|
||||
token[out++] = s[i++];
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (isspace((unsigned char) s[i]) || s[i] == ',')
|
||||
break;
|
||||
/* Handle quoted stuff */
|
||||
if (out == 0 && (s[i] == '\"' || s[i] == '\''))
|
||||
{
|
||||
@ -110,7 +126,8 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
|
||||
while (s[i] != '\0' && out != smax)
|
||||
{
|
||||
#ifdef MULTIBYTE
|
||||
if (multibyte_char_check(s[i]) != 0)
|
||||
encoded_nextchar(&encstr);
|
||||
if (ENCODE_STATUS(encstr) != 0)
|
||||
{
|
||||
token[out++] = s[i++];
|
||||
continue;
|
||||
@ -197,22 +214,22 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu
|
||||
|
||||
|
||||
#if 0
|
||||
QR_set_num_fields(stmt->result, 14);
|
||||
QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(stmt->result, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(stmt->result, 4, "DATA_TYPE", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(stmt->result, 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(stmt->result, 6, "PRECISION", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(stmt->result, 7, "LENGTH", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(stmt->result, 8, "SCALE", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(stmt->result, 9, "RADIX", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(stmt->result, 10, "NULLABLE", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(stmt->result, 11, "REMARKS", PG_TYPE_TEXT, 254);
|
||||
QR_set_num_fields(SC_get_Curres(stmt), 14);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 4, "DATA_TYPE", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 6, "PRECISION", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 7, "LENGTH", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 8, "SCALE", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 9, "RADIX", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 10, "NULLABLE", PG_TYPE_INT2, 2);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 11, "REMARKS", PG_TYPE_TEXT, 254);
|
||||
/* User defined fields */
|
||||
QR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4);
|
||||
QR_set_field_info(SC_get_Curres(stmt), 13, "FIELD_TYPE", PG_TYPE_INT4, 4);
|
||||
#endif
|
||||
|
||||
void
|
||||
@ -312,9 +329,10 @@ parse_statement(StatementClass *stmt)
|
||||
stmt->ntab = 0;
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
multibyte_init();
|
||||
#endif
|
||||
while (pptr = ptr, (ptr = getNextToken(conn->ccsc, pptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL)
|
||||
#else
|
||||
while (pptr = ptr, (ptr = getNextToken(pptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL)
|
||||
#endif
|
||||
{
|
||||
unquoted = !(quote || dquote);
|
||||
|
||||
@ -607,12 +625,17 @@ parse_statement(StatementClass *stmt)
|
||||
if (!dquote)
|
||||
{
|
||||
char *ptr;
|
||||
#ifdef MULTIBYTE
|
||||
encoded_str encstr;
|
||||
make_encoded_str(&encstr, conn, ti[stmt->ntab]->name);
|
||||
#endif /* MULTIBYTE */
|
||||
|
||||
/* lower case table name */
|
||||
for (ptr = ti[stmt->ntab]->name; *ptr; ptr++)
|
||||
{
|
||||
#ifdef MULTIBYTE
|
||||
if ((unsigned char) *ptr >= 0x80)
|
||||
encoded_nextchar(&encstr);
|
||||
if (ENCODE_STATUS(encstr) != 0)
|
||||
ptr++;
|
||||
else
|
||||
#endif /* MULTIBYTE */
|
||||
@ -773,13 +796,13 @@ parse_statement(StatementClass *stmt)
|
||||
* structure
|
||||
*/
|
||||
strcpy(conn->col_info[conn->ntables]->name, ti[i]->name);
|
||||
conn->col_info[conn->ntables]->result = col_stmt->result;
|
||||
conn->col_info[conn->ntables]->result = SC_get_Curres(col_stmt);
|
||||
|
||||
/*
|
||||
* The connection will now free the result structures, so
|
||||
* make sure that the statement doesn't free it
|
||||
*/
|
||||
col_stmt->result = NULL;
|
||||
SC_set_Result(col_stmt, NULL);
|
||||
|
||||
conn->ntables++;
|
||||
|
||||
|
@ -36,37 +36,92 @@ PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||
RETCODE ret;
|
||||
static const char *func = "PGAPI_GetDiagRec";
|
||||
|
||||
mylog("%s entering ", func);
|
||||
mylog("%s entering rec=%d", func, RecNumber);
|
||||
switch (HandleType)
|
||||
{
|
||||
case SQL_HANDLE_ENV:
|
||||
ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError,
|
||||
MessageText, BufferLength, TextLength);
|
||||
ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate,
|
||||
NativeError, MessageText,
|
||||
BufferLength, TextLength, 0);
|
||||
break;
|
||||
case SQL_HANDLE_DBC:
|
||||
ret = PGAPI_Error(NULL, Handle, NULL, Sqlstate, NativeError,
|
||||
MessageText, BufferLength, TextLength);
|
||||
ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate,
|
||||
NativeError, MessageText, BufferLength,
|
||||
TextLength, 0);
|
||||
break;
|
||||
case SQL_HANDLE_STMT:
|
||||
ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError,
|
||||
MessageText, BufferLength, TextLength);
|
||||
ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate,
|
||||
NativeError, MessageText, BufferLength,
|
||||
TextLength, 0);
|
||||
break;
|
||||
default:
|
||||
ret = SQL_ERROR;
|
||||
}
|
||||
if (ret == SQL_SUCCESS_WITH_INFO &&
|
||||
BufferLength == 0 &&
|
||||
*TextLength)
|
||||
{
|
||||
SQLSMALLINT BufferLength = *TextLength + 4;
|
||||
SQLCHAR *MessageText = malloc(BufferLength);
|
||||
mylog("%s exiting %d\n", func, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
|
||||
NativeError, MessageText, BufferLength,
|
||||
TextLength);
|
||||
free(MessageText);
|
||||
RETCODE SQL_API
|
||||
PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||
SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
|
||||
PTR DiagInfoPtr, SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT *StringLengthPtr)
|
||||
{
|
||||
RETCODE ret = SQL_SUCCESS;
|
||||
static const char *func = "PGAPI_GetDiagField";
|
||||
|
||||
mylog("%s entering rec=%d", func, RecNumber);
|
||||
switch (HandleType)
|
||||
{
|
||||
case SQL_HANDLE_ENV:
|
||||
switch (DiagIdentifier)
|
||||
{
|
||||
case SQL_DIAG_CLASS_ORIGIN:
|
||||
case SQL_DIAG_SUBCLASS_ORIGIN:
|
||||
case SQL_DIAG_CONNECTION_NAME:
|
||||
case SQL_DIAG_MESSAGE_TEXT:
|
||||
case SQL_DIAG_NATIVE:
|
||||
case SQL_DIAG_NUMBER:
|
||||
case SQL_DIAG_RETURNCODE:
|
||||
case SQL_DIAG_SERVER_NAME:
|
||||
case SQL_DIAG_SQLSTATE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SQL_HANDLE_DBC:
|
||||
switch (DiagIdentifier)
|
||||
{
|
||||
case SQL_DIAG_CLASS_ORIGIN:
|
||||
case SQL_DIAG_SUBCLASS_ORIGIN:
|
||||
case SQL_DIAG_CONNECTION_NAME:
|
||||
case SQL_DIAG_MESSAGE_TEXT:
|
||||
case SQL_DIAG_NATIVE:
|
||||
case SQL_DIAG_NUMBER:
|
||||
case SQL_DIAG_RETURNCODE:
|
||||
case SQL_DIAG_SERVER_NAME:
|
||||
case SQL_DIAG_SQLSTATE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SQL_HANDLE_STMT:
|
||||
switch (DiagIdentifier)
|
||||
{
|
||||
case SQL_DIAG_CLASS_ORIGIN:
|
||||
case SQL_DIAG_SUBCLASS_ORIGIN:
|
||||
case SQL_DIAG_CONNECTION_NAME:
|
||||
case SQL_DIAG_MESSAGE_TEXT:
|
||||
case SQL_DIAG_NATIVE:
|
||||
case SQL_DIAG_NUMBER:
|
||||
case SQL_DIAG_RETURNCODE:
|
||||
case SQL_DIAG_SERVER_NAME:
|
||||
case SQL_DIAG_SQLSTATE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = SQL_ERROR;
|
||||
}
|
||||
mylog("%s exiting\n", func);
|
||||
mylog("%s exiting %d\n", func, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -87,7 +142,7 @@ PGAPI_GetConnectAttr(HDBC ConnectionHandle,
|
||||
case SQL_ATTR_CONNECTION_TIMEOUT:
|
||||
case SQL_ATTR_METADATA_ID:
|
||||
conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
conn->errormsg = "Unsupported connection option (Set)";
|
||||
conn->errormsg = "Unsupported connect attribute (Get)";
|
||||
return SQL_ERROR;
|
||||
}
|
||||
return PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value);
|
||||
@ -373,7 +428,7 @@ PGAPI_SetConnectAttr(HDBC ConnectionHandle,
|
||||
case SQL_ATTR_CONNECTION_TIMEOUT:
|
||||
case SQL_ATTR_METADATA_ID:
|
||||
conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
conn->errormsg = "Unsupported connection option (Set)";
|
||||
conn->errormsg = "Unsupported connect attribute (Set)";
|
||||
return SQL_ERROR;
|
||||
}
|
||||
return PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value);
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#define PODBC_NOT_SEARCH_PATTERN 1L
|
||||
#define PODBC_ALLOW_PARTIAL_EXTRACT 1L
|
||||
#define PODBC_ERROR_CLEAR (1L << 1)
|
||||
|
||||
RETCODE SQL_API PGAPI_AllocConnect(HENV EnvironmentHandle,
|
||||
HDBC FAR * ConnectionHandle);
|
||||
@ -56,6 +58,20 @@ RETCODE SQL_API PGAPI_Error(HENV EnvironmentHandle,
|
||||
SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
|
||||
SQLCHAR *MessageText, SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT *TextLength);
|
||||
/* Helper functions for Error handling */
|
||||
RETCODE SQL_API PGAPI_EnvError(HENV EnvironmentHandle, SWORD RecNumber,
|
||||
SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
|
||||
SQLCHAR *MessageText, SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT *TextLength, UWORD flag);
|
||||
RETCODE SQL_API PGAPI_ConnectError(HDBC ConnectionHandle, SWORD RecNumber,
|
||||
SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
|
||||
SQLCHAR *MessageText, SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT *TextLength, UWORD flag);
|
||||
RETCODE SQL_API PGAPI_StmtError(HSTMT StatementHandle, SWORD RecNumber,
|
||||
SQLCHAR *Sqlstate, SQLINTEGER *NativeError,
|
||||
SQLCHAR *MessageText, SQLSMALLINT BufferLength,
|
||||
SQLSMALLINT *TextLength, UWORD flag);
|
||||
|
||||
RETCODE SQL_API PGAPI_ExecDirect(HSTMT StatementHandle,
|
||||
SQLCHAR *StatementText, SQLINTEGER TextLength);
|
||||
RETCODE SQL_API PGAPI_Execute(HSTMT StatementHandle);
|
||||
@ -225,7 +241,8 @@ RETCODE SQL_API PGAPI_TablePrivileges(
|
||||
SQLCHAR *szSchemaName,
|
||||
SQLSMALLINT cbSchemaName,
|
||||
SQLCHAR *szTableName,
|
||||
SQLSMALLINT cbTableName);
|
||||
SQLSMALLINT cbTableName,
|
||||
UWORD flag);
|
||||
RETCODE SQL_API PGAPI_BindParameter(
|
||||
HSTMT hstmt,
|
||||
SQLUSMALLINT ipar,
|
||||
@ -243,4 +260,25 @@ RETCODE SQL_API PGAPI_SetScrollOptions(
|
||||
SDWORD crowKeyset,
|
||||
UWORD crowRowset);
|
||||
|
||||
#if (ODBCVER >= 0x0300)
|
||||
RETCODE SQL_API PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
|
||||
SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
|
||||
SQLINTEGER *NativeError, SQLCHAR *MessageText,
|
||||
SQLSMALLINT BufferLength, SQLSMALLINT *TextLength);
|
||||
RETCODE SQL_API PGAPI_GetConnectAttr(HDBC ConnectionHandle,
|
||||
SQLINTEGER Attribute, PTR Value,
|
||||
SQLINTEGER BufferLength, SQLINTEGER *StringLength);
|
||||
RETCODE SQL_API PGAPI_GetStmtAttr(HSTMT StatementHandle,
|
||||
SQLINTEGER Attribute, PTR Value,
|
||||
SQLINTEGER BufferLength, SQLINTEGER *StringLength);
|
||||
RETCODE SQL_API PGAPI_SetConnectAttr(HDBC ConnectionHandle,
|
||||
SQLINTEGER Attribute, PTR Value,
|
||||
SQLINTEGER StringLength);
|
||||
RETCODE SQL_API PGAPI_SetStmtAttr(HSTMT StatementHandle,
|
||||
SQLINTEGER Attribute, PTR Value,
|
||||
SQLINTEGER StringLength);
|
||||
RETCODE SQL_API PGAPI_SetDescField(SQLHDESC DescriptorHandle,
|
||||
SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
|
||||
PTR Value, SQLINTEGER BufferLength);
|
||||
#endif /* ODBCVER */
|
||||
#endif /* define_PG_API_FUNC_H__ */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "dlg_specific.h"
|
||||
#include "statement.h"
|
||||
#include "connection.h"
|
||||
#include "environ.h"
|
||||
#include "qresult.h"
|
||||
|
||||
|
||||
@ -90,15 +91,26 @@ Int2 sqlTypes[] = {
|
||||
SQL_TINYINT,
|
||||
SQL_VARBINARY,
|
||||
SQL_VARCHAR,
|
||||
#ifdef UNICODE_SUPPORT
|
||||
SQL_WCHAR,
|
||||
SQL_WVARCHAR,
|
||||
SQL_WLONGVARCHAR,
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
0
|
||||
};
|
||||
|
||||
#if (ODBCVER >= 0x0300) && defined(OBDCINT64)
|
||||
#define ALLOWED_C_BIGINT SQL_C_SBIGINT
|
||||
#else
|
||||
#define ALLOWED_C_BIGINT SQL_C_CHAR
|
||||
#endif
|
||||
|
||||
Int4
|
||||
sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
|
||||
{
|
||||
Int4 pgType;
|
||||
ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
|
||||
ConnectionClass *conn = SC_get_conn(stmt);
|
||||
ConnInfo *ci = &(conn->connInfo);
|
||||
|
||||
switch (fSqlType)
|
||||
{
|
||||
@ -110,11 +122,20 @@ sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
|
||||
pgType = PG_TYPE_BPCHAR;
|
||||
break;
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case SQL_WCHAR:
|
||||
pgType = PG_TYPE_BPCHAR;
|
||||
break;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
case SQL_BIT:
|
||||
pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
|
||||
break;
|
||||
|
||||
case SQL_DATE:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_TYPE_DATE:
|
||||
#endif /* ODBCVER */
|
||||
pgType = PG_TYPE_DATE;
|
||||
break;
|
||||
|
||||
@ -144,6 +165,12 @@ sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
|
||||
pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
|
||||
break;
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case SQL_WLONGVARCHAR:
|
||||
pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
|
||||
break;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
case SQL_REAL:
|
||||
pgType = PG_TYPE_FLOAT4;
|
||||
break;
|
||||
@ -154,10 +181,16 @@ sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
|
||||
break;
|
||||
|
||||
case SQL_TIME:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_TYPE_TIME:
|
||||
#endif /* ODBCVER */
|
||||
pgType = PG_TYPE_TIME;
|
||||
break;
|
||||
|
||||
case SQL_TIMESTAMP:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
#endif /* ODBCVER */
|
||||
pgType = PG_TYPE_DATETIME;
|
||||
break;
|
||||
|
||||
@ -169,6 +202,12 @@ sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
|
||||
pgType = PG_TYPE_VARCHAR;
|
||||
break;
|
||||
|
||||
#if UNICODE_SUPPORT
|
||||
case SQL_WVARCHAR:
|
||||
pgType = PG_TYPE_VARCHAR;
|
||||
break;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
default:
|
||||
pgType = 0; /* ??? */
|
||||
break;
|
||||
@ -193,7 +232,9 @@ sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
|
||||
Int2
|
||||
pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
||||
{
|
||||
ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
|
||||
ConnectionClass *conn = SC_get_conn(stmt);
|
||||
ConnInfo *ci = &(conn->connInfo);
|
||||
EnvironmentClass *env = (EnvironmentClass *) (conn->henv);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -204,6 +245,19 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
||||
case PG_TYPE_NAME:
|
||||
return SQL_CHAR;
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case PG_TYPE_BPCHAR:
|
||||
return conn->unicode ? SQL_WCHAR : SQL_CHAR;
|
||||
|
||||
case PG_TYPE_VARCHAR:
|
||||
return conn->unicode ? SQL_WVARCHAR : SQL_VARCHAR;
|
||||
|
||||
case PG_TYPE_TEXT:
|
||||
return ci->drivers.text_as_longvarchar ?
|
||||
(conn->unicode ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR) :
|
||||
(conn->unicode ? SQL_WVARCHAR : SQL_VARCHAR);
|
||||
|
||||
#else
|
||||
case PG_TYPE_BPCHAR:
|
||||
return SQL_CHAR;
|
||||
|
||||
@ -212,6 +266,7 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
||||
|
||||
case PG_TYPE_TEXT:
|
||||
return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
case PG_TYPE_BYTEA:
|
||||
return SQL_VARBINARY;
|
||||
@ -229,10 +284,10 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
||||
/* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */
|
||||
case PG_TYPE_INT8:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_BIGINT;
|
||||
#else
|
||||
return SQL_CHAR;
|
||||
if (!conn->ms_jet)
|
||||
return SQL_BIGINT;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_CHAR;
|
||||
|
||||
case PG_TYPE_NUMERIC:
|
||||
return SQL_NUMERIC;
|
||||
@ -242,12 +297,24 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
||||
case PG_TYPE_FLOAT8:
|
||||
return SQL_FLOAT;
|
||||
case PG_TYPE_DATE:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (EN_is_odbc3(env))
|
||||
return SQL_TYPE_DATE;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_DATE;
|
||||
case PG_TYPE_TIME:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (EN_is_odbc3(env))
|
||||
return SQL_TYPE_TIME;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_TIME;
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (EN_is_odbc3(env))
|
||||
return SQL_TYPE_TIMESTAMP;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_TIMESTAMP;
|
||||
case PG_TYPE_MONEY:
|
||||
return SQL_FLOAT;
|
||||
@ -273,16 +340,18 @@ pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
||||
Int2
|
||||
pgtype_to_ctype(StatementClass *stmt, Int4 type)
|
||||
{
|
||||
ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
|
||||
ConnectionClass *conn = SC_get_conn(stmt);
|
||||
ConnInfo *ci = &(conn->connInfo);
|
||||
EnvironmentClass *env = (EnvironmentClass *) (conn->henv);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PG_TYPE_INT8:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_SBIGINT;
|
||||
#else
|
||||
if (!conn->ms_jet)
|
||||
return ALLOWED_C_BIGINT;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_C_CHAR;
|
||||
#endif
|
||||
case PG_TYPE_NUMERIC:
|
||||
return SQL_C_CHAR;
|
||||
case PG_TYPE_INT2:
|
||||
@ -297,24 +366,24 @@ pgtype_to_ctype(StatementClass *stmt, Int4 type)
|
||||
return SQL_C_DOUBLE;
|
||||
case PG_TYPE_DATE:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_TYPE_DATE;
|
||||
#else
|
||||
return SQL_C_DATE;
|
||||
if (EN_is_odbc3(env))
|
||||
return SQL_C_TYPE_DATE;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_C_DATE;
|
||||
case PG_TYPE_TIME:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_TYPE_TIME;
|
||||
#else
|
||||
return SQL_C_TIME;
|
||||
if (EN_is_odbc3(env))
|
||||
return SQL_C_TYPE_TIME;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_C_TIME;
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_TYPE_TIMESTAMP;
|
||||
#else
|
||||
return SQL_C_TIMESTAMP;
|
||||
if (EN_is_odbc3(env))
|
||||
return SQL_C_TYPE_TIMESTAMP;
|
||||
#endif /* ODBCVER */
|
||||
return SQL_C_TIMESTAMP;
|
||||
case PG_TYPE_MONEY:
|
||||
return SQL_C_FLOAT;
|
||||
case PG_TYPE_BOOL:
|
||||
@ -324,6 +393,12 @@ pgtype_to_ctype(StatementClass *stmt, Int4 type)
|
||||
return SQL_C_BINARY;
|
||||
case PG_TYPE_LO:
|
||||
return SQL_C_BINARY;
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case PG_TYPE_BPCHAR:
|
||||
case PG_TYPE_VARCHAR:
|
||||
case PG_TYPE_TEXT:
|
||||
return conn->unicode ? SQL_C_WCHAR : SQL_C_CHAR;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
default:
|
||||
/* hack until permanent type is available */
|
||||
@ -416,7 +491,7 @@ getNumericScale(StatementClass *stmt, Int4 type, int col)
|
||||
if (col < 0)
|
||||
return PG_NUMERIC_MAX_SCALE;
|
||||
|
||||
result = SC_get_Result(stmt);
|
||||
result = SC_get_Curres(stmt);
|
||||
|
||||
/*
|
||||
* Manual Result Sets -- use assigned column width (i.e., from
|
||||
@ -457,7 +532,7 @@ getNumericPrecision(StatementClass *stmt, Int4 type, int col)
|
||||
if (col < 0)
|
||||
return PG_NUMERIC_MAX_PRECISION;
|
||||
|
||||
result = SC_get_Result(stmt);
|
||||
result = SC_get_Curres(stmt);
|
||||
|
||||
/*
|
||||
* Manual Result Sets -- use assigned column width (i.e., from
|
||||
@ -520,10 +595,6 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Static Precision (i.e., the Maximum Precision of the datatype) This
|
||||
* has nothing to do with a result set.
|
||||
*/
|
||||
if (maxsize == TEXT_FIELD_SIZE + 1) /* magic length for testing */
|
||||
{
|
||||
if (PG_VERSION_GE(SC_get_conn(stmt), 7.1))
|
||||
@ -531,10 +602,14 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
|
||||
else
|
||||
maxsize = TEXT_FIELD_SIZE;
|
||||
}
|
||||
/*
|
||||
* Static Precision (i.e., the Maximum Precision of the datatype) This
|
||||
* has nothing to do with a result set.
|
||||
*/
|
||||
if (col < 0)
|
||||
return maxsize;
|
||||
|
||||
result = SC_get_Result(stmt);
|
||||
result = SC_get_Curres(stmt);
|
||||
|
||||
/*
|
||||
* Manual Result Sets -- use assigned column width (i.e., from
|
||||
@ -553,16 +628,20 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
|
||||
if (QR_get_atttypmod(result, col) > -1)
|
||||
return QR_get_atttypmod(result, col);
|
||||
|
||||
/* The type is really unknown */
|
||||
if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST)
|
||||
{
|
||||
p = QR_get_display_size(result, col);
|
||||
mylog("getCharPrecision: LONGEST: p = %d\n", p);
|
||||
if (p >= 0)
|
||||
return p;
|
||||
}
|
||||
|
||||
if (p < 0 && handle_unknown_size_as == UNKNOWNS_AS_MAX)
|
||||
if (handle_unknown_size_as == UNKNOWNS_AS_MAX)
|
||||
return maxsize;
|
||||
else
|
||||
return p;
|
||||
else /* handle_unknown_size_as == DONT_KNOW */
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
static Int2
|
||||
@ -580,7 +659,7 @@ getTimestampScale(StatementClass *stmt, Int4 type, int col)
|
||||
if (PG_VERSION_LT(conn, 7.2))
|
||||
return 0;
|
||||
|
||||
result = SC_get_Result(stmt);
|
||||
result = SC_get_Curres(stmt);
|
||||
|
||||
/*
|
||||
* Manual Result Sets -- use assigned column width (i.e., from
|
||||
@ -615,10 +694,7 @@ getTimestampPrecision(StatementClass *stmt, Int4 type, int col)
|
||||
fixed = 8;
|
||||
break;
|
||||
case PG_TYPE_TIME_WITH_TMZONE:
|
||||
if (USE_ZONE)
|
||||
fixed = 11;
|
||||
else
|
||||
fixed = 8;
|
||||
fixed = 11;
|
||||
break;
|
||||
case PG_TYPE_TIMESTAMP_NO_TMZONE:
|
||||
fixed = 19;
|
||||
@ -692,7 +768,10 @@ pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
|
||||
return getTimestampPrecision(stmt, type, col);
|
||||
|
||||
case PG_TYPE_BOOL:
|
||||
return 1;
|
||||
{
|
||||
BOOL true_is_minus1 = FALSE;
|
||||
return true_is_minus1 ? 2 : 1;
|
||||
}
|
||||
|
||||
case PG_TYPE_LO:
|
||||
return SQL_NO_TOTAL;
|
||||
@ -756,6 +835,8 @@ pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown
|
||||
Int4
|
||||
pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
|
||||
{
|
||||
ConnectionClass *conn = SC_get_conn(stmt);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case PG_TYPE_INT2:
|
||||
@ -791,15 +872,27 @@ pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_
|
||||
/* Character types (and NUMERIC) use the default precision */
|
||||
case PG_TYPE_VARCHAR:
|
||||
case PG_TYPE_BPCHAR:
|
||||
{
|
||||
int coef = 1;
|
||||
Int4 prec = pgtype_precision(stmt, type, col, handle_unknown_size_as), maxvarc;
|
||||
if (conn->unicode)
|
||||
return (prec + 1) * 2;
|
||||
#ifdef MULTIBYTE
|
||||
/* after 7.2 */
|
||||
if (PG_VERSION_GE(SC_get_conn(stmt), 7.2))
|
||||
return 3 * pgtype_precision(stmt, type, col, handle_unknown_size_as);
|
||||
if (PG_VERSION_GE(conn, 7.2))
|
||||
coef = 3;
|
||||
else
|
||||
#else
|
||||
/* CR -> CR/LF */
|
||||
return 2 * pgtype_precision(stmt, type, col, handle_unknown_size_as);
|
||||
#endif /* MULTIBYTE */
|
||||
if ((conn->connInfo).lf_conversion)
|
||||
/* CR -> CR/LF */
|
||||
coef = 2;
|
||||
if (coef == 1)
|
||||
return prec + 1;
|
||||
maxvarc = conn->connInfo.drivers.max_varchar_size;
|
||||
if (prec <= maxvarc && prec * coef > maxvarc)
|
||||
return maxvarc;
|
||||
return coef * prec;
|
||||
}
|
||||
default:
|
||||
return pgtype_precision(stmt, type, col, handle_unknown_size_as);
|
||||
}
|
||||
@ -885,8 +978,8 @@ pgtype_auto_increment(StatementClass *stmt, Int4 type)
|
||||
case PG_TYPE_NUMERIC:
|
||||
|
||||
case PG_TYPE_DATE:
|
||||
case PG_TYPE_TIME:
|
||||
case PG_TYPE_TIME_WITH_TMZONE:
|
||||
case PG_TYPE_TIME:
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP:
|
||||
@ -1058,9 +1151,16 @@ sqltype_to_default_ctype(Int2 sqltype)
|
||||
#else
|
||||
return SQL_C_CHAR;
|
||||
case SQL_BIGINT:
|
||||
return SQL_C_SBIGINT;
|
||||
return ALLOWED_C_BIGINT;
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
case SQL_WCHAR:
|
||||
case SQL_WVARCHAR:
|
||||
case SQL_WLONGVARCHAR:
|
||||
return SQL_C_WCHAR;
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
|
||||
case SQL_BIT:
|
||||
return SQL_C_BIT;
|
||||
|
||||
@ -1086,24 +1186,23 @@ sqltype_to_default_ctype(Int2 sqltype)
|
||||
return SQL_C_BINARY;
|
||||
|
||||
case SQL_DATE:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_TYPE_DATE;
|
||||
#else
|
||||
return SQL_C_DATE;
|
||||
#endif /* ODBCVER */
|
||||
|
||||
case SQL_TIME:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_TYPE_TIME;
|
||||
#else
|
||||
return SQL_C_TIME;
|
||||
#endif /* ODBCVER */
|
||||
|
||||
case SQL_TIMESTAMP:
|
||||
#if (ODBCVER >= 0x0300)
|
||||
return SQL_C_TYPE_TIMESTAMP;
|
||||
#else
|
||||
return SQL_C_TIMESTAMP;
|
||||
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_TYPE_DATE:
|
||||
return SQL_C_TYPE_DATE;
|
||||
|
||||
case SQL_TYPE_TIME:
|
||||
return SQL_C_TYPE_TIME;
|
||||
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
return SQL_C_TYPE_TIMESTAMP;
|
||||
#endif /* ODBCVER */
|
||||
|
||||
default:
|
||||
@ -1167,6 +1266,7 @@ ctype_length(Int2 ctype)
|
||||
|
||||
case SQL_C_BINARY:
|
||||
case SQL_C_CHAR:
|
||||
case SQL_C_WCHAR:
|
||||
return 0;
|
||||
|
||||
default: /* should never happen */
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
*
|
||||
* $Id: psqlodbc.h,v 1.57 2002/02/18 03:16:11 inoue Exp $
|
||||
* $Id: psqlodbc.h,v 1.58 2002/03/08 08:52:53 inoue Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -87,7 +87,7 @@ typedef UInt4 Oid;
|
||||
#define DBMS_NAME "PostgreSQL"
|
||||
#endif /* ODBCVER */
|
||||
|
||||
#define POSTGRESDRIVERVERSION "07.01.0010"
|
||||
#define POSTGRESDRIVERVERSION "07.01.0011"
|
||||
|
||||
#ifdef WIN32
|
||||
#if (ODBCVER >= 0x0300)
|
||||
@ -254,6 +254,11 @@ void logs_on_off(int cnopen, int, int);
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
#ifdef UNICODE_SUPPORT
|
||||
UInt4 ucs2strlen(const SQLWCHAR *ucs2str);
|
||||
char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen);
|
||||
UInt4 utf8_to_ucs2(const char * utf8str, Int4 ilen, SQLWCHAR *ucs2str, UInt4 buflen);
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
#ifdef _MEMORY_DEBUG_
|
||||
void *debug_alloc(size_t);
|
||||
void *debug_realloc(void *, size_t);
|
||||
|
@ -138,7 +138,7 @@ BEGIN
|
||||
BS_NOTIFY | WS_TABSTOP,247,205,40,10
|
||||
END
|
||||
|
||||
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 161
|
||||
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 176
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Advanced Options (DataSource)"
|
||||
FONT 10, "Terminal"
|
||||
@ -151,23 +151,27 @@ BEGIN
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,45,28,88,10
|
||||
CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,149,28,86,10
|
||||
GROUPBOX "Protocol",IDC_STATIC,43,44,180,25
|
||||
CONTROL "LF <-> CR/LF convert",DS_LFCONVERSION,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,45,43,92,10
|
||||
CONTROL "True is -1",DS_TRUEISMINUS1,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,149,43,86,10
|
||||
GROUPBOX "Protocol",IDC_STATIC,43,59,180,25
|
||||
CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON |
|
||||
WS_GROUP,53,54,47,10
|
||||
WS_GROUP,53,69,47,10
|
||||
CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
|
||||
131,54,26,10
|
||||
131,69,26,10
|
||||
CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
|
||||
187,54,26,10
|
||||
GROUPBOX "OID Options",IDC_STATIC,43,74,180,25
|
||||
187,69,26,10
|
||||
GROUPBOX "OID Options",IDC_STATIC,43,89,180,25
|
||||
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
|
||||
WS_GROUP | WS_TABSTOP,53,85,59,10
|
||||
WS_GROUP | WS_TABSTOP,53,100,59,10
|
||||
CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX |
|
||||
WS_GROUP | WS_TABSTOP,161,85,55,10
|
||||
LTEXT "Connect &Settings:",IDC_STATIC,10,105,35,25
|
||||
EDITTEXT DS_CONNSETTINGS,50,105,200,20,ES_MULTILINE |
|
||||
WS_GROUP | WS_TABSTOP,161,100,55,10
|
||||
LTEXT "Connect &Settings:",IDC_STATIC,10,120,35,25
|
||||
EDITTEXT DS_CONNSETTINGS,50,120,200,20,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
|
||||
DEFPUSHBUTTON "OK",IDOK,71,135,50,14,WS_GROUP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,146,135,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,71,150,50,14,WS_GROUP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,146,150,50,14
|
||||
END
|
||||
#else
|
||||
DLG_CONFIG DIALOG DISCARDABLE 65, 43, 292, 116
|
||||
@ -255,7 +259,7 @@ BEGIN
|
||||
BS_NOTIFY | WS_TABSTOP,233,224,40,10
|
||||
END
|
||||
|
||||
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 161
|
||||
DLG_OPTIONS_DS DIALOG DISCARDABLE 0, 0, 267, 176
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Advanced Options (DataSource)"
|
||||
FONT 8, "MS Sans Serif"
|
||||
@ -268,23 +272,27 @@ BEGIN
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,25,25,85,10
|
||||
CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,130,25,85,10
|
||||
GROUPBOX "Protocol",IDC_STATIC,15,40,180,25
|
||||
CONTROL "LF <-> CR/LF convert",DS_LFCONVERSION,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,45,40,92,10
|
||||
CONTROL "True is -1",DS_TRUEISMINUS1,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,149,40,86,10
|
||||
GROUPBOX "Protocol",IDC_STATIC,15,55,180,25
|
||||
CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,25,
|
||||
50,35,10
|
||||
65,35,10
|
||||
CONTROL "6.3",DS_PG63,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
|
||||
75,50,26,10
|
||||
75,65,26,10
|
||||
CONTROL "6.2",DS_PG62,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,
|
||||
130,50,26,10
|
||||
GROUPBOX "OID Options",IDC_STATIC,15,70,180,25
|
||||
130,65,26,10
|
||||
GROUPBOX "OID Options",IDC_STATIC,15,86,180,25
|
||||
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
|
||||
WS_GROUP | WS_TABSTOP,25,81,59,10
|
||||
WS_GROUP | WS_TABSTOP,25,96,59,10
|
||||
CONTROL "Fake &Index",DS_FAKEOIDINDEX,"Button",BS_AUTOCHECKBOX |
|
||||
WS_GROUP | WS_TABSTOP,115,81,51,10
|
||||
RTEXT "Connect &Settings:",IDC_STATIC,10,105,35,25
|
||||
EDITTEXT DS_CONNSETTINGS,50,105,200,20,ES_MULTILINE |
|
||||
WS_GROUP | WS_TABSTOP,115,96,51,10
|
||||
RTEXT "Connect &Settings:",IDC_STATIC,10,120,35,25
|
||||
EDITTEXT DS_CONNSETTINGS,50,120,200,20,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
|
||||
DEFPUSHBUTTON "OK",IDOK,71,135,50,14,WS_GROUP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,146,135,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,71,150,50,14,WS_GROUP
|
||||
PUSHBUTTON "Cancel",IDCANCEL,146,150,50,14
|
||||
END
|
||||
#endif
|
||||
|
||||
@ -354,8 +362,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 7,1,0,10
|
||||
PRODUCTVERSION 7,1,0,10
|
||||
FILEVERSION 7,1,0,11
|
||||
PRODUCTVERSION 7,1,0,11
|
||||
FILEFLAGSMASK 0x3L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -377,14 +385,14 @@ BEGIN
|
||||
VALUE "CompanyName", "Insight Distribution Systems\0"
|
||||
#endif
|
||||
VALUE "FileDescription", "PostgreSQL Driver\0"
|
||||
VALUE "FileVersion", " 07.01.0010\0"
|
||||
VALUE "FileVersion", " 07.01.0011\0"
|
||||
VALUE "InternalName", "psqlodbc\0"
|
||||
VALUE "LegalCopyright", "\0"
|
||||
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft<66> is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
|
||||
VALUE "OriginalFilename", "psqlodbc.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
|
||||
VALUE "ProductVersion", " 07.01.0010\0"
|
||||
VALUE "ProductVersion", " 07.01.0011\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
106
src/interfaces/odbc/psqlodbc_api30w.def
Normal file
106
src/interfaces/odbc/psqlodbc_api30w.def
Normal file
@ -0,0 +1,106 @@
|
||||
LIBRARY psqlodbc30
|
||||
EXPORTS
|
||||
SQLAllocConnect @1
|
||||
SQLAllocEnv @2
|
||||
SQLAllocStmt @3
|
||||
SQLBindCol @4
|
||||
SQLCancel @5
|
||||
SQLColAttributes @6
|
||||
SQLConnect @7
|
||||
SQLDescribeCol @8
|
||||
SQLDisconnect @9
|
||||
SQLError @10
|
||||
SQLExecDirect @11
|
||||
SQLExecute @12
|
||||
SQLFetch @13
|
||||
SQLFreeConnect @14
|
||||
SQLFreeEnv @15
|
||||
SQLFreeStmt @16
|
||||
SQLGetCursorName @17
|
||||
SQLNumResultCols @18
|
||||
SQLPrepare @19
|
||||
SQLRowCount @20
|
||||
SQLSetCursorName @21
|
||||
SQLTransact @23
|
||||
SQLColumns @40
|
||||
SQLDriverConnect @41
|
||||
SQLGetData @43
|
||||
SQLGetFunctions @44
|
||||
SQLGetInfo @45
|
||||
SQLGetStmtOption @46
|
||||
SQLGetTypeInfo @47
|
||||
SQLParamData @48
|
||||
SQLPutData @49
|
||||
SQLSpecialColumns @52
|
||||
SQLStatistics @53
|
||||
SQLTables @54
|
||||
SQLBrowseConnect @55
|
||||
SQLColumnPrivileges @56
|
||||
SQLDescribeParam @58
|
||||
SQLExtendedFetch @59
|
||||
SQLForeignKeys @60
|
||||
SQLMoreResults @61
|
||||
SQLNativeSql @62
|
||||
SQLNumParams @63
|
||||
SQLParamOptions @64
|
||||
SQLPrimaryKeys @65
|
||||
SQLProcedureColumns @66
|
||||
SQLProcedures @67
|
||||
SQLSetPos @68
|
||||
SQLSetScrollOptions @69
|
||||
SQLTablePrivileges @70
|
||||
SQLBindParameter @72
|
||||
|
||||
SQLAllocHandle @80
|
||||
SQLBindParam @81
|
||||
SQLCloseCursor @82
|
||||
SQLColAttribute @83
|
||||
SQLCopyDesc @84
|
||||
SQLEndTran @85
|
||||
SQLFetchScroll @86
|
||||
SQLFreeHandle @87
|
||||
SQLGetDescField @88
|
||||
SQLGetDescRec @89
|
||||
SQLGetDiagField @90
|
||||
SQLGetDiagRec @91
|
||||
SQLGetEnvAttr @92
|
||||
SQLGetConnectAttr @93
|
||||
SQLGetStmtAttr @94
|
||||
SQLSetConnectAttr @95
|
||||
SQLSetDescField @96
|
||||
SQLSetDescRec @97
|
||||
SQLSetEnvAttr @98
|
||||
SQLSetStmtAttr @99
|
||||
|
||||
SQLDummyOrdinal @199
|
||||
dconn_FDriverConnectProc @200
|
||||
DllMain @201
|
||||
ConfigDSN @202
|
||||
|
||||
SQLColAttributeW @101
|
||||
SQLColumnPrivilegesW @102
|
||||
SQLColumnsW @103
|
||||
SQLConnectW @104
|
||||
SQLDescribeColW @106
|
||||
SQLExecDirectW @107
|
||||
SQLForeignKeysW @108
|
||||
SQLGetConnectAttrW @109
|
||||
SQLGetCursorNameW @110
|
||||
SQLGetInfoW @111
|
||||
SQLNativeSqlW @112
|
||||
SQLPrepareW @113
|
||||
SQLPrimaryKeysW @114
|
||||
SQLProcedureColumnsW @115
|
||||
SQLProceduresW @116
|
||||
SQLSetConnectAttrW @117
|
||||
SQLSetCursorNameW @118
|
||||
SQLSpecialColumnsW @119
|
||||
SQLStatisticsW @120
|
||||
SQLTablesW @121
|
||||
SQLTablePrivilegesW @122
|
||||
SQLDriverConnectW @123
|
||||
SQLGetDiagRecW @124
|
||||
SQLGetStmtAttrW @125
|
||||
SQLSetStmtAttrW @126
|
||||
SQLSetDescFieldW @127
|
||||
SQLGetTypeInfoW @128
|
84
src/interfaces/odbc/psqlodbc_apiw.def
Normal file
84
src/interfaces/odbc/psqlodbc_apiw.def
Normal file
@ -0,0 +1,84 @@
|
||||
LIBRARY psqlodbc
|
||||
EXPORTS
|
||||
SQLAllocConnect @1
|
||||
SQLAllocEnv @2
|
||||
SQLAllocStmt @3
|
||||
SQLBindCol @4
|
||||
SQLCancel @5
|
||||
SQLColAttributes @6
|
||||
SQLConnect @7
|
||||
SQLDescribeCol @8
|
||||
SQLDisconnect @9
|
||||
SQLError @10
|
||||
SQLExecDirect @11
|
||||
SQLExecute @12
|
||||
SQLFetch @13
|
||||
SQLFreeConnect @14
|
||||
SQLFreeEnv @15
|
||||
SQLFreeStmt @16
|
||||
SQLGetCursorName @17
|
||||
SQLNumResultCols @18
|
||||
SQLPrepare @19
|
||||
SQLRowCount @20
|
||||
SQLSetCursorName @21
|
||||
SQLTransact @23
|
||||
SQLColumns @40
|
||||
SQLDriverConnect @41
|
||||
SQLGetConnectOption @42
|
||||
SQLGetData @43
|
||||
SQLGetFunctions @44
|
||||
SQLGetInfo @45
|
||||
SQLGetStmtOption @46
|
||||
SQLGetTypeInfo @47
|
||||
SQLParamData @48
|
||||
SQLPutData @49
|
||||
SQLSetConnectOption @50
|
||||
SQLSetStmtOption @51
|
||||
SQLSpecialColumns @52
|
||||
SQLStatistics @53
|
||||
SQLTables @54
|
||||
SQLBrowseConnect @55
|
||||
SQLColumnPrivileges @56
|
||||
SQLDescribeParam @58
|
||||
SQLExtendedFetch @59
|
||||
SQLForeignKeys @60
|
||||
SQLMoreResults @61
|
||||
SQLNativeSql @62
|
||||
SQLNumParams @63
|
||||
SQLParamOptions @64
|
||||
SQLPrimaryKeys @65
|
||||
SQLProcedureColumns @66
|
||||
SQLProcedures @67
|
||||
SQLSetPos @68
|
||||
SQLSetScrollOptions @69
|
||||
SQLTablePrivileges @70
|
||||
SQLBindParameter @72
|
||||
|
||||
SQLColAttributesW @101
|
||||
SQLColumnPrivilegesW @102
|
||||
SQLColumnsW @103
|
||||
SQLConnectW @104
|
||||
SQLDescribeColW @106
|
||||
SQLExecDirectW @107
|
||||
SQLForeignKeysW @108
|
||||
SQLGetConnectOptionW @109
|
||||
SQLGetCursorNameW @110
|
||||
SQLGetInfoW @111
|
||||
SQLNativeSqlW @112
|
||||
SQLPrepareW @113
|
||||
SQLPrimaryKeysW @114
|
||||
SQLProcedureColumnsW @115
|
||||
SQLProceduresW @116
|
||||
SQLSetConnectOptionW @117
|
||||
SQLSetCursorNameW @118
|
||||
SQLSpecialColumnsW @119
|
||||
SQLStatisticsW @120
|
||||
SQLTablesW @121
|
||||
SQLTablePrivilegesW @122
|
||||
SQLDriverConnectW @123
|
||||
SQLErrorW @124
|
||||
SQLGetTypeInfoW @128
|
||||
|
||||
dconn_FDriverConnectProc @200
|
||||
DllMain @201
|
||||
ConfigDSN @202
|
@ -108,6 +108,7 @@ QR_Constructor()
|
||||
rv->command = NULL;
|
||||
rv->notice = NULL;
|
||||
rv->conn = NULL;
|
||||
rv->next = NULL;
|
||||
rv->inTuples = FALSE;
|
||||
rv->fcount = 0;
|
||||
rv->fetch_count = 0;
|
||||
@ -160,6 +161,9 @@ QR_Destructor(QResultClass *self)
|
||||
/* Free notice info (this is from strdup()) */
|
||||
if (self->notice)
|
||||
free(self->notice);
|
||||
/* Destruct the result object in the chain */
|
||||
if (self->next)
|
||||
QR_Destructor(self->next);
|
||||
|
||||
free(self);
|
||||
|
||||
@ -247,6 +251,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
|
||||
|
||||
if (self->cursor)
|
||||
free(self->cursor);
|
||||
self->cursor = NULL;
|
||||
|
||||
if (fetch_cursor)
|
||||
{
|
||||
@ -342,7 +347,7 @@ QR_close(QResultClass *self)
|
||||
sprintf(buf, "close %s", self->cursor);
|
||||
mylog("QResult: closing cursor: '%s'\n", buf);
|
||||
|
||||
res = CC_send_query(self->conn, buf, NULL);
|
||||
res = CC_send_query(self->conn, buf, NULL, TRUE);
|
||||
|
||||
self->inTuples = FALSE;
|
||||
self->currTuple = -1;
|
||||
@ -487,13 +492,11 @@ QR_next_tuple(QResultClass *self)
|
||||
qi.row_size = self->cache_size;
|
||||
qi.result_in = self;
|
||||
qi.cursor = NULL;
|
||||
res = CC_send_query(self->conn, fetch, &qi);
|
||||
if (res == NULL || QR_get_aborted(res))
|
||||
res = CC_send_query(self->conn, fetch, &qi, TRUE);
|
||||
if (res == NULL)
|
||||
{
|
||||
self->status = PGRES_FATAL_ERROR;
|
||||
QR_set_message(self, "Error fetching next group.");
|
||||
if (res)
|
||||
QR_Destructor(res);
|
||||
return FALSE;
|
||||
}
|
||||
self->inTuples = TRUE;
|
||||
@ -689,7 +692,7 @@ QR_read_tuple(QResultClass *self, char binary)
|
||||
*/
|
||||
|
||||
flds = self->fields;
|
||||
if (flds->display_size[field_lf] < len)
|
||||
if (flds && flds->display_size && flds->display_size[field_lf] < len)
|
||||
flds->display_size[field_lf] = len;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ struct QResultClass_
|
||||
TupleListClass *manual_tuples; /* manual result tuple list */
|
||||
ConnectionClass *conn; /* the connection this result is using
|
||||
* (backend) */
|
||||
QResultClass *next; /* the following result class */
|
||||
|
||||
/* Stuff for declare/fetch tuples */
|
||||
int count_allocated; /* m(re)alloced count */
|
||||
|
@ -52,6 +52,8 @@
|
||||
#define IDC_OPTIONS 1054
|
||||
#define DRV_KSQO 1055
|
||||
#define DS_PG64 1057
|
||||
#define DS_PG63 1058
|
||||
#define DRV_OR_DSN 1059
|
||||
#define DRV_DEBUG 1060
|
||||
#define DS_DISALLOWPREMATURE 1061
|
||||
#define DS_LFCONVERSION 1062
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
* API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol,
|
||||
* SQLColAttributes, SQLGetData, SQLFetch, SQLExtendedFetch,
|
||||
* SQLMoreResults(NI), SQLSetPos, SQLSetScrollOptions(NI),
|
||||
* SQLMoreResults, SQLSetPos, SQLSetScrollOptions(NI),
|
||||
* SQLSetCursorName, SQLGetCursorName
|
||||
*
|
||||
* Comments: See "notice.txt" for copyright and license information.
|
||||
@ -45,6 +45,7 @@ PGAPI_RowCount(
|
||||
*ptr;
|
||||
ConnInfo *ci;
|
||||
|
||||
mylog("%s: entering...\n", func);
|
||||
if (!stmt)
|
||||
{
|
||||
SC_log_error(func, "", NULL);
|
||||
@ -62,7 +63,7 @@ PGAPI_RowCount(
|
||||
{
|
||||
if (stmt->status == STMT_FINISHED)
|
||||
{
|
||||
res = SC_get_Result(stmt);
|
||||
res = SC_get_Curres(stmt);
|
||||
|
||||
if (res && pcrow)
|
||||
{
|
||||
@ -73,7 +74,7 @@ PGAPI_RowCount(
|
||||
}
|
||||
else
|
||||
{
|
||||
res = SC_get_Result(stmt);
|
||||
res = SC_get_Curres(stmt);
|
||||
if (res && pcrow)
|
||||
{
|
||||
msg = QR_get_command(res);
|
||||
@ -115,6 +116,7 @@ PGAPI_NumResultCols(
|
||||
char parse_ok;
|
||||
ConnInfo *ci;
|
||||
|
||||
mylog("%s: entering...\n", func);
|
||||
if (!stmt)
|
||||
{
|
||||
SC_log_error(func, "", NULL);
|
||||
@ -144,7 +146,7 @@ PGAPI_NumResultCols(
|
||||
if (!parse_ok)
|
||||
{
|
||||
SC_pre_execute(stmt);
|
||||
result = SC_get_Result(stmt);
|
||||
result = SC_get_Curres(stmt);
|
||||
|
||||
mylog("PGAPI_NumResultCols: result = %u, status = %d, numcols = %d\n", result, stmt->status, result != NULL ? QR_NumResultCols(result) : -1);
|
||||
if ((!result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)))
|
||||
@ -210,6 +212,25 @@ PGAPI_DescribeCol(
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (0 == icol) /* bookmark column */
|
||||
{
|
||||
SQLSMALLINT fType = SQL_INTEGER;
|
||||
if (szColName && cbColNameMax > 0)
|
||||
*szColName = '\0';
|
||||
if (pcbColName)
|
||||
*pcbColName = 0;
|
||||
if (pfSqlType)
|
||||
*pfSqlType = fType;
|
||||
if (pcbColDef)
|
||||
*pcbColDef = 10;
|
||||
if (pibScale)
|
||||
*pibScale = 0;
|
||||
if (pfNullable)
|
||||
*pfNullable = SQL_NO_NULLS;
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
#endif /* ODBCVER */
|
||||
/*
|
||||
* Dont check for bookmark column. This is the responsibility of the
|
||||
* driver manager.
|
||||
@ -262,7 +283,7 @@ PGAPI_DescribeCol(
|
||||
{
|
||||
SC_pre_execute(stmt);
|
||||
|
||||
res = SC_get_Result(stmt);
|
||||
res = SC_get_Curres(stmt);
|
||||
|
||||
mylog("**** PGAPI_DescribeCol: res = %u, stmt->status = %d, !finished=%d, !premature=%d\n", res, stmt->status, stmt->status != STMT_FINISHED, stmt->status != STMT_PREMATURE);
|
||||
if ((NULL == res) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)))
|
||||
@ -305,7 +326,7 @@ PGAPI_DescribeCol(
|
||||
if (pcbColName)
|
||||
*pcbColName = len;
|
||||
|
||||
if (szColName)
|
||||
if (szColName && cbColNameMax > 0)
|
||||
{
|
||||
strncpy_null(szColName, col_name, cbColNameMax);
|
||||
|
||||
@ -379,17 +400,19 @@ PGAPI_ColAttributes(
|
||||
{
|
||||
static char *func = "PGAPI_ColAttributes";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
Int4 field_type = 0;
|
||||
ConnInfo *ci;
|
||||
Int4 col_idx, field_type = 0;
|
||||
ConnectionClass *conn;
|
||||
ConnInfo *ci;
|
||||
int unknown_sizes;
|
||||
int cols = 0;
|
||||
char parse_ok;
|
||||
RETCODE result;
|
||||
char *p = NULL;
|
||||
const char *p = NULL;
|
||||
int len = 0,
|
||||
value = 0;
|
||||
const FIELD_INFO *fi = NULL;
|
||||
|
||||
mylog("%s: entering...\n", func);
|
||||
mylog("%s: entering..col=%d %d.\n", func, icol, fDescType);
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
@ -397,7 +420,8 @@ PGAPI_ColAttributes(
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
ci = &(SC_get_conn(stmt)->connInfo);
|
||||
conn = SC_get_conn(stmt);
|
||||
ci = &(conn->connInfo);
|
||||
|
||||
/*
|
||||
* Dont check for bookmark column. This is the responsibility of the
|
||||
@ -405,7 +429,24 @@ PGAPI_ColAttributes(
|
||||
* is ignored anyway, so it may be 0.
|
||||
*/
|
||||
|
||||
icol--;
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (0 == icol) /* bookmark column */
|
||||
{
|
||||
switch (fDescType)
|
||||
{
|
||||
case SQL_DESC_OCTET_LENGTH:
|
||||
if (pfDesc)
|
||||
*pfDesc = 4;
|
||||
break;
|
||||
case SQL_DESC_TYPE:
|
||||
if (pfDesc)
|
||||
*pfDesc = SQL_INTEGER;
|
||||
break;
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
#endif /* ODBCVER */
|
||||
col_idx = icol - 1;
|
||||
|
||||
/* atoi(ci->unknown_sizes); */
|
||||
unknown_sizes = ci->drivers.unknown_sizes;
|
||||
@ -437,28 +478,30 @@ PGAPI_ColAttributes(
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[icol])
|
||||
if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[col_idx])
|
||||
{
|
||||
if (icol >= cols)
|
||||
if (col_idx >= cols)
|
||||
{
|
||||
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
|
||||
stmt->errormsg = "Invalid column number in ColAttributes.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
field_type = stmt->fi[icol]->type;
|
||||
field_type = stmt->fi[col_idx]->type;
|
||||
if (field_type > 0)
|
||||
parse_ok = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parse_ok)
|
||||
if (parse_ok)
|
||||
fi = stmt->fi[col_idx];
|
||||
else
|
||||
{
|
||||
SC_pre_execute(stmt);
|
||||
|
||||
mylog("**** PGAPI_ColAtt: result = %u, status = %d, numcols = %d\n", stmt->result, stmt->status, stmt->result != NULL ? QR_NumResultCols(stmt->result) : -1);
|
||||
mylog("**** PGAPI_ColAtt: result = %u, status = %d, numcols = %d\n", SC_get_Curres(stmt), stmt->status, SC_get_Curres(stmt) != NULL ? QR_NumResultCols(SC_get_Curres(stmt)) : -1);
|
||||
|
||||
if ((NULL == stmt->result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)))
|
||||
if ((NULL == SC_get_Curres(stmt)) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)))
|
||||
{
|
||||
stmt->errormsg = "Can't get column attributes: no result found.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
@ -466,13 +509,17 @@ PGAPI_ColAttributes(
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
cols = QR_NumResultCols(stmt->result);
|
||||
cols = QR_NumResultCols(SC_get_Curres(stmt));
|
||||
|
||||
/*
|
||||
* Column Count is a special case. The Column number is ignored
|
||||
* in this case.
|
||||
*/
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (fDescType == SQL_DESC_COUNT)
|
||||
#else
|
||||
if (fDescType == SQL_COLUMN_COUNT)
|
||||
#endif /* ODBCVER */
|
||||
{
|
||||
if (pfDesc)
|
||||
*pfDesc = cols;
|
||||
@ -480,7 +527,7 @@ PGAPI_ColAttributes(
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
||||
if (icol >= cols)
|
||||
if (col_idx >= cols)
|
||||
{
|
||||
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
|
||||
stmt->errormsg = "Invalid column number in ColAttributes.";
|
||||
@ -488,21 +535,21 @@ PGAPI_ColAttributes(
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
field_type = QR_get_field_type(stmt->result, icol);
|
||||
field_type = QR_get_field_type(SC_get_Curres(stmt), col_idx);
|
||||
}
|
||||
|
||||
mylog("colAttr: col %d field_type = %d\n", icol, field_type);
|
||||
mylog("colAttr: col %d field_type = %d\n", col_idx, field_type);
|
||||
|
||||
switch (fDescType)
|
||||
{
|
||||
case SQL_COLUMN_AUTO_INCREMENT:
|
||||
case SQL_COLUMN_AUTO_INCREMENT: /* == SQL_DESC_AUTO_UNIQUE_VALUE */
|
||||
value = pgtype_auto_increment(stmt, field_type);
|
||||
if (value == -1) /* non-numeric becomes FALSE (ODBC Doc) */
|
||||
value = FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_CASE_SENSITIVE:
|
||||
case SQL_COLUMN_CASE_SENSITIVE: /* == SQL_DESC_CASE_SENSITIVE */
|
||||
value = pgtype_case_sensitive(stmt, field_type);
|
||||
break;
|
||||
|
||||
@ -511,17 +558,17 @@ PGAPI_ColAttributes(
|
||||
*
|
||||
* case SQL_COLUMN_COUNT:
|
||||
*/
|
||||
case SQL_COLUMN_DISPLAY_SIZE:
|
||||
value = (parse_ok) ? stmt->fi[icol]->display_size : pgtype_display_size(stmt, field_type, icol, unknown_sizes);
|
||||
case SQL_COLUMN_DISPLAY_SIZE: /* == SQL_DESC_DISPLAY_SIZE */
|
||||
value = fi ? fi->display_size : pgtype_display_size(stmt, field_type, col_idx, unknown_sizes);
|
||||
|
||||
mylog("PGAPI_ColAttributes: col %d, display_size= %d\n", icol, value);
|
||||
mylog("PGAPI_ColAttributes: col %d, display_size= %d\n", col_idx, value);
|
||||
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_LABEL:
|
||||
if (parse_ok && stmt->fi[icol]->alias[0] != '\0')
|
||||
case SQL_COLUMN_LABEL: /* == SQL_DESC_LABEL */
|
||||
if (fi && fi->alias[0] != '\0')
|
||||
{
|
||||
p = stmt->fi[icol]->alias;
|
||||
p = fi->alias;
|
||||
|
||||
mylog("PGAPI_ColAttr: COLUMN_LABEL = '%s'\n", p);
|
||||
break;
|
||||
@ -529,70 +576,78 @@ PGAPI_ColAttributes(
|
||||
}
|
||||
/* otherwise same as column name -- FALL THROUGH!!! */
|
||||
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_DESC_NAME:
|
||||
#else
|
||||
case SQL_COLUMN_NAME:
|
||||
p = (parse_ok) ? stmt->fi[icol]->name : QR_get_fieldname(stmt->result, icol);
|
||||
#endif /* ODBCVER */
|
||||
p = fi ? (fi->alias[0] ? fi->alias : fi->name) : QR_get_fieldname(SC_get_Curres(stmt), col_idx);
|
||||
|
||||
mylog("PGAPI_ColAttr: COLUMN_NAME = '%s'\n", p);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_LENGTH:
|
||||
value = (parse_ok) ? stmt->fi[icol]->length : pgtype_length(stmt, field_type, icol, unknown_sizes);
|
||||
value = fi ? fi->length : pgtype_length(stmt, field_type, col_idx, unknown_sizes);
|
||||
|
||||
mylog("PGAPI_ColAttributes: col %d, length = %d\n", icol, value);
|
||||
mylog("PGAPI_ColAttributes: col %d, length = %d\n", col_idx, value);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_MONEY:
|
||||
case SQL_COLUMN_MONEY: /* == SQL_DESC_FIXED_PREC_SCALE */
|
||||
value = pgtype_money(stmt, field_type);
|
||||
break;
|
||||
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_DESC_NULLABLE:
|
||||
#else
|
||||
case SQL_COLUMN_NULLABLE:
|
||||
value = (parse_ok) ? stmt->fi[icol]->nullable : pgtype_nullable(stmt, field_type);
|
||||
#endif /* ODBCVER */
|
||||
value = fi ? fi->nullable : pgtype_nullable(stmt, field_type);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_OWNER_NAME:
|
||||
case SQL_COLUMN_OWNER_NAME: /* == SQL_DESC_SCHEMA_NAME */
|
||||
p = "";
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_PRECISION:
|
||||
value = (parse_ok) ? stmt->fi[icol]->precision : pgtype_precision(stmt, field_type, icol, unknown_sizes);
|
||||
value = fi ? fi->precision : pgtype_precision(stmt, field_type, col_idx, unknown_sizes);
|
||||
|
||||
mylog("PGAPI_ColAttributes: col %d, precision = %d\n", icol, value);
|
||||
mylog("PGAPI_ColAttributes: col %d, precision = %d\n", col_idx, value);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_QUALIFIER_NAME:
|
||||
case SQL_COLUMN_QUALIFIER_NAME: /* == SQL_DESC_CATALOG_NAME */
|
||||
p = "";
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_SCALE:
|
||||
value = pgtype_scale(stmt, field_type, icol);
|
||||
value = pgtype_scale(stmt, field_type, col_idx);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_SEARCHABLE:
|
||||
case SQL_COLUMN_SEARCHABLE: /* SQL_DESC_SEARCHABLE */
|
||||
value = pgtype_searchable(stmt, field_type);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_TABLE_NAME:
|
||||
p = (parse_ok && stmt->fi[icol]->ti) ? stmt->fi[icol]->ti->name : "";
|
||||
case SQL_COLUMN_TABLE_NAME: /* == SQL_DESC_TABLE_NAME */
|
||||
p = fi && (fi->ti) ? fi->ti->name : "";
|
||||
|
||||
mylog("PGAPI_ColAttr: TABLE_NAME = '%s'\n", p);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_TYPE:
|
||||
case SQL_COLUMN_TYPE: /* == SQL_DESC_CONCISE_TYPE */
|
||||
value = pgtype_to_sqltype(stmt, field_type);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_TYPE_NAME:
|
||||
case SQL_COLUMN_TYPE_NAME: /* == SQL_DESC_TYPE_NAME */
|
||||
p = pgtype_to_name(stmt, field_type);
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_UNSIGNED:
|
||||
case SQL_COLUMN_UNSIGNED: /* == SQL_DESC_UNSINGED */
|
||||
value = pgtype_unsigned(stmt, field_type);
|
||||
if (value == -1) /* non-numeric becomes TRUE (ODBC Doc) */
|
||||
value = TRUE;
|
||||
|
||||
break;
|
||||
|
||||
case SQL_COLUMN_UPDATABLE:
|
||||
case SQL_COLUMN_UPDATABLE: /* == SQL_DESC_UPDATABLE */
|
||||
|
||||
/*
|
||||
* Neither Access or Borland care about this.
|
||||
@ -604,6 +659,60 @@ PGAPI_ColAttributes(
|
||||
|
||||
mylog("PGAPI_ColAttr: UPDATEABLE = %d\n", value);
|
||||
break;
|
||||
#if (ODBCVER >= 0x0300)
|
||||
case SQL_DESC_BASE_COLUMN_NAME:
|
||||
|
||||
p = fi ? fi->name : QR_get_fieldname(SC_get_Curres(stmt), col_idx);
|
||||
|
||||
mylog("PGAPI_ColAttr: BASE_COLUMN_NAME = '%s'\n", p);
|
||||
break;
|
||||
case SQL_DESC_BASE_TABLE_NAME: /* the same as TABLE_NAME ok ? */
|
||||
p = fi && (fi->ti) ? fi->ti->name : "";
|
||||
|
||||
mylog("PGAPI_ColAttr: BASE_TABLE_NAME = '%s'\n", p);
|
||||
break;
|
||||
case SQL_DESC_LENGTH: /* different from SQL_COLUMN_LENGTH */
|
||||
value = fi ? fi->length : pgtype_length(stmt, field_type, col_idx, unknown_sizes);
|
||||
|
||||
mylog("PGAPI_ColAttributes: col %d, length = %d\n", col_idx, value);
|
||||
break;
|
||||
case SQL_DESC_OCTET_LENGTH:
|
||||
value = fi ? fi->length : pgtype_length(stmt, field_type, col_idx, unknown_sizes);
|
||||
|
||||
mylog("PGAPI_ColAttributes: col %d, octet_length = %d\n", col_idx, value);
|
||||
break;
|
||||
case SQL_DESC_PRECISION: /* different from SQL_COLUMN_PRECISION */
|
||||
value = fi ? fi->precision : pgtype_precision(stmt, field_type, col_idx, unknown_sizes);
|
||||
|
||||
mylog("PGAPI_ColAttributes: col %d, desc_precision = %d\n", col_idx, value);
|
||||
break;
|
||||
case SQL_DESC_SCALE: /* different from SQL_COLUMN_SCALE */
|
||||
value = pgtype_scale(stmt, field_type, col_idx);
|
||||
break;
|
||||
case SQL_DESC_LOCAL_TYPE_NAME:
|
||||
p = pgtype_to_name(stmt, field_type);
|
||||
break;
|
||||
case SQL_DESC_TYPE:
|
||||
value = pgtype_to_sqltype(stmt, field_type);
|
||||
switch (value)
|
||||
{
|
||||
case SQL_TYPE_DATE:
|
||||
case SQL_TYPE_TIME:
|
||||
case SQL_TYPE_TIMESTAMP:
|
||||
value = SQL_DATETIME;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SQL_DESC_LITERAL_PREFIX:
|
||||
case SQL_DESC_LITERAL_SUFFIX:
|
||||
case SQL_DESC_NUM_PREC_RADIX:
|
||||
case SQL_DESC_UNNAMED:
|
||||
#endif /* ODBCVER */
|
||||
default:
|
||||
stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
|
||||
stmt->errormsg = "ColAttribute for this type not implemented yet";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
result = SQL_SUCCESS;
|
||||
@ -614,6 +723,14 @@ PGAPI_ColAttributes(
|
||||
|
||||
if (rgbDesc)
|
||||
{
|
||||
#ifdef UNICODE_SUPPORT
|
||||
if (conn->unicode)
|
||||
{
|
||||
len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbDesc, cbDescMax / 2);
|
||||
len *= 2;
|
||||
}
|
||||
else
|
||||
#endif /* UNICODE_SUPPORT */
|
||||
strncpy_null((char *) rgbDesc, p, (size_t) cbDescMax);
|
||||
|
||||
if (len >= cbDescMax)
|
||||
@ -667,7 +784,7 @@ PGAPI_GetData(
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
ci = &(SC_get_conn(stmt)->connInfo);
|
||||
res = stmt->result;
|
||||
res = SC_get_Curres(stmt);
|
||||
|
||||
if (STMT_EXECUTING == stmt->status)
|
||||
{
|
||||
@ -834,7 +951,7 @@ PGAPI_Fetch(
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
QResultClass *res;
|
||||
|
||||
mylog("PGAPI_Fetch: stmt = %u, stmt->result= %u\n", stmt, stmt->result);
|
||||
mylog("PGAPI_Fetch: stmt = %u, stmt->result= %u\n", stmt, SC_get_Curres(stmt));
|
||||
|
||||
if (!stmt)
|
||||
{
|
||||
@ -844,7 +961,7 @@ PGAPI_Fetch(
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
{
|
||||
stmt->errormsg = "Null statement result in PGAPI_Fetch.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
@ -935,7 +1052,7 @@ PGAPI_ExtendedFetch(
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
{
|
||||
stmt->errormsg = "Null statement result in PGAPI_ExtendedFetch.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
@ -1214,6 +1331,15 @@ RETCODE SQL_API
|
||||
PGAPI_MoreResults(
|
||||
HSTMT hstmt)
|
||||
{
|
||||
const char *func = "PGAPI_MoreResults";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
QResultClass *res;
|
||||
|
||||
mylog("%s: entering...\n", func);
|
||||
if (stmt && (res = SC_get_Curres(stmt)))
|
||||
SC_get_Curres(stmt) = res->next;
|
||||
if (SC_get_Curres(stmt))
|
||||
return SQL_SUCCESS;
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
@ -1243,12 +1369,7 @@ positioned_load(StatementClass *stmt, BOOL latest, int res_cols, UInt4 oid, cons
|
||||
}
|
||||
sprintf(selstr, "%s oid = %u", selstr, oid),
|
||||
mylog("selstr=%s\n", selstr);
|
||||
qres = CC_send_query(SC_get_conn(stmt), selstr, NULL);
|
||||
if (qres && QR_aborted(qres))
|
||||
{
|
||||
QR_Destructor(qres);
|
||||
qres = (QResultClass *) 0;
|
||||
}
|
||||
qres = CC_send_query(SC_get_conn(stmt), selstr, NULL, TRUE);
|
||||
return qres;
|
||||
}
|
||||
|
||||
@ -1270,7 +1391,7 @@ SC_pos_reload(StatementClass *stmt, UWORD irow, UWORD *count)
|
||||
rcnt = 0;
|
||||
if (count)
|
||||
*count = 0;
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
return SQL_ERROR;
|
||||
if (!stmt->ti)
|
||||
parse_statement(stmt); /* not preferable */
|
||||
@ -1339,7 +1460,7 @@ SC_pos_newload(StatementClass *stmt, UInt4 oid, const char *tidval)
|
||||
RETCODE ret = SQL_ERROR;
|
||||
|
||||
mylog("positioned new fi=%x ti=%x\n", stmt->fi, stmt->ti);
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
return SQL_ERROR;
|
||||
if (!stmt->ti)
|
||||
parse_statement(stmt); /* not preferable */
|
||||
@ -1401,6 +1522,41 @@ SC_pos_newload(StatementClass *stmt, UInt4 oid, const char *tidval)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RETCODE SQL_API
|
||||
irow_update(RETCODE ret, StatementClass *stmt, UWORD irow)
|
||||
{
|
||||
if (ret != SQL_ERROR)
|
||||
{
|
||||
int updcnt;
|
||||
const char *cmdstr = QR_get_command(SC_get_Curres(stmt));
|
||||
|
||||
if (cmdstr &&
|
||||
sscanf(cmdstr, "UPDATE %d", &updcnt) == 1)
|
||||
{
|
||||
if (updcnt == 1)
|
||||
SC_pos_reload(stmt, irow, (UWORD *) 0);
|
||||
else if (updcnt == 0)
|
||||
{
|
||||
stmt->errornumber = STMT_ROW_VERSION_CHANGED;
|
||||
stmt->errormsg = "the content was changed before updation";
|
||||
ret = SQL_ERROR;
|
||||
if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN)
|
||||
SC_pos_reload(stmt, irow, (UWORD *) 0);
|
||||
}
|
||||
else
|
||||
ret = SQL_ERROR;
|
||||
stmt->currTuple = stmt->rowset_start + irow;
|
||||
}
|
||||
else
|
||||
ret = SQL_ERROR;
|
||||
if (ret == SQL_ERROR && stmt->errornumber == 0)
|
||||
{
|
||||
stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND;
|
||||
stmt->errormsg = "SetPos update return error";
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
RETCODE SQL_API
|
||||
SC_pos_update(StatementClass *stmt,
|
||||
UWORD irow)
|
||||
@ -1419,8 +1575,8 @@ SC_pos_update(StatementClass *stmt,
|
||||
UInt4 offset;
|
||||
Int4 *used;
|
||||
|
||||
mylog("POS UPDATE %d+%d fi=%x ti=%x\n", irow, stmt->result->base, stmt->fi, stmt->ti);
|
||||
if (!(res = stmt->result))
|
||||
mylog("POS UPDATE %d+%d fi=%x ti=%x\n", irow, SC_get_Curres(stmt)->base, stmt->fi, stmt->ti);
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
return SQL_ERROR;
|
||||
if (!stmt->ti)
|
||||
parse_statement(stmt); /* not preferable */
|
||||
@ -1510,40 +1666,12 @@ SC_pos_update(StatementClass *stmt,
|
||||
stmt->errormsg = "SetPos with data_at_exec not yet supported";
|
||||
ret = SQL_ERROR;
|
||||
}
|
||||
if (ret != SQL_ERROR)
|
||||
{
|
||||
int updcnt;
|
||||
const char *cmdstr = QR_get_command(qstmt->result);
|
||||
|
||||
if (cmdstr &&
|
||||
sscanf(cmdstr, "UPDATE %d", &updcnt) == 1)
|
||||
{
|
||||
if (updcnt == 1)
|
||||
SC_pos_reload(stmt, irow, (UWORD *) 0);
|
||||
else if (updcnt == 0)
|
||||
{
|
||||
stmt->errornumber = STMT_ROW_VERSION_CHANGED;
|
||||
stmt->errormsg = "the content was changed before updation";
|
||||
ret = SQL_ERROR;
|
||||
if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN)
|
||||
SC_pos_reload(stmt, irow, (UWORD *) 0);
|
||||
}
|
||||
else
|
||||
ret = SQL_ERROR;
|
||||
stmt->currTuple = stmt->rowset_start + irow;
|
||||
}
|
||||
else
|
||||
ret = SQL_ERROR;
|
||||
if (ret == SQL_ERROR && stmt->errornumber == 0)
|
||||
{
|
||||
stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND;
|
||||
stmt->errormsg = "SetPos update return error";
|
||||
}
|
||||
}
|
||||
ret = irow_update(ret, qstmt, irow);
|
||||
PGAPI_FreeStmt(hstmt, SQL_DROP);
|
||||
}
|
||||
else
|
||||
ret = SQL_SUCCESS_WITH_INFO;
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (stmt->options.rowStatusArray)
|
||||
{
|
||||
switch (ret)
|
||||
@ -1556,6 +1684,7 @@ SC_pos_update(StatementClass *stmt,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ODBCVER */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1573,7 +1702,7 @@ SC_pos_delete(StatementClass *stmt,
|
||||
char *oidval;
|
||||
|
||||
mylog("POS DELETE fi=%x ti=%x\n", stmt->fi, stmt->ti);
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
return SQL_ERROR;
|
||||
if (!stmt->ti)
|
||||
parse_statement(stmt); /* not preferable */
|
||||
@ -1591,11 +1720,11 @@ SC_pos_delete(StatementClass *stmt,
|
||||
}
|
||||
sprintf(dltstr, "delete from \"%s\" where ctid = '%s' and oid = %s",
|
||||
stmt->ti[0]->name,
|
||||
QR_get_value_backend_row(stmt->result, global_ridx, res_cols - 2),
|
||||
QR_get_value_backend_row(SC_get_Curres(stmt), global_ridx, res_cols - 2),
|
||||
oidval);
|
||||
|
||||
mylog("dltstr=%s\n", dltstr);
|
||||
qres = CC_send_query(SC_get_conn(stmt), dltstr, NULL);
|
||||
qres = CC_send_query(SC_get_conn(stmt), dltstr, NULL, TRUE);
|
||||
if (qres && QR_command_successful(qres))
|
||||
{
|
||||
int dltcnt;
|
||||
@ -1630,6 +1759,7 @@ SC_pos_delete(StatementClass *stmt,
|
||||
}
|
||||
if (qres)
|
||||
QR_Destructor(qres);
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (stmt->options.rowStatusArray)
|
||||
{
|
||||
switch (ret)
|
||||
@ -1642,6 +1772,40 @@ SC_pos_delete(StatementClass *stmt,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ODBCVER */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RETCODE SQL_API
|
||||
irow_insert(RETCODE ret, StatementClass *stmt, int addpos)
|
||||
{
|
||||
if (ret != SQL_ERROR)
|
||||
{
|
||||
int addcnt;
|
||||
UInt4 oid;
|
||||
const char *cmdstr = QR_get_command(SC_get_Curres(stmt));
|
||||
|
||||
if (cmdstr &&
|
||||
sscanf(cmdstr, "INSERT %u %d", &oid, &addcnt) == 2 &&
|
||||
addcnt == 1)
|
||||
{
|
||||
SC_pos_newload(stmt, oid, NULL);
|
||||
if (stmt->bookmark.buffer)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
sprintf(buf, "%ld", addpos);
|
||||
copy_and_convert_field(stmt, 0, buf,
|
||||
SQL_C_ULONG, stmt->bookmark.buffer,
|
||||
0, stmt->bookmark.used);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND;
|
||||
stmt->errormsg = "SetPos insert return error";
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
RETCODE SQL_API
|
||||
@ -1661,7 +1825,7 @@ SC_pos_add(StatementClass *stmt,
|
||||
Int4 *used;
|
||||
|
||||
mylog("POS ADD fi=%x ti=%x\n", stmt->fi, stmt->ti);
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
return SQL_ERROR;
|
||||
if (!stmt->ti)
|
||||
parse_statement(stmt); /* not preferable */
|
||||
@ -1721,50 +1885,24 @@ SC_pos_add(StatementClass *stmt,
|
||||
mylog("addstr=%s\n", addstr);
|
||||
qstmt->exec_start_row = qstmt->exec_end_row = irow;
|
||||
ret = PGAPI_ExecDirect(hstmt, addstr, strlen(addstr));
|
||||
if (ret == SQL_NEED_DATA) /* must be fixed */
|
||||
if (ret == SQL_ERROR)
|
||||
{
|
||||
stmt->errornumber = qstmt->errornumber;
|
||||
stmt->errormsg = qstmt->errormsg;
|
||||
}
|
||||
else if (ret == SQL_NEED_DATA) /* must be fixed */
|
||||
{
|
||||
stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
|
||||
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
||||
stmt->errormsg = "SetPos with data_at_exec not yet supported";
|
||||
ret = SQL_ERROR;
|
||||
}
|
||||
if (ret == SQL_ERROR)
|
||||
{
|
||||
stmt->errornumber = qstmt->errornumber;
|
||||
stmt->errormsg = qstmt->errormsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
int addcnt;
|
||||
UInt4 oid;
|
||||
const char *cmdstr = QR_get_command(qstmt->result);
|
||||
|
||||
if (cmdstr &&
|
||||
sscanf(cmdstr, "INSERT %u %d", &oid, &addcnt) == 2 &&
|
||||
addcnt == 1)
|
||||
{
|
||||
SC_pos_newload(stmt, oid, NULL);
|
||||
if (stmt->bookmark.buffer)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
sprintf(buf, "%ld", res->fcount);
|
||||
copy_and_convert_field(stmt, 0, buf,
|
||||
SQL_C_ULONG, stmt->bookmark.buffer,
|
||||
0, stmt->bookmark.used);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND;
|
||||
stmt->errormsg = "SetPos insert return error";
|
||||
ret = SQL_ERROR;
|
||||
}
|
||||
}
|
||||
ret = irow_insert(ret, qstmt, res->fcount);
|
||||
}
|
||||
else
|
||||
ret = SQL_SUCCESS_WITH_INFO;
|
||||
PGAPI_FreeStmt(hstmt, SQL_DROP);
|
||||
#if (ODBCVER >= 0x0300)
|
||||
if (stmt->options.rowStatusArray)
|
||||
{
|
||||
switch (ret)
|
||||
@ -1777,6 +1915,8 @@ SC_pos_add(StatementClass *stmt,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ODBCVER */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1823,7 +1963,7 @@ PGAPI_SetPos(
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if (!(res = stmt->result))
|
||||
if (!(res = SC_get_Curres(stmt)))
|
||||
{
|
||||
stmt->errormsg = "Null statement result in PGAPI_SetPos.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
|
@ -90,7 +90,6 @@ ConfigDSN(HWND hwnd,
|
||||
if (!hglbAttr)
|
||||
return FALSE;
|
||||
lpsetupdlg = (LPSETUPDLG) GlobalLock(hglbAttr);
|
||||
|
||||
/* Parse attribute string */
|
||||
if (lpszAttributes)
|
||||
ParseAttributes(lpszAttributes, lpsetupdlg);
|
||||
@ -339,7 +338,7 @@ ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
|
||||
int cbKey;
|
||||
char value[MAXPGPATH];
|
||||
|
||||
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
|
||||
CC_conninfo_init(&(lpsetupdlg->ci));
|
||||
|
||||
for (lpsz = lpszAttributes; *lpsz; lpsz++)
|
||||
{
|
||||
|
@ -159,10 +159,10 @@ PGAPI_FreeStmt(HSTMT hstmt,
|
||||
}
|
||||
|
||||
/* Free any cursors and discard any result info */
|
||||
if (stmt->result)
|
||||
if (SC_get_Result(stmt))
|
||||
{
|
||||
QR_Destructor(stmt->result);
|
||||
stmt->result = NULL;
|
||||
QR_Destructor(SC_get_Result(stmt));
|
||||
SC_set_Result(stmt, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,6 +230,7 @@ SC_Constructor(void)
|
||||
rv->hdbc = NULL; /* no connection associated yet */
|
||||
rv->phstmt = NULL;
|
||||
rv->result = NULL;
|
||||
rv->curres = NULL;
|
||||
rv->manual_result = FALSE;
|
||||
rv->prepare = FALSE;
|
||||
rv->status = STMT_ALLOCATED;
|
||||
@ -238,7 +239,6 @@ SC_Constructor(void)
|
||||
rv->errormsg = NULL;
|
||||
rv->errornumber = 0;
|
||||
rv->errormsg_created = FALSE;
|
||||
rv->errormsg_malloced = FALSE;
|
||||
|
||||
rv->statement = NULL;
|
||||
rv->stmt_with_params = NULL;
|
||||
@ -292,7 +292,9 @@ SC_Constructor(void)
|
||||
char
|
||||
SC_Destructor(StatementClass *self)
|
||||
{
|
||||
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc);
|
||||
QResultClass *res = SC_get_Result(self);
|
||||
|
||||
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, res, self->hdbc);
|
||||
SC_clear_error(self);
|
||||
if (STMT_EXECUTING == self->status)
|
||||
{
|
||||
@ -301,12 +303,12 @@ SC_Destructor(StatementClass *self)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (self->result)
|
||||
if (res)
|
||||
{
|
||||
if (!self->hdbc)
|
||||
self->result->conn = NULL; /* prevent any dbase activity */
|
||||
res->conn = NULL; /* prevent any dbase activity */
|
||||
|
||||
QR_Destructor(self->result);
|
||||
QR_Destructor(res);
|
||||
}
|
||||
|
||||
if (self->statement)
|
||||
@ -442,6 +444,7 @@ char
|
||||
SC_recycle_statement(StatementClass *self)
|
||||
{
|
||||
ConnectionClass *conn;
|
||||
QResultClass *res;
|
||||
|
||||
mylog("recycle statement: self= %u\n", self);
|
||||
|
||||
@ -514,10 +517,10 @@ SC_recycle_statement(StatementClass *self)
|
||||
self->parse_status = STMT_PARSE_NONE;
|
||||
|
||||
/* Free any cursors */
|
||||
if (self->result)
|
||||
if (res = SC_get_Result(self), res)
|
||||
{
|
||||
QR_Destructor(self->result);
|
||||
self->result = NULL;
|
||||
QR_Destructor(res);
|
||||
SC_set_Result(self, NULL);
|
||||
}
|
||||
self->inaccurate_result = FALSE;
|
||||
|
||||
@ -533,12 +536,9 @@ SC_recycle_statement(StatementClass *self)
|
||||
self->bind_row = 0;
|
||||
self->last_fetch_count = 0;
|
||||
|
||||
if (self->errormsg_malloced && self->errormsg)
|
||||
free(self->errormsg);
|
||||
self->errormsg = NULL;
|
||||
self->errornumber = 0;
|
||||
self->errormsg_created = FALSE;
|
||||
self->errormsg_malloced = FALSE;
|
||||
|
||||
self->lobj_fd = -1;
|
||||
|
||||
@ -583,8 +583,8 @@ SC_pre_execute(StatementClass *self)
|
||||
}
|
||||
if (!SC_is_pre_executable(self))
|
||||
{
|
||||
self->result = QR_Constructor();
|
||||
QR_set_status(self->result, PGRES_TUPLES_OK);
|
||||
SC_set_Result(self, QR_Constructor());
|
||||
QR_set_status(SC_get_Result(self), PGRES_TUPLES_OK);
|
||||
self->inaccurate_result = TRUE;
|
||||
self->status = STMT_PREMATURE;
|
||||
}
|
||||
@ -617,12 +617,11 @@ SC_unbind_cols(StatementClass *self)
|
||||
void
|
||||
SC_clear_error(StatementClass *self)
|
||||
{
|
||||
if (self->errormsg_malloced && self->errormsg)
|
||||
free(self->errormsg);
|
||||
self->errornumber = 0;
|
||||
self->errormsg = NULL;
|
||||
self->errormsg_created = FALSE;
|
||||
self->errormsg_malloced = FALSE;
|
||||
self->errorpos = 0;
|
||||
self->error_recsize = -1;
|
||||
}
|
||||
|
||||
|
||||
@ -633,7 +632,7 @@ SC_clear_error(StatementClass *self)
|
||||
char *
|
||||
SC_create_errormsg(StatementClass *self)
|
||||
{
|
||||
QResultClass *res = self->result;
|
||||
QResultClass *res = SC_get_Curres(self);
|
||||
ConnectionClass *conn = self->hdbc;
|
||||
int pos;
|
||||
static char msg[4096];
|
||||
@ -642,10 +641,21 @@ SC_create_errormsg(StatementClass *self)
|
||||
|
||||
if (res && res->message)
|
||||
strcpy(msg, res->message);
|
||||
|
||||
else if (self->errormsg)
|
||||
strcpy(msg, self->errormsg);
|
||||
|
||||
if (!msg[0] && res && QR_get_notice(res))
|
||||
{
|
||||
char *notice = QR_get_notice(res);
|
||||
int len = strlen(notice);
|
||||
if (len < sizeof(msg))
|
||||
{
|
||||
memcpy(msg, notice, len);
|
||||
msg[len] = '\0';
|
||||
}
|
||||
else
|
||||
return notice;
|
||||
}
|
||||
if (conn)
|
||||
{
|
||||
SocketClass *sock = conn->sock;
|
||||
@ -653,7 +663,7 @@ SC_create_errormsg(StatementClass *self)
|
||||
if (conn->errormsg && conn->errormsg[0] != '\0')
|
||||
{
|
||||
pos = strlen(msg);
|
||||
sprintf(&msg[pos], ";\n%s", conn->errormsg);
|
||||
/*sprintf(&msg[pos], ";\n%s", conn->errormsg);*/
|
||||
}
|
||||
|
||||
if (sock && sock->errormsg && sock->errormsg[0] != '\0')
|
||||
@ -662,9 +672,6 @@ SC_create_errormsg(StatementClass *self)
|
||||
sprintf(&msg[pos], ";\n%s", sock->errormsg);
|
||||
}
|
||||
}
|
||||
if (!msg[0] && res && QR_get_notice(res))
|
||||
return QR_get_notice(res);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@ -679,18 +686,17 @@ SC_get_error(StatementClass *self, int *number, char **message)
|
||||
{
|
||||
self->errormsg = SC_create_errormsg(self);
|
||||
self->errormsg_created = TRUE;
|
||||
self->errorpos = 0;
|
||||
self->error_recsize = -1;
|
||||
}
|
||||
|
||||
if (self->errornumber)
|
||||
{
|
||||
*number = self->errornumber;
|
||||
*message = self->errormsg;
|
||||
if (!self->errormsg_malloced)
|
||||
self->errormsg = NULL;
|
||||
}
|
||||
|
||||
rv = (self->errornumber != 0);
|
||||
self->errornumber = 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -712,7 +718,7 @@ RETCODE
|
||||
SC_fetch(StatementClass *self)
|
||||
{
|
||||
static char *func = "SC_fetch";
|
||||
QResultClass *res = self->result;
|
||||
QResultClass *res = SC_get_Curres(self);
|
||||
int retval,
|
||||
result;
|
||||
|
||||
@ -901,6 +907,7 @@ SC_execute(StatementClass *self)
|
||||
static char *func = "SC_execute";
|
||||
ConnectionClass *conn;
|
||||
char was_ok, was_nonfatal;
|
||||
QResultClass *res = NULL;
|
||||
Int2 oldstatus,
|
||||
numcols;
|
||||
QueryInfo qi;
|
||||
@ -952,12 +959,12 @@ SC_execute(StatementClass *self)
|
||||
mylog(" Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name);
|
||||
|
||||
/* send the declare/select */
|
||||
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
|
||||
res = CC_send_query(conn, self->stmt_with_params, NULL, TRUE);
|
||||
|
||||
if (SC_is_fetchcursor(self) && self->result != NULL &&
|
||||
QR_command_successful(self->result))
|
||||
if (SC_is_fetchcursor(self) && res != NULL &&
|
||||
QR_command_successful(res))
|
||||
{
|
||||
QR_Destructor(self->result);
|
||||
QR_Destructor(res);
|
||||
|
||||
/*
|
||||
* That worked, so now send the fetch to start getting data
|
||||
@ -976,7 +983,7 @@ SC_execute(StatementClass *self)
|
||||
*/
|
||||
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
|
||||
|
||||
self->result = CC_send_query(conn, fetch, &qi);
|
||||
res = CC_send_query(conn, fetch, &qi, FALSE);
|
||||
}
|
||||
mylog(" done sending the query:\n");
|
||||
}
|
||||
@ -984,7 +991,7 @@ SC_execute(StatementClass *self)
|
||||
{
|
||||
/* not a SELECT statement so don't use a cursor */
|
||||
mylog(" it's NOT a select statement: stmt=%u\n", self);
|
||||
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
|
||||
res = CC_send_query(conn, self->stmt_with_params, NULL, FALSE);
|
||||
|
||||
/*
|
||||
* We shouldn't send COMMIT. Postgres backend does the autocommit
|
||||
@ -1003,10 +1010,10 @@ SC_execute(StatementClass *self)
|
||||
self->status = STMT_FINISHED;
|
||||
|
||||
/* Check the status of the result */
|
||||
if (self->result)
|
||||
if (res)
|
||||
{
|
||||
was_ok = QR_command_successful(self->result);
|
||||
was_nonfatal = QR_command_nonfatal(self->result);
|
||||
was_ok = QR_command_successful(res);
|
||||
was_nonfatal = QR_command_nonfatal(res);
|
||||
|
||||
if (was_ok)
|
||||
self->errornumber = STMT_OK;
|
||||
@ -1018,24 +1025,30 @@ SC_execute(StatementClass *self)
|
||||
self->current_col = -1;
|
||||
self->rowset_start = -1;
|
||||
|
||||
/* see if the query did return any result columns */
|
||||
numcols = QR_NumResultCols(self->result);
|
||||
|
||||
/* now allocate the array to hold the binding info */
|
||||
if (numcols > 0)
|
||||
/* issue "ABORT" when query aborted */
|
||||
if (QR_get_aborted(res))
|
||||
{
|
||||
extend_bindings(self, numcols);
|
||||
if (self->bindings == NULL)
|
||||
if (!self->internal)
|
||||
CC_abort(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* see if the query did return any result columns */
|
||||
numcols = QR_NumResultCols(res);
|
||||
/* now allocate the array to hold the binding info */
|
||||
if (numcols > 0)
|
||||
{
|
||||
self->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
self->errormsg = "Could not get enough free memory to store the binding information";
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
extend_bindings(self, numcols);
|
||||
if (self->bindings == NULL)
|
||||
{
|
||||
QR_Destructor(res);
|
||||
self->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
self->errormsg = "Could not get enough free memory to store the binding information";
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* issue "ABORT" when query aborted */
|
||||
if (QR_get_aborted(self->result) && !self->internal)
|
||||
CC_abort(conn);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1061,6 +1074,15 @@ SC_execute(StatementClass *self)
|
||||
if (!self->internal)
|
||||
CC_abort(conn);
|
||||
}
|
||||
if (!SC_get_Result(self))
|
||||
SC_set_Result(self, res);
|
||||
else
|
||||
{
|
||||
QResultClass *last;
|
||||
for (last = SC_get_Result(self); last->next; last = last->next)
|
||||
;
|
||||
last->next = res;
|
||||
}
|
||||
|
||||
if (self->statement_type == STMT_TYPE_PROCCALL &&
|
||||
(self->errornumber == STMT_OK ||
|
||||
@ -1095,7 +1117,8 @@ SC_execute(StatementClass *self)
|
||||
return SQL_SUCCESS_WITH_INFO;
|
||||
else
|
||||
{
|
||||
self->errormsg = "Error while executing the query";
|
||||
if (!self->errormsg || !self->errormsg[0])
|
||||
self->errormsg = "Error while executing the query";
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
@ -1103,17 +1126,19 @@ SC_execute(StatementClass *self)
|
||||
|
||||
|
||||
void
|
||||
SC_log_error(char *func, char *desc, StatementClass *self)
|
||||
SC_log_error(const char *func, const char *desc, const StatementClass *self)
|
||||
{
|
||||
#ifdef PRN_NULLCHECK
|
||||
#define nullcheck(a) (a ? a : "(NULL)")
|
||||
#endif
|
||||
if (self)
|
||||
{
|
||||
QResultClass *res = SC_get_Result(self);
|
||||
|
||||
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
|
||||
mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, nullcheck(self->errormsg));
|
||||
qlog(" ------------------------------------------------------------\n");
|
||||
qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, self->result);
|
||||
qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, res);
|
||||
qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal);
|
||||
qlog(" bindings=%u, bindings_allocated=%d\n", self->bindings, self->bindings_allocated);
|
||||
qlog(" parameters=%u, parameters_allocated=%d\n", self->parameters, self->parameters_allocated);
|
||||
@ -1126,10 +1151,8 @@ SC_log_error(char *func, char *desc, StatementClass *self)
|
||||
|
||||
qlog(" ----------------QResult Info -------------------------------\n");
|
||||
|
||||
if (self->result)
|
||||
if (res)
|
||||
{
|
||||
QResultClass *res = self->result;
|
||||
|
||||
qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn);
|
||||
qlog(" fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, nullcheck(res->cursor));
|
||||
qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice));
|
||||
@ -1140,6 +1163,9 @@ SC_log_error(char *func, char *desc, StatementClass *self)
|
||||
CC_log_error(func, desc, self->hdbc);
|
||||
}
|
||||
else
|
||||
{
|
||||
qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
mylog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
}
|
||||
#undef PRN_NULLCHECK
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ enum
|
||||
STMT_PARSE_NONE = 0,
|
||||
STMT_PARSE_COMPLETE,
|
||||
STMT_PARSE_INCOMPLETE,
|
||||
STMT_PARSE_FATAL
|
||||
STMT_PARSE_FATAL,
|
||||
};
|
||||
|
||||
/* Result style */
|
||||
@ -111,7 +111,7 @@ enum
|
||||
{
|
||||
STMT_FETCH_NONE = 0,
|
||||
STMT_FETCH_NORMAL,
|
||||
STMT_FETCH_EXTENDED
|
||||
STMT_FETCH_EXTENDED,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@ -147,6 +147,7 @@ struct StatementClass_
|
||||
ConnectionClass *hdbc; /* pointer to ConnectionClass this
|
||||
* statement belongs to */
|
||||
QResultClass *result; /* result of the current statement */
|
||||
QResultClass *curres; /* the current result in the chain */
|
||||
HSTMT FAR *phstmt;
|
||||
StatementOptions options;
|
||||
|
||||
@ -215,14 +216,15 @@ struct StatementClass_
|
||||
char pre_executing; /* This statement is prematurely executing */
|
||||
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;
|
||||
SWORD errorpos;
|
||||
SWORD error_recsize;
|
||||
};
|
||||
|
||||
#define SC_get_conn(a) (a->hdbc)
|
||||
#define SC_get_Result(a) (a->result);
|
||||
#define SC_set_Result(a, b) (a->result = a->curres = b)
|
||||
#define SC_get_Result(a) (a->result)
|
||||
#define SC_get_Curres(a) (a->curres)
|
||||
|
||||
/* options for SC_free_params() */
|
||||
#define STMT_FREE_PARAMS_ALL 0
|
||||
@ -252,7 +254,7 @@ char *SC_create_errormsg(StatementClass *self);
|
||||
RETCODE SC_execute(StatementClass *self);
|
||||
RETCODE SC_fetch(StatementClass *self);
|
||||
void SC_free_params(StatementClass *self, char option);
|
||||
void SC_log_error(char *func, char *desc, StatementClass *self);
|
||||
void SC_log_error(const char *func, const char *desc, const StatementClass *self);
|
||||
unsigned long SC_get_bookmark(StatementClass *self);
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@ CFG=Release
|
||||
!MESSAGE "Release" (Win32 Release DLL)
|
||||
!MESSAGE "Debug" (Win32 Debug DLL)
|
||||
!MESSAGE "MultibyteRelease" (Win32 Release DLL with Multibyte support)
|
||||
!MESSAGE "MultibyteDebug" (Win32 Release DLL with Multibyte support)
|
||||
!MESSAGE "MultibyteDebug" (Win32 Debug DLL with Multibyte support)
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration was specified.
|
||||
!ENDIF
|
||||
@ -46,13 +46,15 @@ NULL=nul
|
||||
|
||||
!IF "$(CFG)" == "MultibyteRelease"
|
||||
OUTDIR=.\MultibyteRelease
|
||||
OUTDIRBIN=.\MultibyteRelease
|
||||
INTDIR=.\MultibyteRelease
|
||||
!ELSE
|
||||
OUTDIR=.\Release
|
||||
OUTDIRBIN=.\Release
|
||||
INTDIR=.\Release
|
||||
!ENDIF
|
||||
|
||||
ALL : "$(OUTDIR)\psqlodbc.dll"
|
||||
ALL : "$(OUTDIRBIN)\psqlodbc.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
@ -64,7 +66,6 @@ CLEAN :
|
||||
-@erase "$(INTDIR)\drvconn.obj"
|
||||
-@erase "$(INTDIR)\environ.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\gpps.obj"
|
||||
-@erase "$(INTDIR)\info.obj"
|
||||
-@erase "$(INTDIR)\lobj.obj"
|
||||
-@erase "$(INTDIR)\win_md5.obj"
|
||||
@ -139,7 +140,7 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_win32.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib"
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_win32.def" /out:"$(OUTDIRBIN)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib"
|
||||
DEF_FILE= "psqlodbc_win32.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\bind.obj" \
|
||||
@ -150,7 +151,6 @@ LINK32_OBJS= \
|
||||
"$(INTDIR)\drvconn.obj" \
|
||||
"$(INTDIR)\environ.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\gpps.obj" \
|
||||
"$(INTDIR)\info.obj" \
|
||||
"$(INTDIR)\lobj.obj" \
|
||||
"$(INTDIR)\win_md5.obj" \
|
||||
@ -172,7 +172,7 @@ LINK32_OBJS= \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
"$(OUTDIRBIN)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
@ -199,7 +199,6 @@ CLEAN :
|
||||
-@erase "$(INTDIR)\drvconn.obj"
|
||||
-@erase "$(INTDIR)\environ.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\gpps.obj"
|
||||
-@erase "$(INTDIR)\info.obj"
|
||||
-@erase "$(INTDIR)\lobj.obj"
|
||||
-@erase "$(INTDIR)\win_md5.obj"
|
||||
@ -288,7 +287,6 @@ LINK32_OBJS= \
|
||||
"$(INTDIR)\drvconn.obj" \
|
||||
"$(INTDIR)\environ.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\gpps.obj" \
|
||||
"$(INTDIR)\info.obj" \
|
||||
"$(INTDIR)\lobj.obj" \
|
||||
"$(INTDIR)\win_md5.obj"
|
||||
@ -367,12 +365,6 @@ SOURCE=execute.c
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=gpps.c
|
||||
|
||||
"$(INTDIR)\gpps.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=info.c
|
||||
|
||||
"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
@ -88,6 +88,7 @@ CLEAN :
|
||||
-@erase "$(INTDIR)\tuplelist.obj"
|
||||
-@erase "$(INTDIR)\odbcapi.obj"
|
||||
-@erase "$(INTDIR)\odbcapi30.obj"
|
||||
-@erase "$(INTDIR)\pgapi30.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\psqlodbc30.dll"
|
||||
-@erase "$(OUTDIR)\psqlodbc.exp"
|
||||
@ -174,6 +175,7 @@ LINK32_OBJS= \
|
||||
"$(INTDIR)\tuplelist.obj" \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\odbcapi30.obj" \
|
||||
"$(INTDIR)\pgapi30.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIRBIN)\psqlodbc30.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
@ -225,6 +227,7 @@ CLEAN :
|
||||
-@erase "$(INTDIR)\tuplelist.obj"
|
||||
-@erase "$(INTDIR)\odbcapi.obj"
|
||||
-@erase "$(INTDIR)\odbcapi30.obj"
|
||||
-@erase "$(INTDIR)\pgapi30.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\psqlodbc30.dll"
|
||||
@ -314,6 +317,7 @@ LINK32_OBJS= \
|
||||
"$(INTDIR)\tuplelist.obj" \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\odbcapi30.obj" \
|
||||
"$(INTDIR)\pgapi30.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIR)\psqlodbc30.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
@ -513,7 +517,10 @@ SOURCE=odbcapi30.c
|
||||
"$(INTDIR)\odbcapi30.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=pgcapi30.c
|
||||
|
||||
"$(INTDIR)\pgcapi30.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
508
src/interfaces/odbc/win32_30w.mak
Normal file
508
src/interfaces/odbc/win32_30w.mak
Normal file
@ -0,0 +1,508 @@
|
||||
#
|
||||
# File: win32_30w.mak
|
||||
#
|
||||
# Description: psqlodbc30 Unicode version Makefile for Win32.
|
||||
#
|
||||
# Configurations: Unicode30Debug, Unicode30
|
||||
# Build Types: ALL, CLEAN
|
||||
# Usage: NMAKE /f win32_30.mak CFG=[Unicode30 | Unicode30Debug] [ALL | CLEAN]
|
||||
#
|
||||
# Comments: Created by Dave Page, 2001-02-12
|
||||
#
|
||||
|
||||
!MESSAGE Building the PostgreSQL Unicode 3.0 Driver for Win32...
|
||||
!MESSAGE
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=Unicode30
|
||||
!MESSAGE No configuration specified. Defaulting to Unicode30.
|
||||
!MESSAGE
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "Unicode30" && "$(CFG)" != "Unicode30Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f win32_30.mak CFG=[Unicode30 | Unicode30Debug] [ALL | CLEAN]
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Unicode30" (Win32 Release DLL)
|
||||
!MESSAGE "Unicode30Debug" (Win32 Debug DLL)
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration was specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "Unicode30"
|
||||
|
||||
OUTDIR=.\Unicode30
|
||||
OUTDIRBIN=.\Unicode30
|
||||
INTDIR=.\Unicode30
|
||||
|
||||
ALL : "$(OUTDIRBIN)\psqlodbc30.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\bind.obj"
|
||||
-@erase "$(INTDIR)\columninfo.obj"
|
||||
-@erase "$(INTDIR)\connection.obj"
|
||||
-@erase "$(INTDIR)\convert.obj"
|
||||
-@erase "$(INTDIR)\dlg_specific.obj"
|
||||
-@erase "$(INTDIR)\drvconn.obj"
|
||||
-@erase "$(INTDIR)\environ.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\info.obj"
|
||||
-@erase "$(INTDIR)\info30.obj"
|
||||
-@erase "$(INTDIR)\lobj.obj"
|
||||
-@erase "$(INTDIR)\win_md5.obj"
|
||||
-@erase "$(INTDIR)\misc.obj"
|
||||
-@erase "$(INTDIR)\pgapi30.obj"
|
||||
-@erase "$(INTDIR)\multibyte.obj"
|
||||
-@erase "$(INTDIR)\odbcapiw.obj"
|
||||
-@erase "$(INTDIR)\odbcapi30w.obj"
|
||||
-@erase "$(INTDIR)\win_unicode.obj"
|
||||
-@erase "$(INTDIR)\options.obj"
|
||||
-@erase "$(INTDIR)\parse.obj"
|
||||
-@erase "$(INTDIR)\pgtypes.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.res"
|
||||
-@erase "$(INTDIR)\qresult.obj"
|
||||
-@erase "$(INTDIR)\results.obj"
|
||||
-@erase "$(INTDIR)\setup.obj"
|
||||
-@erase "$(INTDIR)\socket.obj"
|
||||
-@erase "$(INTDIR)\statement.obj"
|
||||
-@erase "$(INTDIR)\tuple.obj"
|
||||
-@erase "$(INTDIR)\tuplelist.obj"
|
||||
-@erase "$(INTDIR)\odbcapi.obj"
|
||||
-@erase "$(INTDIR)\odbcapi30.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\psqlodbc30.dll"
|
||||
-@erase "$(OUTDIR)\psqlodbc.exp"
|
||||
-@erase "$(OUTDIR)\psqlodbc.lib"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_api30w.def" /out:"$(OUTDIRBIN)\psqlodbc30.dll" /implib:"$(OUTDIR)\psqlodbc.lib"
|
||||
DEF_FILE= "psqlodbc_api30w.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\bind.obj" \
|
||||
"$(INTDIR)\columninfo.obj" \
|
||||
"$(INTDIR)\connection.obj" \
|
||||
"$(INTDIR)\convert.obj" \
|
||||
"$(INTDIR)\dlg_specific.obj" \
|
||||
"$(INTDIR)\drvconn.obj" \
|
||||
"$(INTDIR)\environ.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\info.obj" \
|
||||
"$(INTDIR)\info30.obj" \
|
||||
"$(INTDIR)\lobj.obj" \
|
||||
"$(INTDIR)\win_md5.obj" \
|
||||
"$(INTDIR)\misc.obj" \
|
||||
"$(INTDIR)\pgapi30.obj" \
|
||||
"$(INTDIR)\multibyte.obj" \
|
||||
"$(INTDIR)\odbcapiw.obj" \
|
||||
"$(INTDIR)\odbcapi30w.obj" \
|
||||
"$(INTDIR)\win_unicode.obj" \
|
||||
"$(INTDIR)\options.obj" \
|
||||
"$(INTDIR)\parse.obj" \
|
||||
"$(INTDIR)\pgtypes.obj" \
|
||||
"$(INTDIR)\psqlodbc.obj" \
|
||||
"$(INTDIR)\qresult.obj" \
|
||||
"$(INTDIR)\results.obj" \
|
||||
"$(INTDIR)\setup.obj" \
|
||||
"$(INTDIR)\socket.obj" \
|
||||
"$(INTDIR)\statement.obj" \
|
||||
"$(INTDIR)\tuple.obj" \
|
||||
"$(INTDIR)\tuplelist.obj" \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\odbcapi30.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIRBIN)\psqlodbc30.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "Unicode30Debug"
|
||||
|
||||
ALL : "$(OUTDIR)\psqlodbc30.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\bind.obj"
|
||||
-@erase "$(INTDIR)\columninfo.obj"
|
||||
-@erase "$(INTDIR)\connection.obj"
|
||||
-@erase "$(INTDIR)\convert.obj"
|
||||
-@erase "$(INTDIR)\dlg_specific.obj"
|
||||
-@erase "$(INTDIR)\drvconn.obj"
|
||||
-@erase "$(INTDIR)\environ.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\info.obj"
|
||||
-@erase "$(INTDIR)\info30.obj"
|
||||
-@erase "$(INTDIR)\lobj.obj"
|
||||
-@erase "$(INTDIR)\win_md5.obj"
|
||||
-@erase "$(INTDIR)\misc.obj"
|
||||
-@erase "$(INTDIR)\pgapi30.obj"
|
||||
-@erase "$(INTDIR)\multibyte.obj"
|
||||
-@erase "$(INTDIR)\odbcapiw.obj"
|
||||
-@erase "$(INTDIR)\odbcapi30w.obj"
|
||||
-@erase "$(INTDIR)\win_unicode.obj"
|
||||
-@erase "$(INTDIR)\options.obj"
|
||||
-@erase "$(INTDIR)\parse.obj"
|
||||
-@erase "$(INTDIR)\pgtypes.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.res"
|
||||
-@erase "$(INTDIR)\qresult.obj"
|
||||
-@erase "$(INTDIR)\results.obj"
|
||||
-@erase "$(INTDIR)\setup.obj"
|
||||
-@erase "$(INTDIR)\socket.obj"
|
||||
-@erase "$(INTDIR)\statement.obj"
|
||||
-@erase "$(INTDIR)\tuple.obj"
|
||||
-@erase "$(INTDIR)\tuplelist.obj"
|
||||
-@erase "$(INTDIR)\odbcapi.obj"
|
||||
-@erase "$(INTDIR)\odbcapi30.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\psqlodbc30.dll"
|
||||
-@erase "$(OUTDIR)\psqlodbc.exp"
|
||||
-@erase "$(OUTDIR)\psqlodbc.ilk"
|
||||
-@erase "$(OUTDIR)\psqlodbc.lib"
|
||||
-@erase "$(OUTDIR)\psqlodbc.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0300" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_api30w.def" /out:"$(OUTDIR)\psqlodbc30.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept
|
||||
DEF_FILE= "psqlodbc_api30w.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\bind.obj" \
|
||||
"$(INTDIR)\columninfo.obj" \
|
||||
"$(INTDIR)\connection.obj" \
|
||||
"$(INTDIR)\convert.obj" \
|
||||
"$(INTDIR)\dlg_specific.obj" \
|
||||
"$(INTDIR)\drvconn.obj" \
|
||||
"$(INTDIR)\environ.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\info.obj" \
|
||||
"$(INTDIR)\info30.obj" \
|
||||
"$(INTDIR)\lobj.obj" \
|
||||
"$(INTDIR)\win_md5.obj"
|
||||
"$(INTDIR)\misc.obj" \
|
||||
"$(INTDIR)\pgapi30.obj" \
|
||||
"$(INTDIR)\multibyte.obj" \
|
||||
"$(INTDIR)\odbcapiw.obj" \
|
||||
"$(INTDIR)\odbcapi30w.obj" \
|
||||
"$(INTDIR)\win_unicode.obj" \
|
||||
"$(INTDIR)\options.obj" \
|
||||
"$(INTDIR)\parse.obj" \
|
||||
"$(INTDIR)\pgtypes.obj" \
|
||||
"$(INTDIR)\psqlodbc.obj" \
|
||||
"$(INTDIR)\qresult.obj" \
|
||||
"$(INTDIR)\results.obj" \
|
||||
"$(INTDIR)\setup.obj" \
|
||||
"$(INTDIR)\socket.obj" \
|
||||
"$(INTDIR)\statement.obj" \
|
||||
"$(INTDIR)\tuple.obj" \
|
||||
"$(INTDIR)\tuplelist.obj" \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\odbcapi30.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIR)\psqlodbc30.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "Unicode30" || "$(CFG)" == "Unicode30Debug"
|
||||
|
||||
SOURCE=bind.c
|
||||
|
||||
"$(INTDIR)\bind.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=columninfo.c
|
||||
|
||||
"$(INTDIR)\columninfo.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=connection.c
|
||||
|
||||
"$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=convert.c
|
||||
|
||||
"$(INTDIR)\convert.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=dlg_specific.c
|
||||
|
||||
"$(INTDIR)\dlg_specific.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=drvconn.c
|
||||
|
||||
"$(INTDIR)\drvconn.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=environ.c
|
||||
|
||||
"$(INTDIR)\environ.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=execute.c
|
||||
|
||||
"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=info.c
|
||||
|
||||
"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=info30.c
|
||||
|
||||
"$(INTDIR)\info30.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=lobj.c
|
||||
|
||||
"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=misc.c
|
||||
|
||||
"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=multibyte.c
|
||||
|
||||
"$(INTDIR)\multibyte.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=odbcapiw.c
|
||||
|
||||
"$(INTDIR)\odbcapiw.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=pgapi30.c
|
||||
|
||||
"$(INTDIR)\pgapi30.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=odbcapi30w.c
|
||||
|
||||
"$(INTDIR)\odbcapi30w.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=win_unicode.c
|
||||
|
||||
"$(INTDIR)\win_unicode.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=options.c
|
||||
|
||||
"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=parse.c
|
||||
|
||||
"$(INTDIR)\parse.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=pgtypes.c
|
||||
|
||||
"$(INTDIR)\pgtypes.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=psqlodbc.c
|
||||
|
||||
"$(INTDIR)\psqlodbc.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=psqlodbc.rc
|
||||
|
||||
!IF "$(CFG)" == "Unicode30"
|
||||
"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE)
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "Unicode30Debug"
|
||||
"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" $(SOURCE)
|
||||
!ENDIF
|
||||
|
||||
|
||||
SOURCE=qresult.c
|
||||
|
||||
"$(INTDIR)\qresult.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=results.c
|
||||
|
||||
"$(INTDIR)\results.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=setup.c
|
||||
|
||||
"$(INTDIR)\setup.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=socket.c
|
||||
|
||||
"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=statement.c
|
||||
|
||||
"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=tuple.c
|
||||
|
||||
"$(INTDIR)\tuple.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=tuplelist.c
|
||||
|
||||
"$(INTDIR)\tuplelist.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=win_md5.c
|
||||
|
||||
"$(INTDIR)\win_md5.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=odbcapi.c
|
||||
|
||||
"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=odbcapi30.c
|
||||
|
||||
"$(INTDIR)\odbcapi30.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
478
src/interfaces/odbc/win32w.mak
Normal file
478
src/interfaces/odbc/win32w.mak
Normal file
@ -0,0 +1,478 @@
|
||||
#
|
||||
# File: win32w.mak
|
||||
#
|
||||
# Description: psqlodbc Unicode version Makefile for Win32.
|
||||
#
|
||||
# Configurations: UnicodeDebug, Unicode
|
||||
# Build Types: ALL, CLEAN
|
||||
# Usage: NMAKE /f win32w.mak CFG=[Unicode | UnicodeDebug] [ALL | CLEAN]
|
||||
#
|
||||
# Comments: Created by Dave Page, 2001-02-12
|
||||
#
|
||||
|
||||
!MESSAGE Building the PostgreSQL Unicode Driver for Win32...
|
||||
!MESSAGE
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=Unicode
|
||||
!MESSAGE No configuration specified. Defaulting to Unicode.
|
||||
!MESSAGE
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "Unicode" && "$(CFG)" != "UnicodeDebug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f win32w.mak CFG=[Unicode | UnicodeDebug] [ALL | CLEAN]
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Unicode" (Win32 Release DLL)
|
||||
!MESSAGE "UnicodeDebug" (Win32 Debug DLL)
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration was specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "Unicode"
|
||||
|
||||
OUTDIR=.\Unicode
|
||||
OUTDIRBIN=.\Unicode
|
||||
INTDIR=.\Unicode
|
||||
|
||||
ALL : "$(OUTDIRBIN)\psqlodbc.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\bind.obj"
|
||||
-@erase "$(INTDIR)\columninfo.obj"
|
||||
-@erase "$(INTDIR)\connection.obj"
|
||||
-@erase "$(INTDIR)\convert.obj"
|
||||
-@erase "$(INTDIR)\dlg_specific.obj"
|
||||
-@erase "$(INTDIR)\drvconn.obj"
|
||||
-@erase "$(INTDIR)\environ.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\info.obj"
|
||||
-@erase "$(INTDIR)\lobj.obj"
|
||||
-@erase "$(INTDIR)\win_md5.obj"
|
||||
-@erase "$(INTDIR)\misc.obj"
|
||||
-@erase "$(INTDIR)\multibyte.obj"
|
||||
-@erase "$(INTDIR)\odbcapiw.obj"
|
||||
-@erase "$(INTDIR)\odbcapi25w.obj"
|
||||
-@erase "$(INTDIR)\win_unicode.obj"
|
||||
-@erase "$(INTDIR)\options.obj"
|
||||
-@erase "$(INTDIR)\parse.obj"
|
||||
-@erase "$(INTDIR)\pgtypes.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.res"
|
||||
-@erase "$(INTDIR)\qresult.obj"
|
||||
-@erase "$(INTDIR)\results.obj"
|
||||
-@erase "$(INTDIR)\setup.obj"
|
||||
-@erase "$(INTDIR)\socket.obj"
|
||||
-@erase "$(INTDIR)\statement.obj"
|
||||
-@erase "$(INTDIR)\tuple.obj"
|
||||
-@erase "$(INTDIR)\tuplelist.obj"
|
||||
-@erase "$(INTDIR)\odbcapi.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\psqlodbc.dll"
|
||||
-@erase "$(OUTDIR)\psqlodbc.exp"
|
||||
-@erase "$(OUTDIR)\psqlodbc.lib"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0250" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"psqlodbc_apiw.def" /out:"$(OUTDIRBIN)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib"
|
||||
DEF_FILE= "psqlodbc_apiw.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\bind.obj" \
|
||||
"$(INTDIR)\columninfo.obj" \
|
||||
"$(INTDIR)\connection.obj" \
|
||||
"$(INTDIR)\convert.obj" \
|
||||
"$(INTDIR)\dlg_specific.obj" \
|
||||
"$(INTDIR)\drvconn.obj" \
|
||||
"$(INTDIR)\environ.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\info.obj" \
|
||||
"$(INTDIR)\lobj.obj" \
|
||||
"$(INTDIR)\win_md5.obj" \
|
||||
"$(INTDIR)\misc.obj" \
|
||||
"$(INTDIR)\multibyte.obj" \
|
||||
"$(INTDIR)\odbcapiw.obj" \
|
||||
"$(INTDIR)\odbcapi25w.obj" \
|
||||
"$(INTDIR)\win_unicode.obj" \
|
||||
"$(INTDIR)\options.obj" \
|
||||
"$(INTDIR)\parse.obj" \
|
||||
"$(INTDIR)\pgtypes.obj" \
|
||||
"$(INTDIR)\psqlodbc.obj" \
|
||||
"$(INTDIR)\qresult.obj" \
|
||||
"$(INTDIR)\results.obj" \
|
||||
"$(INTDIR)\setup.obj" \
|
||||
"$(INTDIR)\socket.obj" \
|
||||
"$(INTDIR)\statement.obj" \
|
||||
"$(INTDIR)\tuple.obj" \
|
||||
"$(INTDIR)\tuplelist.obj" \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIRBIN)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "UnicodeDebug"
|
||||
|
||||
ALL : "$(OUTDIR)\psqlodbc.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\bind.obj"
|
||||
-@erase "$(INTDIR)\columninfo.obj"
|
||||
-@erase "$(INTDIR)\connection.obj"
|
||||
-@erase "$(INTDIR)\convert.obj"
|
||||
-@erase "$(INTDIR)\dlg_specific.obj"
|
||||
-@erase "$(INTDIR)\drvconn.obj"
|
||||
-@erase "$(INTDIR)\environ.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\info.obj"
|
||||
-@erase "$(INTDIR)\lobj.obj"
|
||||
-@erase "$(INTDIR)\win_md5.obj"
|
||||
-@erase "$(INTDIR)\misc.obj"
|
||||
-@erase "$(INTDIR)\multibyte.obj"
|
||||
-@erase "$(INTDIR)\odbcapiw.obj"
|
||||
-@erase "$(INTDIR)\odbcapi25w.obj"
|
||||
-@erase "$(INTDIR)\win_unicode.obj"
|
||||
-@erase "$(INTDIR)\options.obj"
|
||||
-@erase "$(INTDIR)\parse.obj"
|
||||
-@erase "$(INTDIR)\pgtypes.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.obj"
|
||||
-@erase "$(INTDIR)\psqlodbc.res"
|
||||
-@erase "$(INTDIR)\qresult.obj"
|
||||
-@erase "$(INTDIR)\results.obj"
|
||||
-@erase "$(INTDIR)\setup.obj"
|
||||
-@erase "$(INTDIR)\socket.obj"
|
||||
-@erase "$(INTDIR)\statement.obj"
|
||||
-@erase "$(INTDIR)\tuple.obj"
|
||||
-@erase "$(INTDIR)\tuplelist.obj"
|
||||
-@erase "$(INTDIR)\odbcapi.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\psqlodbc.dll"
|
||||
-@erase "$(OUTDIR)\psqlodbc.exp"
|
||||
-@erase "$(OUTDIR)\psqlodbc.ilk"
|
||||
-@erase "$(OUTDIR)\psqlodbc.lib"
|
||||
-@erase "$(OUTDIR)\psqlodbc.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PSQLODBC_EXPORTS" /D "ODBCVER=0x0250" /D "MULTIBYTE" /D "UNICODE_SUPPORT" /D "DRIVER_CURSOR_IMPLEMENT" /Fp"$(INTDIR)\psqlodbc.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"psqlodbc_apiw.def" /out:"$(OUTDIR)\psqlodbc.dll" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept
|
||||
DEF_FILE= "psqlodbc_apiw.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\bind.obj" \
|
||||
"$(INTDIR)\columninfo.obj" \
|
||||
"$(INTDIR)\connection.obj" \
|
||||
"$(INTDIR)\convert.obj" \
|
||||
"$(INTDIR)\dlg_specific.obj" \
|
||||
"$(INTDIR)\drvconn.obj" \
|
||||
"$(INTDIR)\environ.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\info.obj" \
|
||||
"$(INTDIR)\lobj.obj" \
|
||||
"$(INTDIR)\win_md5.obj"
|
||||
"$(INTDIR)\misc.obj" \
|
||||
"$(INTDIR)\multibyte.obj" \
|
||||
"$(INTDIR)\odbcapiw.obj" \
|
||||
"$(INTDIR)\odbcapi25w.obj" \
|
||||
"$(INTDIR)\win_unicode.obj" \
|
||||
"$(INTDIR)\options.obj" \
|
||||
"$(INTDIR)\parse.obj" \
|
||||
"$(INTDIR)\pgtypes.obj" \
|
||||
"$(INTDIR)\psqlodbc.obj" \
|
||||
"$(INTDIR)\qresult.obj" \
|
||||
"$(INTDIR)\results.obj" \
|
||||
"$(INTDIR)\setup.obj" \
|
||||
"$(INTDIR)\socket.obj" \
|
||||
"$(INTDIR)\statement.obj" \
|
||||
"$(INTDIR)\tuple.obj" \
|
||||
"$(INTDIR)\tuplelist.obj" \
|
||||
"$(INTDIR)\odbcapi.obj" \
|
||||
"$(INTDIR)\psqlodbc.res"
|
||||
|
||||
"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "Unicode" || "$(CFG)" == "UnicodeDebug"
|
||||
|
||||
SOURCE=bind.c
|
||||
|
||||
"$(INTDIR)\bind.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=columninfo.c
|
||||
|
||||
"$(INTDIR)\columninfo.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=connection.c
|
||||
|
||||
"$(INTDIR)\connection.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=convert.c
|
||||
|
||||
"$(INTDIR)\convert.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=dlg_specific.c
|
||||
|
||||
"$(INTDIR)\dlg_specific.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=drvconn.c
|
||||
|
||||
"$(INTDIR)\drvconn.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=environ.c
|
||||
|
||||
"$(INTDIR)\environ.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=execute.c
|
||||
|
||||
"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=info.c
|
||||
|
||||
"$(INTDIR)\info.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=lobj.c
|
||||
|
||||
"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=misc.c
|
||||
|
||||
"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=multibyte.c
|
||||
|
||||
"$(INTDIR)\multibyte.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=odbcapiw.c
|
||||
|
||||
"$(INTDIR)\odbcapiw.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=odbcapi25w.c
|
||||
|
||||
"$(INTDIR)\odbcapi25w.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
SOURCE=win_unicode.c
|
||||
|
||||
"$(INTDIR)\win_unicode.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=options.c
|
||||
|
||||
"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=parse.c
|
||||
|
||||
"$(INTDIR)\parse.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=pgtypes.c
|
||||
|
||||
"$(INTDIR)\pgtypes.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=psqlodbc.c
|
||||
|
||||
"$(INTDIR)\psqlodbc.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=psqlodbc.rc
|
||||
|
||||
!IF "$(CFG)" == "Unicode"
|
||||
"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "NDEBUG" /d "MULTIBYTE" $(SOURCE)
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "UnicodeDebug"
|
||||
"$(INTDIR)\psqlodbc.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) /l 0x809 /fo"$(INTDIR)\psqlodbc.res" /d "_DEBUG" $(SOURCE)
|
||||
!ENDIF
|
||||
|
||||
|
||||
SOURCE=qresult.c
|
||||
|
||||
"$(INTDIR)\qresult.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=results.c
|
||||
|
||||
"$(INTDIR)\results.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=setup.c
|
||||
|
||||
"$(INTDIR)\setup.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=socket.c
|
||||
|
||||
"$(INTDIR)\socket.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=statement.c
|
||||
|
||||
"$(INTDIR)\statement.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=tuple.c
|
||||
|
||||
"$(INTDIR)\tuple.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=tuplelist.c
|
||||
|
||||
"$(INTDIR)\tuplelist.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=win_md5.c
|
||||
|
||||
"$(INTDIR)\win_md5.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=odbcapi.c
|
||||
|
||||
"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
@ -20,6 +20,13 @@
|
||||
#define byte3_mask2 0x0fc0
|
||||
#define byte3_mask3 0x003f
|
||||
|
||||
UInt4 ucs2strlen(const SQLWCHAR *ucs2str)
|
||||
{
|
||||
UInt4 len;
|
||||
for (len = 0; ucs2str[len]; len++)
|
||||
;
|
||||
return len;
|
||||
}
|
||||
char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen)
|
||||
{
|
||||
char * utf8str;
|
||||
@ -28,24 +35,21 @@ char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen)
|
||||
if (!ucs2str)
|
||||
return NULL;
|
||||
if (ilen < 0)
|
||||
{
|
||||
for (ilen = 0; ucs2str[ilen]; ilen++)
|
||||
;
|
||||
}
|
||||
ilen = ucs2strlen(ucs2str);
|
||||
/*mylog(" newlen=%d", ilen);*/
|
||||
utf8str = (char *) malloc(ilen * 3 + 1);
|
||||
if (utf8str)
|
||||
{
|
||||
int i, len = 0;
|
||||
Int2 byte2code;
|
||||
Int4 byte4code;
|
||||
|
||||
UInt2 byte2code;
|
||||
Int4 byte4code;
|
||||
const SQLWCHAR *wstr;
|
||||
|
||||
for (i = 0, wstr = ucs2str; i < ilen; i++, wstr++)
|
||||
{
|
||||
if (!*wstr)
|
||||
break;
|
||||
else if (iswascii(*wstr))
|
||||
else if (0 == (*wstr & 0xff80))
|
||||
utf8str[len++] = (char) *wstr;
|
||||
else if ((*wstr & byte3check) == 0)
|
||||
{
|
||||
@ -66,7 +70,8 @@ char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen)
|
||||
}
|
||||
}
|
||||
utf8str[len] = '\0';
|
||||
*olen = len;
|
||||
if (olen)
|
||||
*olen = len;
|
||||
}
|
||||
/*mylog(" olen=%d %s\n", *olen, utf8str ? utf8str : "");*/
|
||||
return utf8str;
|
||||
@ -109,7 +114,7 @@ UInt4 utf8_to_ucs2(const char *utf8str, Int4 ilen, SQLWCHAR *ucs2str, UInt4 bufc
|
||||
{
|
||||
wcode = ((((UInt4) *str) & byte3_m1) << 12) |
|
||||
((((UInt4) str[1]) & byte3_m2) << 6) |
|
||||
((UInt4) str[2]) & byte3_m3;
|
||||
(((UInt4) str[2]) & byte3_m3);
|
||||
ucs2str[ocount] = (SQLWCHAR) wcode;
|
||||
}
|
||||
ocount++;
|
||||
@ -121,7 +126,7 @@ UInt4 utf8_to_ucs2(const char *utf8str, Int4 ilen, SQLWCHAR *ucs2str, UInt4 bufc
|
||||
if (ocount < bufcount)
|
||||
{
|
||||
wcode = ((((UInt4) *str) & byte2_m1) << 6) |
|
||||
((UInt4) str[1]) & byte2_m2;
|
||||
(((UInt4) str[1]) & byte2_m2);
|
||||
ucs2str[ocount] = (SQLWCHAR) wcode;
|
||||
}
|
||||
ocount++;
|
||||
|
Reference in New Issue
Block a user