Update to v.0246
This commit is contained in:
parent
fd262dac8c
commit
a80771f0a7
|
@ -37,9 +37,12 @@ RETCODE SQL_API SQLBindParameter(
|
|||
SDWORD FAR *pcbValue)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char *func="SQLBindParameter";
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if(stmt->parameters_allocated < ipar) {
|
||||
ParameterInfoClass *old_parameters;
|
||||
|
@ -52,6 +55,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
if ( ! stmt->parameters) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Could not allocate memory for statement parameters";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -133,53 +137,51 @@ RETCODE SQL_API SQLBindCol(
|
|||
SDWORD FAR *pcbValue)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
Int2 numcols;
|
||||
Int2 numcols = 0;
|
||||
char *func="SQLBindCol";
|
||||
|
||||
mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (icol < 1) {
|
||||
/* currently we do not support bookmarks */
|
||||
stmt->errormsg = "Bookmarks are not currently supported.";
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
icol--; /* use zero based col numbers */
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
if( ! stmt->result) {
|
||||
stmt->errormsg = "Can't bind columns with a NULL query result structure.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if( stmt->status == STMT_EXECUTING) {
|
||||
stmt->errormsg = "Can't bind columns while statement is still executing.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
numcols = QR_NumResultCols(stmt->result);
|
||||
|
||||
mylog("SQLBindCol: numcols = %d\n", numcols);
|
||||
|
||||
if (icol >= numcols) {
|
||||
stmt->errornumber = STMT_COLNUM_ERROR;
|
||||
stmt->errormsg = "Column number too big";
|
||||
return SQL_ERROR;
|
||||
}
|
||||
// allocate enough bindings if not already done
|
||||
// Most likely, execution of a statement would have setup the
|
||||
// necessary bindings. But some apps call BindCol before any
|
||||
// statement is executed.
|
||||
if ( icol > stmt->bindings_allocated)
|
||||
extend_bindings(stmt, icol);
|
||||
|
||||
// check to see if the bindings were allocated
|
||||
if ( ! stmt->bindings) {
|
||||
stmt->errormsg = "Bindings were not allocated properly.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "Could not allocate memory for bindings.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if ((cbValueMax == 0) || (rgbValue == NULL)) {
|
||||
icol--; /* use zero based col numbers from here out */
|
||||
|
||||
if (rgbValue == NULL) {
|
||||
/* we have to unbind the column */
|
||||
stmt->bindings[icol].buflen = 0;
|
||||
stmt->bindings[icol].buffer = NULL;
|
||||
|
@ -216,13 +218,17 @@ RETCODE SQL_API SQLDescribeParam(
|
|||
SWORD FAR *pfNullable)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char *func = "SQLDescribeParam";
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) {
|
||||
stmt->errormsg = "Invalid parameter number for SQLDescribeParam.";
|
||||
stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -254,6 +260,9 @@ RETCODE SQL_API SQLParamOptions(
|
|||
UDWORD crow,
|
||||
UDWORD FAR *pirow)
|
||||
{
|
||||
char *func = "SQLParamOptions";
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -273,21 +282,26 @@ RETCODE SQL_API SQLNumParams(
|
|||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char in_quote = FALSE;
|
||||
unsigned int i;
|
||||
char *func = "SQLNumParams";
|
||||
|
||||
|
||||
if(!stmt)
|
||||
if(!stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (pcpar)
|
||||
*pcpar = 0;
|
||||
else
|
||||
else {
|
||||
SC_log_error(func, "pcpar was null", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if(!stmt->statement) {
|
||||
// no statement has been allocated
|
||||
stmt->errormsg = "SQLNumParams called with no statement ready.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
} else {
|
||||
|
||||
|
@ -341,6 +355,14 @@ mylog("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d\n", st
|
|||
if(stmt->bindings_allocated < num_columns) {
|
||||
|
||||
new_bindings = create_empty_bindings(num_columns);
|
||||
if ( ! new_bindings) {
|
||||
if (stmt->bindings) {
|
||||
free(stmt->bindings);
|
||||
stmt->bindings = NULL;
|
||||
}
|
||||
stmt->bindings_allocated = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(stmt->bindings) {
|
||||
for(i=0; i<stmt->bindings_allocated; i++)
|
||||
|
@ -349,18 +371,17 @@ mylog("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d\n", st
|
|||
free(stmt->bindings);
|
||||
}
|
||||
|
||||
stmt->bindings = new_bindings; // null indicates error
|
||||
stmt->bindings = new_bindings;
|
||||
stmt->bindings_allocated = num_columns;
|
||||
|
||||
} else {
|
||||
/* if we have too many, make sure the extra ones are emptied out */
|
||||
/* so we don't accidentally try to use them for anything */
|
||||
for(i = num_columns; i < stmt->bindings_allocated; i++) {
|
||||
stmt->bindings[i].buflen = 0;
|
||||
stmt->bindings[i].buffer = NULL;
|
||||
stmt->bindings[i].used = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
// There is no reason to zero out extra bindings if there are
|
||||
// more than needed. If an app has allocated extra bindings,
|
||||
// let it worry about it by unbinding those columns.
|
||||
|
||||
// SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings
|
||||
// SQLExecDirect(...) # returns 5 cols
|
||||
// SQLExecDirect(...) # returns 10 cols (now OK)
|
||||
|
||||
mylog("exit extend_bindings\n");
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ RETCODE SQL_API SQLAllocConnect(
|
|||
{
|
||||
EnvironmentClass *env = (EnvironmentClass *)henv;
|
||||
ConnectionClass *conn;
|
||||
|
||||
char *func="SQLAllocConnect";
|
||||
|
||||
conn = CC_Constructor();
|
||||
mylog("**** SQLAllocConnect: henv = %u, conn = %u\n", henv, conn);
|
||||
|
@ -44,6 +44,7 @@ ConnectionClass *conn;
|
|||
env->errormsg = "Couldn't allocate memory for Connection object.";
|
||||
env->errornumber = ENV_ALLOC_ERROR;
|
||||
*phdbc = SQL_NULL_HDBC;
|
||||
EN_log_error(func, "", env);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -52,6 +53,7 @@ ConnectionClass *conn;
|
|||
env->errornumber = ENV_ALLOC_ERROR;
|
||||
CC_Destructor(conn);
|
||||
*phdbc = SQL_NULL_HDBC;
|
||||
EN_log_error(func, "", env);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -74,9 +76,12 @@ RETCODE SQL_API SQLConnect(
|
|||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnInfo *ci;
|
||||
char *func = "SQLConnect";
|
||||
|
||||
if ( ! conn)
|
||||
if ( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
ci = &conn->connInfo;
|
||||
|
||||
|
@ -96,9 +101,11 @@ ConnInfo *ci;
|
|||
|
||||
qlog("conn = %u, SQLConnect(DSN='%s', UID='%s', PWD='%s')\n", ci->dsn, ci->username, ci->password);
|
||||
|
||||
if ( CC_connect(conn, FALSE) <= 0)
|
||||
if ( CC_connect(conn, FALSE) <= 0) {
|
||||
// Error messages are filled in
|
||||
CC_log_error(func, "Error on CC_connect", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
@ -123,17 +130,21 @@ RETCODE SQL_API SQLDisconnect(
|
|||
HDBC hdbc)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
char *func = "SQLDisconnect";
|
||||
|
||||
mylog("**** in SQLDisconnect\n");
|
||||
|
||||
if ( ! conn)
|
||||
if ( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
qlog("conn=%u, SQLDisconnect\n", conn);
|
||||
|
||||
if (conn->status == CONN_EXECUTING) {
|
||||
conn->errornumber = CONN_IN_USE;
|
||||
conn->errormsg = "A transaction is currently being executed";
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -155,16 +166,20 @@ RETCODE SQL_API SQLFreeConnect(
|
|||
HDBC hdbc)
|
||||
{
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
char *func = "SQLFreeConnect";
|
||||
|
||||
mylog("**** in SQLFreeConnect: hdbc=%u\n", hdbc);
|
||||
|
||||
if ( ! conn)
|
||||
if ( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Remove the connection from the environment */
|
||||
if ( ! EN_remove_connection(conn->henv, conn)) {
|
||||
conn->errornumber = CONN_IN_USE;
|
||||
conn->errormsg = "A transaction is currently being executed";
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -577,8 +592,9 @@ char salt[2];
|
|||
/******* Send any initial settings *********/
|
||||
/**********************************************/
|
||||
|
||||
if ( ! CC_send_settings(self))
|
||||
return 0;
|
||||
// The Unix iodbc errors out on this call because it allocates a statement
|
||||
// before the connection is established. Therefore, don't check for error here.
|
||||
CC_send_settings(self);
|
||||
|
||||
CC_lookup_lo(self); /* a hack to get the oid of our large object oid type */
|
||||
|
||||
|
@ -1155,6 +1171,27 @@ RETCODE result;
|
|||
result = SQLFreeStmt(hstmt, SQL_DROP);
|
||||
}
|
||||
|
||||
void
|
||||
CC_log_error(char *func, char *desc, ConnectionClass *self)
|
||||
{
|
||||
if (self) {
|
||||
qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
|
||||
qlog(" ------------------------------------------------------------\n");
|
||||
qlog(" henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts);
|
||||
qlog(" sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type);
|
||||
|
||||
qlog(" ---------------- Socket Info -------------------------------\n");
|
||||
if (self->sock) {
|
||||
SocketClass *sock = self->sock;
|
||||
qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, sock->errormsg);
|
||||
qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out);
|
||||
qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in);
|
||||
}
|
||||
}
|
||||
else
|
||||
qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
CC_test(ConnectionClass *self)
|
||||
|
@ -1165,23 +1202,28 @@ SDWORD pcbValue;
|
|||
UDWORD pcrow;
|
||||
UWORD rgfRowStatus;
|
||||
char buf[255];
|
||||
SDWORD buflen;
|
||||
DATE_STRUCT *ds;
|
||||
|
||||
result = SQLAllocStmt( self, &hstmt1);
|
||||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = SQLExtendedFetch(hstmt1, SQL_FETCH_ABSOLUTE, -2, &pcrow, &rgfRowStatus);
|
||||
SQLGetData(hstmt1, 1, SQL_C_CHAR, buf, sizeof(buf), &pcbValue);
|
||||
qlog("FETCH_ABSOLUTE, -2: result=%d, Col1 = '%s'\n", result, buf);
|
||||
result = SQLExecDirect(hstmt1, "select * from cpar", SQL_NTS);
|
||||
qlog("exec result = %d\n", result);
|
||||
|
||||
result = SQLBindCol(hstmt1, 2, SQL_C_DATE, buf, 0, &buflen);
|
||||
qlog("bind result = %d\n", result);
|
||||
|
||||
result = SQLFetch(hstmt1);
|
||||
while (result != SQL_NO_DATA_FOUND) {
|
||||
ds = (DATE_STRUCT *) buf;
|
||||
qlog("fetch on stmt1: result=%d, buflen=%d: year=%d, month=%d, day=%d\n", result, buflen, ds->year, ds->month, ds->day);
|
||||
|
||||
result = SQLFetch(hstmt1);
|
||||
qlog("fetch on stmt1\n");
|
||||
}
|
||||
SQLFreeStmt(hstmt1, SQL_DROP);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -133,6 +133,7 @@ typedef struct {
|
|||
// char unknown_sizes[SMALL_REGISTRY_LEN];
|
||||
char fake_oid_index[SMALL_REGISTRY_LEN];
|
||||
char show_oid_column[SMALL_REGISTRY_LEN];
|
||||
char row_versioning[SMALL_REGISTRY_LEN];
|
||||
char show_system_tables[SMALL_REGISTRY_LEN];
|
||||
char focus_password;
|
||||
} ConnInfo;
|
||||
|
@ -188,5 +189,6 @@ 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);
|
||||
char CC_send_settings(ConnectionClass *self);
|
||||
void CC_lookup_lo(ConnectionClass *conn);
|
||||
void CC_log_error(char *func, char *desc, ConnectionClass *self);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -94,289 +94,272 @@ struct tm *tim;
|
|||
st.y = tim->tm_year + 1900;
|
||||
|
||||
mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, value, cbValueMax);
|
||||
if(value) {
|
||||
|
||||
/********************************************************************
|
||||
First convert any specific postgres types into more
|
||||
useable data.
|
||||
|
||||
NOTE: Conversions from PG char/varchar of a date/time/timestamp
|
||||
value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported
|
||||
*********************************************************************/
|
||||
switch(field_type) {
|
||||
/* $$$ need to add parsing for date/time/timestamp strings in PG_TYPE_CHAR,VARCHAR $$$ */
|
||||
case PG_TYPE_DATE:
|
||||
sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d);
|
||||
break;
|
||||
|
||||
case PG_TYPE_TIME:
|
||||
sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss);
|
||||
break;
|
||||
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
if (strnicmp(value, "invalid", 7) != 0) {
|
||||
sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss);
|
||||
|
||||
} else { /* The timestamp is invalid so set something conspicuous, like the epoch */
|
||||
t = 0;
|
||||
tim = localtime(&t);
|
||||
st.m = tim->tm_mon + 1;
|
||||
st.d = tim->tm_mday;
|
||||
st.y = tim->tm_year + 1900;
|
||||
st.hh = tim->tm_hour;
|
||||
st.mm = tim->tm_min;
|
||||
st.ss = tim->tm_sec;
|
||||
}
|
||||
break;
|
||||
|
||||
case PG_TYPE_BOOL: { /* change T/F to 1/0 */
|
||||
char *s = (char *) value;
|
||||
if (s[0] == 'T' || s[0] == 't')
|
||||
s[0] = '1';
|
||||
else
|
||||
s[0] = '0';
|
||||
}
|
||||
break;
|
||||
|
||||
/* This is for internal use by SQLStatistics() */
|
||||
case PG_TYPE_INT28: {
|
||||
// this is an array of eight integers
|
||||
short *short_array = (short *)rgbValue;
|
||||
|
||||
len = 16;
|
||||
|
||||
sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd",
|
||||
&short_array[0],
|
||||
&short_array[1],
|
||||
&short_array[2],
|
||||
&short_array[3],
|
||||
&short_array[4],
|
||||
&short_array[5],
|
||||
&short_array[6],
|
||||
&short_array[7]);
|
||||
|
||||
/* There is no corresponding fCType for this. */
|
||||
if(pcbValue)
|
||||
*pcbValue = len;
|
||||
|
||||
return COPY_OK; /* dont go any further or the data will be trashed */
|
||||
}
|
||||
|
||||
/* This is a large object OID, which is used to store LONGVARBINARY objects. */
|
||||
case PG_TYPE_LO:
|
||||
|
||||
return convert_lo( stmt, value, fCType, rgbValue, cbValueMax, pcbValue, multiple);
|
||||
|
||||
default:
|
||||
|
||||
if (field_type == stmt->hdbc->lobj_type) /* hack until permanent type available */
|
||||
return convert_lo( stmt, value, fCType, rgbValue, cbValueMax, pcbValue, multiple);
|
||||
}
|
||||
|
||||
/* Change default into something useable */
|
||||
if (fCType == SQL_C_DEFAULT) {
|
||||
fCType = pgtype_to_ctype(stmt, field_type);
|
||||
|
||||
mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType);
|
||||
}
|
||||
|
||||
|
||||
if(fCType == SQL_C_CHAR) {
|
||||
|
||||
/* Special character formatting as required */
|
||||
switch(field_type) {
|
||||
case PG_TYPE_DATE:
|
||||
len = 11;
|
||||
if (cbValueMax >= len)
|
||||
sprintf((char *)rgbValue, "%.4d-%.2d-%.2d", st.y, st.m, st.d);
|
||||
break;
|
||||
|
||||
case PG_TYPE_TIME:
|
||||
len = 9;
|
||||
if (cbValueMax >= len)
|
||||
sprintf((char *)rgbValue, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss);
|
||||
break;
|
||||
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
len = 19;
|
||||
if (cbValueMax >= len)
|
||||
sprintf((char *) rgbValue, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
|
||||
st.y, st.m, st.d, st.hh, st.mm, st.ss);
|
||||
break;
|
||||
|
||||
case PG_TYPE_BOOL:
|
||||
len = 1;
|
||||
if (cbValueMax > len) {
|
||||
strcpy((char *) rgbValue, value);
|
||||
mylog("PG_TYPE_BOOL: rgbValue = '%s'\n", rgbValue);
|
||||
}
|
||||
break;
|
||||
|
||||
case PG_TYPE_BYTEA: // convert binary data to hex strings (i.e, 255 = "FF")
|
||||
len = convert_pgbinary_to_char(value, rgbValue, cbValueMax);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* convert linefeeds to carriage-return/linefeed */
|
||||
convert_linefeeds( (char *) value, rgbValue, cbValueMax);
|
||||
len = strlen(rgbValue);
|
||||
|
||||
mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValue = '%s'\n", len, cbValueMax, rgbValue);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* for SQL_C_CHAR, its probably ok to leave currency symbols in. But
|
||||
to convert to numeric types, it is necessary to get rid of those.
|
||||
*/
|
||||
if (field_type == PG_TYPE_MONEY)
|
||||
convert_money(value);
|
||||
|
||||
switch(fCType) {
|
||||
case SQL_C_DATE:
|
||||
len = 6;
|
||||
if (cbValueMax >= len) {
|
||||
DATE_STRUCT *ds = (DATE_STRUCT *) rgbValue;
|
||||
ds->year = st.y;
|
||||
ds->month = st.m;
|
||||
ds->day = st.d;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_TIME:
|
||||
len = 6;
|
||||
if (cbValueMax >= len) {
|
||||
TIME_STRUCT *ts = (TIME_STRUCT *) rgbValue;
|
||||
ts->hour = st.hh;
|
||||
ts->minute = st.mm;
|
||||
ts->second = st.ss;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_TIMESTAMP:
|
||||
len = 16;
|
||||
if (cbValueMax >= len) {
|
||||
TIMESTAMP_STRUCT *ts = (TIMESTAMP_STRUCT *) rgbValue;
|
||||
ts->year = st.y;
|
||||
ts->month = st.m;
|
||||
ts->day = st.d;
|
||||
ts->hour = st.hh;
|
||||
ts->minute = st.mm;
|
||||
ts->second = st.ss;
|
||||
ts->fraction = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_BIT:
|
||||
len = 1;
|
||||
if (cbValueMax >= len || field_type == PG_TYPE_BOOL) {
|
||||
*((UCHAR *)rgbValue) = atoi(value);
|
||||
mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", atoi(value), cbValueMax, *((UCHAR *)rgbValue));
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_STINYINT:
|
||||
case SQL_C_TINYINT:
|
||||
len = 1;
|
||||
if (cbValueMax >= len)
|
||||
*((SCHAR *) rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_UTINYINT:
|
||||
len = 1;
|
||||
if (cbValueMax >= len)
|
||||
*((UCHAR *) rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_FLOAT:
|
||||
len = 4;
|
||||
if(cbValueMax >= len)
|
||||
*((SFLOAT *)rgbValue) = (float) atof(value);
|
||||
break;
|
||||
|
||||
case SQL_C_DOUBLE:
|
||||
len = 8;
|
||||
if(cbValueMax >= len)
|
||||
*((SDOUBLE *)rgbValue) = atof(value);
|
||||
break;
|
||||
|
||||
case SQL_C_SSHORT:
|
||||
case SQL_C_SHORT:
|
||||
len = 2;
|
||||
if(cbValueMax >= len)
|
||||
*((SWORD *)rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_USHORT:
|
||||
len = 2;
|
||||
if(cbValueMax >= len)
|
||||
*((UWORD *)rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_SLONG:
|
||||
case SQL_C_LONG:
|
||||
len = 4;
|
||||
if(cbValueMax >= len)
|
||||
*((SDWORD *)rgbValue) = atol(value);
|
||||
break;
|
||||
|
||||
case SQL_C_ULONG:
|
||||
len = 4;
|
||||
if(cbValueMax >= len)
|
||||
*((UDWORD *)rgbValue) = atol(value);
|
||||
break;
|
||||
|
||||
case SQL_C_BINARY:
|
||||
|
||||
// truncate if necessary
|
||||
// convert octal escapes to bytes
|
||||
len = convert_from_pgbinary(value, rgbValue, cbValueMax);
|
||||
mylog("SQL_C_BINARY: len = %d\n", len);
|
||||
break;
|
||||
|
||||
default:
|
||||
return COPY_UNSUPPORTED_TYPE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ! value) {
|
||||
/* handle a null just by returning SQL_NULL_DATA in pcbValue, */
|
||||
/* and doing nothing to the buffer. */
|
||||
if(pcbValue) {
|
||||
*pcbValue = SQL_NULL_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
// store the length of what was copied, if there's a place for it
|
||||
// unless it was a NULL (in which case it was already set above)
|
||||
if(pcbValue && value)
|
||||
*pcbValue = len;
|
||||
|
||||
if(len > cbValueMax) {
|
||||
mylog("!!! COPY_RESULT_TRUNCATED !!!\n");
|
||||
|
||||
// Don't return truncated because an application
|
||||
// (like Access) will try to call GetData again
|
||||
// to retrieve the rest of the data. Since we
|
||||
// are not currently ready for this, and the result
|
||||
// is an endless loop, we better just silently
|
||||
// truncate the data.
|
||||
// return COPY_RESULT_TRUNCATED;
|
||||
|
||||
// LongVarBinary types do handle truncated multiple get calls
|
||||
// through convert_lo().
|
||||
|
||||
if (pcbValue)
|
||||
*pcbValue = cbValueMax -1;
|
||||
|
||||
return COPY_OK;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
First convert any specific postgres types into more
|
||||
useable data.
|
||||
|
||||
NOTE: Conversions from PG char/varchar of a date/time/timestamp
|
||||
value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported
|
||||
*********************************************************************/
|
||||
switch(field_type) {
|
||||
/* $$$ need to add parsing for date/time/timestamp strings in PG_TYPE_CHAR,VARCHAR $$$ */
|
||||
case PG_TYPE_DATE:
|
||||
sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d);
|
||||
break;
|
||||
|
||||
case PG_TYPE_TIME:
|
||||
sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss);
|
||||
break;
|
||||
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP:
|
||||
if (strnicmp(value, "invalid", 7) != 0) {
|
||||
sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss);
|
||||
|
||||
} else { /* The timestamp is invalid so set something conspicuous, like the epoch */
|
||||
t = 0;
|
||||
tim = localtime(&t);
|
||||
st.m = tim->tm_mon + 1;
|
||||
st.d = tim->tm_mday;
|
||||
st.y = tim->tm_year + 1900;
|
||||
st.hh = tim->tm_hour;
|
||||
st.mm = tim->tm_min;
|
||||
st.ss = tim->tm_sec;
|
||||
}
|
||||
break;
|
||||
|
||||
case PG_TYPE_BOOL: { /* change T/F to 1/0 */
|
||||
char *s = (char *) value;
|
||||
if (s[0] == 'T' || s[0] == 't')
|
||||
s[0] = '1';
|
||||
else
|
||||
s[0] = '0';
|
||||
}
|
||||
break;
|
||||
|
||||
/* This is for internal use by SQLStatistics() */
|
||||
case PG_TYPE_INT28: {
|
||||
// this is an array of eight integers
|
||||
short *short_array = (short *)rgbValue;
|
||||
|
||||
len = 16;
|
||||
|
||||
sscanf(value, "%hd %hd %hd %hd %hd %hd %hd %hd",
|
||||
&short_array[0],
|
||||
&short_array[1],
|
||||
&short_array[2],
|
||||
&short_array[3],
|
||||
&short_array[4],
|
||||
&short_array[5],
|
||||
&short_array[6],
|
||||
&short_array[7]);
|
||||
|
||||
/* There is no corresponding fCType for this. */
|
||||
if(pcbValue)
|
||||
*pcbValue = len;
|
||||
|
||||
return COPY_OK; /* dont go any further or the data will be trashed */
|
||||
}
|
||||
|
||||
/* This is a large object OID, which is used to store LONGVARBINARY objects. */
|
||||
case PG_TYPE_LO:
|
||||
|
||||
return convert_lo( stmt, value, fCType, rgbValue, cbValueMax, pcbValue, multiple);
|
||||
|
||||
default:
|
||||
|
||||
if (field_type == stmt->hdbc->lobj_type) /* hack until permanent type available */
|
||||
return convert_lo( stmt, value, fCType, rgbValue, cbValueMax, pcbValue, multiple);
|
||||
}
|
||||
|
||||
/* Change default into something useable */
|
||||
if (fCType == SQL_C_DEFAULT) {
|
||||
fCType = pgtype_to_ctype(stmt, field_type);
|
||||
|
||||
mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType);
|
||||
}
|
||||
|
||||
|
||||
if(fCType == SQL_C_CHAR) {
|
||||
|
||||
/* Special character formatting as required */
|
||||
/* These really should return error if cbValueMax is not big enough. */
|
||||
switch(field_type) {
|
||||
case PG_TYPE_DATE:
|
||||
len = 10;
|
||||
if (cbValueMax > len)
|
||||
sprintf((char *)rgbValue, "%.4d-%.2d-%.2d", st.y, st.m, st.d);
|
||||
break;
|
||||
|
||||
case PG_TYPE_TIME:
|
||||
len = 8;
|
||||
if (cbValueMax > len)
|
||||
sprintf((char *)rgbValue, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss);
|
||||
break;
|
||||
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP:
|
||||
len = 19;
|
||||
if (cbValueMax > len)
|
||||
sprintf((char *) rgbValue, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
|
||||
st.y, st.m, st.d, st.hh, st.mm, st.ss);
|
||||
break;
|
||||
|
||||
case PG_TYPE_BOOL:
|
||||
len = 1;
|
||||
if (cbValueMax > len) {
|
||||
strcpy((char *) rgbValue, value);
|
||||
mylog("PG_TYPE_BOOL: rgbValue = '%s'\n", rgbValue);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Currently, data is SILENTLY TRUNCATED for BYTEA and character data
|
||||
types if there is not enough room in cbValueMax because the driver
|
||||
can't handle multiple calls to SQLGetData for these, yet. Most likely,
|
||||
the buffer passed in will be big enough to handle the maximum limit of
|
||||
postgres, anyway.
|
||||
|
||||
LongVarBinary types are handled correctly above, observing truncation
|
||||
and all that stuff since there is essentially no limit on the large
|
||||
object used to store those.
|
||||
*/
|
||||
case PG_TYPE_BYTEA: // convert binary data to hex strings (i.e, 255 = "FF")
|
||||
len = convert_pgbinary_to_char(value, rgbValue, cbValueMax);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* convert linefeeds to carriage-return/linefeed */
|
||||
convert_linefeeds( (char *) value, rgbValue, cbValueMax);
|
||||
len = strlen(rgbValue);
|
||||
|
||||
mylog(" SQL_C_CHAR, default: len = %d, cbValueMax = %d, rgbValue = '%s'\n", len, cbValueMax, rgbValue);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
return COPY_OK;
|
||||
}
|
||||
/* for SQL_C_CHAR, its probably ok to leave currency symbols in. But
|
||||
to convert to numeric types, it is necessary to get rid of those.
|
||||
*/
|
||||
if (field_type == PG_TYPE_MONEY)
|
||||
convert_money(value);
|
||||
|
||||
switch(fCType) {
|
||||
case SQL_C_DATE:
|
||||
len = 6;
|
||||
{
|
||||
DATE_STRUCT *ds = (DATE_STRUCT *) rgbValue;
|
||||
ds->year = st.y;
|
||||
ds->month = st.m;
|
||||
ds->day = st.d;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_TIME:
|
||||
len = 6;
|
||||
{
|
||||
TIME_STRUCT *ts = (TIME_STRUCT *) rgbValue;
|
||||
ts->hour = st.hh;
|
||||
ts->minute = st.mm;
|
||||
ts->second = st.ss;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_TIMESTAMP:
|
||||
len = 16;
|
||||
{
|
||||
TIMESTAMP_STRUCT *ts = (TIMESTAMP_STRUCT *) rgbValue;
|
||||
ts->year = st.y;
|
||||
ts->month = st.m;
|
||||
ts->day = st.d;
|
||||
ts->hour = st.hh;
|
||||
ts->minute = st.mm;
|
||||
ts->second = st.ss;
|
||||
ts->fraction = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SQL_C_BIT:
|
||||
len = 1;
|
||||
*((UCHAR *)rgbValue) = atoi(value);
|
||||
mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", atoi(value), cbValueMax, *((UCHAR *)rgbValue));
|
||||
break;
|
||||
|
||||
case SQL_C_STINYINT:
|
||||
case SQL_C_TINYINT:
|
||||
len = 1;
|
||||
*((SCHAR *) rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_UTINYINT:
|
||||
len = 1;
|
||||
*((UCHAR *) rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_FLOAT:
|
||||
len = 4;
|
||||
*((SFLOAT *)rgbValue) = (float) atof(value);
|
||||
break;
|
||||
|
||||
case SQL_C_DOUBLE:
|
||||
len = 8;
|
||||
*((SDOUBLE *)rgbValue) = atof(value);
|
||||
break;
|
||||
|
||||
case SQL_C_SSHORT:
|
||||
case SQL_C_SHORT:
|
||||
len = 2;
|
||||
*((SWORD *)rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_USHORT:
|
||||
len = 2;
|
||||
*((UWORD *)rgbValue) = atoi(value);
|
||||
break;
|
||||
|
||||
case SQL_C_SLONG:
|
||||
case SQL_C_LONG:
|
||||
len = 4;
|
||||
*((SDWORD *)rgbValue) = atol(value);
|
||||
break;
|
||||
|
||||
case SQL_C_ULONG:
|
||||
len = 4;
|
||||
*((UDWORD *)rgbValue) = atol(value);
|
||||
break;
|
||||
|
||||
case SQL_C_BINARY:
|
||||
|
||||
// truncate if necessary
|
||||
// convert octal escapes to bytes
|
||||
len = convert_from_pgbinary(value, rgbValue, cbValueMax);
|
||||
mylog("SQL_C_BINARY: len = %d\n", len);
|
||||
break;
|
||||
|
||||
default:
|
||||
return COPY_UNSUPPORTED_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
// store the length of what was copied, if there's a place for it
|
||||
if(pcbValue)
|
||||
*pcbValue = len;
|
||||
|
||||
return COPY_OK;
|
||||
|
||||
}
|
||||
|
||||
/* This function inserts parameters into an SQL statements.
|
||||
|
@ -386,6 +369,7 @@ struct tm *tim;
|
|||
int
|
||||
copy_statement_with_parameters(StatementClass *stmt)
|
||||
{
|
||||
char *func="copy_statement_with_parameters";
|
||||
unsigned int opos, npos;
|
||||
char param_string[128], tmp[256], cbuf[TEXT_FIELD_SIZE+5];
|
||||
int param_number;
|
||||
|
@ -400,8 +384,10 @@ char *buffer, *buf;
|
|||
char in_quote = FALSE;
|
||||
|
||||
|
||||
if ( ! old_statement)
|
||||
if ( ! old_statement) {
|
||||
SC_log_error(func, "No statement string", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
memset(&st, 0, sizeof(SIMPLE_TIME));
|
||||
|
@ -624,6 +610,7 @@ char in_quote = FALSE;
|
|||
stmt->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters";
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
new_statement[npos] = '\0'; // just in case
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -226,6 +226,7 @@ char buf[128];
|
|||
|
||||
CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column));
|
||||
CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index));
|
||||
CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning));
|
||||
CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables));
|
||||
|
||||
EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column));
|
||||
|
@ -273,6 +274,8 @@ char buf[128];
|
|||
|
||||
sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES));
|
||||
|
||||
sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING));
|
||||
|
||||
/* OID Options*/
|
||||
sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX));
|
||||
sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
|
||||
|
@ -297,7 +300,7 @@ makeConnectString(char *connect_string, ConnInfo *ci)
|
|||
{
|
||||
char got_dsn = (ci->dsn[0] != '\0');
|
||||
|
||||
sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;READONLY=%s;PWD=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s",
|
||||
sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;READONLY=%s;PWD=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;ROWVERSIONING=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s",
|
||||
got_dsn ? "DSN" : "DRIVER",
|
||||
got_dsn ? ci->dsn : ci->driver,
|
||||
ci->database,
|
||||
|
@ -310,6 +313,7 @@ char got_dsn = (ci->dsn[0] != '\0');
|
|||
// ci->unknown_sizes, -- currently only needed in Driver options.
|
||||
ci->fake_oid_index,
|
||||
ci->show_oid_column,
|
||||
ci->row_versioning,
|
||||
ci->show_system_tables,
|
||||
ci->conn_settings);
|
||||
}
|
||||
|
@ -355,6 +359,9 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
|
|||
else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0)
|
||||
strcpy(ci->fake_oid_index, value);
|
||||
|
||||
else if (stricmp(attribute, INI_ROWVERSIONING) == 0)
|
||||
strcpy(ci->row_versioning, value);
|
||||
|
||||
else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0)
|
||||
strcpy(ci->show_system_tables, value);
|
||||
|
||||
|
@ -398,6 +405,8 @@ getDSNdefaults(ConnInfo *ci)
|
|||
if (ci->show_system_tables[0] == '\0')
|
||||
sprintf(ci->show_system_tables, "%d", DEFAULT_SHOWSYSTEMTABLES);
|
||||
|
||||
if (ci->row_versioning[0] == '\0')
|
||||
sprintf(ci->row_versioning, "%d", DEFAULT_ROWVERSIONING);
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,6 +457,9 @@ char *DSN = ci->dsn;
|
|||
if ( ci->fake_oid_index[0] == '\0' || overwrite)
|
||||
SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI);
|
||||
|
||||
if ( ci->row_versioning[0] == '\0' || overwrite)
|
||||
SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI);
|
||||
|
||||
if ( ci->show_system_tables[0] == '\0' || overwrite)
|
||||
SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI);
|
||||
|
||||
|
@ -533,6 +545,11 @@ char *DSN = ci->dsn;
|
|||
ci->fake_oid_index,
|
||||
ODBC_INI);
|
||||
|
||||
SQLWritePrivateProfileString(DSN,
|
||||
INI_ROWVERSIONING,
|
||||
ci->row_versioning,
|
||||
ODBC_INI);
|
||||
|
||||
SQLWritePrivateProfileString(DSN,
|
||||
INI_SHOWSYSTEMTABLES,
|
||||
ci->show_system_tables,
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
|
||||
#define INI_FAKEOIDINDEX "FakeOidIndex"
|
||||
#define INI_SHOWOIDCOLUMN "ShowOidColumn"
|
||||
#define INI_ROWVERSIONING "RowVersioning"
|
||||
#define INI_SHOWSYSTEMTABLES "ShowSystemTables"
|
||||
#define INI_LIE "Lie"
|
||||
#define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes"
|
||||
|
@ -74,6 +75,7 @@
|
|||
|
||||
#define DEFAULT_FAKEOIDINDEX 0
|
||||
#define DEFAULT_SHOWOIDCOLUMN 0
|
||||
#define DEFAULT_ROWVERSIONING 0
|
||||
#define DEFAULT_SHOWSYSTEMTABLES 0 // dont show system tables
|
||||
#define DEFAULT_LIE 0
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ RETCODE SQL_API SQLDriverConnect(
|
|||
SWORD FAR *pcbConnStrOut,
|
||||
UWORD fDriverCompletion)
|
||||
{
|
||||
char *func = "SQLDriverConnect";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
ConnInfo *ci;
|
||||
RETCODE dialog_result;
|
||||
|
@ -56,8 +57,10 @@ char password_required = FALSE;
|
|||
|
||||
mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, szConnStrIn);
|
||||
|
||||
if ( ! conn)
|
||||
if ( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
qlog("conn=%u, SQLDriverConnect( in)='%s'\n", conn, szConnStrIn);
|
||||
|
||||
|
@ -135,8 +138,10 @@ dialog:
|
|||
// do the actual connect
|
||||
retval = CC_connect(conn, password_required);
|
||||
if (retval < 0) { /* need a password */
|
||||
if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
|
||||
if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
|
||||
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
|
||||
return SQL_ERROR; /* need a password but not allowed to prompt so error */
|
||||
}
|
||||
else {
|
||||
password_required = TRUE;
|
||||
goto dialog;
|
||||
|
@ -144,6 +149,7 @@ dialog:
|
|||
}
|
||||
else if (retval == 0) {
|
||||
// error msg filled in above
|
||||
CC_log_error(func, "Error from CC_Connect", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,14 @@ ConnectionClass *conns[MAX_CONNECTIONS];
|
|||
|
||||
RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv)
|
||||
{
|
||||
char *func = "SQLAllocEnv";
|
||||
|
||||
mylog("**** in SQLAllocEnv ** \n");
|
||||
|
||||
*phenv = (HENV) EN_Constructor();
|
||||
if ( ! *phenv) {
|
||||
*phenv = SQL_NULL_HENV;
|
||||
EN_log_error(func, "Error allocating environment", NULL);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -39,6 +42,7 @@ mylog("**** in SQLAllocEnv ** \n");
|
|||
|
||||
RETCODE SQL_API SQLFreeEnv(HENV henv)
|
||||
{
|
||||
char *func = "SQLFreeEnv";
|
||||
EnvironmentClass *env = (EnvironmentClass *) henv;
|
||||
|
||||
mylog("**** in SQLFreeEnv: env = %u ** \n", env);
|
||||
|
@ -49,6 +53,7 @@ mylog("**** in SQLFreeEnv: env = %u ** \n", env);
|
|||
}
|
||||
|
||||
mylog(" error\n");
|
||||
EN_log_error(func, "Error freeing environment", env);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -73,9 +78,6 @@ int status;
|
|||
// CC: return an error of a hstmt
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
if (NULL == stmt)
|
||||
return SQL_INVALID_HANDLE;
|
||||
|
||||
if (SC_get_error(stmt, &status, &msg)) {
|
||||
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
|
||||
if (NULL == msg) {
|
||||
|
@ -424,3 +426,13 @@ int i;
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
EN_log_error(char *func, char *desc, EnvironmentClass *self)
|
||||
{
|
||||
if (self) {
|
||||
qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
|
||||
}
|
||||
else
|
||||
qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
}
|
||||
|
|
|
@ -29,5 +29,6 @@ char EN_Destructor(EnvironmentClass *self);
|
|||
char EN_get_error(EnvironmentClass *self, int *number, char **message);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,10 +32,13 @@ RETCODE SQL_API SQLPrepare(HSTMT hstmt,
|
|||
UCHAR FAR *szSqlStr,
|
||||
SDWORD cbSqlStr)
|
||||
{
|
||||
char *func = "SQLPrepare";
|
||||
StatementClass *self = (StatementClass *) hstmt;
|
||||
|
||||
if ( ! self)
|
||||
if ( ! self) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* According to the ODBC specs it is valid to call SQLPrepare mulitple times.
|
||||
In that case, the bound SQL statement is replaced by the new one
|
||||
|
@ -66,12 +69,14 @@ StatementClass *self = (StatementClass *) hstmt;
|
|||
|
||||
self->errornumber = STMT_SEQUENCE_ERROR;
|
||||
self->errormsg = "SQLPrepare(): The handle does not point to a statement that is ready to be executed";
|
||||
SC_log_error(func, "", self);
|
||||
|
||||
return SQL_ERROR;
|
||||
|
||||
default:
|
||||
self->errornumber = STMT_INTERNAL_ERROR;
|
||||
self->errormsg = "An Internal Error has occured -- Unknown statement status.";
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -82,6 +87,7 @@ StatementClass *self = (StatementClass *) hstmt;
|
|||
if ( ! self->statement) {
|
||||
self->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
self->errormsg = "No memory available to store statement";
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -92,6 +98,7 @@ StatementClass *self = (StatementClass *) hstmt;
|
|||
if ( CC_is_readonly(self->hdbc) && STMT_UPDATE(self)) {
|
||||
self->errornumber = STMT_EXEC_ERROR;
|
||||
self->errormsg = "Connection is readonly, only select statements are allowed.";
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -110,9 +117,12 @@ RETCODE SQL_API SQLExecDirect(
|
|||
SDWORD cbSqlStr)
|
||||
{
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char *func = "SQLExecDirect";
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (stmt->statement)
|
||||
free(stmt->statement);
|
||||
|
@ -123,6 +133,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
if ( ! stmt->statement) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "No memory available to store statement";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -135,6 +146,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
if ( CC_is_readonly(stmt->hdbc) && STMT_UPDATE(stmt)) {
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
stmt->errormsg = "Connection is readonly, only select statements are allowed.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -147,13 +159,16 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
RETCODE SQL_API SQLExecute(
|
||||
HSTMT hstmt)
|
||||
{
|
||||
char *func="SQLExecute";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
ConnectionClass *conn;
|
||||
int i, retval;
|
||||
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* If the statement is premature, it means we already executed
|
||||
it from an SQLPrepare/SQLDescribeCol type of scenario. So
|
||||
|
@ -161,7 +176,12 @@ int i, retval;
|
|||
*/
|
||||
if ( stmt->prepare && stmt->status == STMT_PREMATURE) {
|
||||
stmt->status = STMT_FINISHED;
|
||||
return stmt->errormsg == NULL ? SQL_SUCCESS : SQL_ERROR;
|
||||
if (stmt->errormsg == NULL)
|
||||
return SQL_SUCCESS;
|
||||
else {
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
@ -170,12 +190,14 @@ int i, retval;
|
|||
if (conn->status == CONN_EXECUTING) {
|
||||
stmt->errormsg = "Connection is already in use.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if ( ! stmt->statement) {
|
||||
stmt->errornumber = STMT_NO_STMTSTRING;
|
||||
stmt->errormsg = "This handle does not have a SQL statement stored in it";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -193,6 +215,7 @@ int i, retval;
|
|||
|
||||
stmt->errornumber = STMT_STATUS_ERROR;
|
||||
stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -240,6 +263,7 @@ RETCODE SQL_API SQLTransact(
|
|||
HDBC hdbc,
|
||||
UWORD fType)
|
||||
{
|
||||
char *func = "SQLTransact";
|
||||
extern ConnectionClass *conns[];
|
||||
ConnectionClass *conn;
|
||||
QResultClass *res;
|
||||
|
@ -248,8 +272,10 @@ int lf;
|
|||
|
||||
mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
|
||||
|
||||
if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV)
|
||||
if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* If hdbc is null and henv is valid,
|
||||
it means transact all connections on that henv.
|
||||
|
@ -277,6 +303,7 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
|
|||
} else {
|
||||
conn->errornumber = CONN_INVALID_ARGUMENT_NO;
|
||||
conn->errormsg ="SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter";
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -288,15 +315,19 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
|
|||
res = CC_send_query(conn, stmt_string, NULL, NULL);
|
||||
CC_set_no_trans(conn);
|
||||
|
||||
if ( ! res)
|
||||
if ( ! res) {
|
||||
// error msg will be in the connection
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
ok = QR_command_successful(res);
|
||||
QR_Destructor(res);
|
||||
|
||||
if (!ok)
|
||||
if (!ok) {
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
@ -307,11 +338,14 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
|
|||
RETCODE SQL_API SQLCancel(
|
||||
HSTMT hstmt) // Statement to cancel.
|
||||
{
|
||||
char *func="SQLCancel";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
// Check if this can handle canceling in the middle of a SQLPutData?
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
// Not in the middle of SQLParamData/SQLPutData so cancel like a close.
|
||||
if (stmt->data_at_exec < 0)
|
||||
|
@ -354,11 +388,14 @@ RETCODE SQL_API SQLParamData(
|
|||
HSTMT hstmt,
|
||||
PTR FAR *prgbValue)
|
||||
{
|
||||
char *func = "SQLParamData";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
int i, retval;
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
mylog("SQLParamData, enter: data_at_exec=%d, params_alloc=%d\n",
|
||||
stmt->data_at_exec, stmt->parameters_allocated);
|
||||
|
@ -366,12 +403,14 @@ int i, retval;
|
|||
if (stmt->data_at_exec < 0) {
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "No execution-time parameters for this statement";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if (stmt->data_at_exec > stmt->parameters_allocated) {
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "Too many execution-time parameters were present";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -422,19 +461,23 @@ RETCODE SQL_API SQLPutData(
|
|||
PTR rgbValue,
|
||||
SDWORD cbValue)
|
||||
{
|
||||
char *func = "SQLPutData";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
int old_pos, retval;
|
||||
ParameterInfoClass *current_param;
|
||||
char *buffer;
|
||||
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
if (stmt->current_exec_param < 0) {
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "Previous call was not SQLPutData or SQLParamData";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -450,6 +493,7 @@ char *buffer;
|
|||
if ( ! current_param->EXEC_used) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Out of memory in SQLPutData (1)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -467,6 +511,7 @@ char *buffer;
|
|||
if (current_param->lobj_oid == 0) {
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
stmt->errormsg = "Couldnt create large object.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -479,6 +524,7 @@ char *buffer;
|
|||
if ( stmt->lobj_fd < 0) {
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
stmt->errormsg = "Couldnt open large object for writing.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -493,6 +539,7 @@ char *buffer;
|
|||
if ( ! current_param->EXEC_buffer) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Out of memory in SQLPutData (2)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -501,6 +548,7 @@ char *buffer;
|
|||
if ( ! current_param->EXEC_buffer) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Out of memory in SQLPutData (2)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
memcpy(current_param->EXEC_buffer, rgbValue, cbValue);
|
||||
|
@ -530,6 +578,7 @@ char *buffer;
|
|||
if ( ! buffer) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Out of memory in SQLPutData (3)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
strcat(buffer, rgbValue);
|
||||
|
@ -555,6 +604,7 @@ char *buffer;
|
|||
if ( ! buffer) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Out of memory in SQLPutData (3)";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -565,8 +615,10 @@ char *buffer;
|
|||
current_param->EXEC_buffer = buffer;
|
||||
|
||||
}
|
||||
else
|
||||
else {
|
||||
SC_log_error(func, "bad cbValue", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,24 +45,19 @@ RETCODE SQL_API SQLGetInfo(
|
|||
SWORD cbInfoValueMax,
|
||||
SWORD FAR *pcbInfoValue)
|
||||
{
|
||||
char *func = "SQLGetInfo";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
char *p;
|
||||
|
||||
if ( ! conn)
|
||||
return SQL_INVALID_HANDLE;
|
||||
|
||||
/* CC: Some sanity checks */
|
||||
if ((NULL == (char *)rgbInfoValue) ||
|
||||
(cbInfoValueMax == 0))
|
||||
|
||||
/* removed: */
|
||||
/* || (NULL == pcbInfoValue) */
|
||||
|
||||
/* pcbInfoValue is ignored for non-character output. */
|
||||
/* some programs (at least Microsoft Query) seem to just send a NULL, */
|
||||
/* so let them get away with it... */
|
||||
if ( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (NULL == (char *)rgbInfoValue) {
|
||||
CC_log_error(func, "Bad rgbInfoValue", conn);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
switch (fInfoType) {
|
||||
|
@ -70,13 +65,13 @@ char *p;
|
|||
// can the user call all functions returned by SQLProcedures?
|
||||
// I assume access permissions could prevent this in some cases(?)
|
||||
// anyway, SQLProcedures doesn't exist yet.
|
||||
*pcbInfoValue = 1;
|
||||
if (pcbInfoValue) *pcbInfoValue = 1;
|
||||
strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax);
|
||||
break;
|
||||
|
||||
case SQL_ACCESSIBLE_TABLES: /* ODBC 1.0 */
|
||||
// is the user guaranteed "SELECT" on every table?
|
||||
*pcbInfoValue = 1;
|
||||
if (pcbInfoValue) *pcbInfoValue = 1;
|
||||
strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax);
|
||||
break;
|
||||
|
||||
|
@ -108,7 +103,7 @@ char *p;
|
|||
|
||||
case SQL_COLUMN_ALIAS: /* ODBC 2.0 */
|
||||
// do we support column aliases? guess not.
|
||||
*pcbInfoValue = 1;
|
||||
if (pcbInfoValue) *pcbInfoValue = 1;
|
||||
strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax);
|
||||
break;
|
||||
|
||||
|
@ -294,6 +289,7 @@ char *p;
|
|||
// do this later
|
||||
conn->errormsg = "SQL_KEYWORDS parameter to SQLGetInfo not implemented.";
|
||||
conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
break;
|
||||
|
||||
|
@ -398,7 +394,7 @@ char *p;
|
|||
case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */
|
||||
// does the preceding value include LONGVARCHAR and LONGVARBINARY
|
||||
// fields? Well, it does include longvarchar, but not longvarbinary.
|
||||
*pcbInfoValue = 1;
|
||||
if (pcbInfoValue) *pcbInfoValue = 1;
|
||||
strncpy_null((char *)rgbInfoValue, "Y", (size_t)cbInfoValueMax);
|
||||
break;
|
||||
|
||||
|
@ -715,6 +711,7 @@ char *p;
|
|||
/* unrecognized key */
|
||||
conn->errormsg = "Unrecognized key passed to SQLGetInfo.";
|
||||
conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -728,6 +725,7 @@ RETCODE SQL_API SQLGetTypeInfo(
|
|||
HSTMT hstmt,
|
||||
SWORD fSqlType)
|
||||
{
|
||||
char *func = "SQLGetTypeInfo";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
TupleNode *row;
|
||||
int i;
|
||||
|
@ -736,12 +734,14 @@ Int4 type;
|
|||
mylog("**** in SQLGetTypeInfo: fSqlType = %d\n", fSqlType);
|
||||
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
stmt->manual_result = TRUE;
|
||||
stmt->result = QR_Constructor();
|
||||
if( ! stmt->result) {
|
||||
SC_log_error(func, "Error creating result.", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -976,6 +976,7 @@ RETCODE SQL_API SQLTables(
|
|||
UCHAR FAR * szTableType,
|
||||
SWORD cbTableType)
|
||||
{
|
||||
char *func = "SQLTables";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
StatementClass *tbl_stmt;
|
||||
TupleNode *row;
|
||||
|
@ -993,8 +994,10 @@ int i;
|
|||
|
||||
mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
stmt->manual_result = TRUE;
|
||||
stmt->errormsg_created = TRUE;
|
||||
|
@ -1005,6 +1008,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Couldn't allocate statement for SQLTables result.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
tbl_stmt = (StatementClass *) htbl_stmt;
|
||||
|
@ -1086,6 +1090,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = SC_create_errormsg(htbl_stmt);
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1095,6 +1100,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1104,6 +1110,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1112,6 +1119,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1120,6 +1128,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if(!stmt->result) {
|
||||
stmt->errormsg = "Couldn't allocate memory for SQLTables result.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1201,6 +1210,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
|
|||
if(result != SQL_NO_DATA_FOUND) {
|
||||
stmt->errormsg = SC_create_errormsg(htbl_stmt);
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1229,6 +1239,7 @@ RETCODE SQL_API SQLColumns(
|
|||
UCHAR FAR * szColumnName,
|
||||
SWORD cbColumnName)
|
||||
{
|
||||
char *func = "SQLColumns";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
TupleNode *row;
|
||||
HSTMT hcol_stmt;
|
||||
|
@ -1238,6 +1249,7 @@ RETCODE result;
|
|||
char table_owner[MAX_INFO_STRING], table_name[MAX_INFO_STRING], field_name[MAX_INFO_STRING], field_type_name[MAX_INFO_STRING];
|
||||
Int2 field_number, field_length, mod_length;
|
||||
Int4 field_type;
|
||||
Int2 the_type;
|
||||
char not_null[MAX_INFO_STRING];
|
||||
ConnInfo *ci;
|
||||
|
||||
|
@ -1245,8 +1257,10 @@ ConnInfo *ci;
|
|||
|
||||
mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
stmt->manual_result = TRUE;
|
||||
stmt->errormsg_created = TRUE;
|
||||
|
@ -1273,6 +1287,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Couldn't allocate statement for SQLColumns result.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
col_stmt = (StatementClass *) hcol_stmt;
|
||||
|
@ -1282,6 +1297,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = SC_create_errormsg(hcol_stmt);
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1291,6 +1307,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1300,6 +1317,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1309,6 +1327,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1318,6 +1337,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1327,6 +1347,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1336,6 +1357,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1345,6 +1367,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1354,6 +1377,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1363,6 +1387,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = col_stmt->errormsg;
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1371,6 +1396,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if(!stmt->result) {
|
||||
stmt->errormsg = "Couldn't allocate memory for SQLColumns result.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1402,33 +1428,37 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
Always show OID if its a system table
|
||||
*/
|
||||
|
||||
if (result != SQL_ERROR && ! stmt->internal &&
|
||||
(atoi(ci->show_oid_column) || strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0)) {
|
||||
if (result != SQL_ERROR && ! stmt->internal) {
|
||||
|
||||
/* For OID fields */
|
||||
row = (TupleNode *)malloc(sizeof(TupleNode) +
|
||||
(12 - 1) * sizeof(TupleField));
|
||||
if (atoi(ci->show_oid_column) || strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0) {
|
||||
|
||||
set_tuplefield_string(&row->tuple[0], "");
|
||||
// see note in SQLTables()
|
||||
// set_tuplefield_string(&row->tuple[1], table_owner);
|
||||
set_tuplefield_string(&row->tuple[1], "");
|
||||
set_tuplefield_string(&row->tuple[2], table_name);
|
||||
set_tuplefield_string(&row->tuple[3], "oid");
|
||||
set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, PG_TYPE_OID));
|
||||
set_tuplefield_string(&row->tuple[5], "OID");
|
||||
/* For OID fields */
|
||||
the_type = PG_TYPE_OID;
|
||||
row = (TupleNode *)malloc(sizeof(TupleNode) +
|
||||
(12 - 1) * sizeof(TupleField));
|
||||
|
||||
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, PG_TYPE_OID, PG_STATIC,
|
||||
PG_STATIC));
|
||||
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, PG_TYPE_OID, PG_STATIC,
|
||||
PG_STATIC));
|
||||
set_tuplefield_string(&row->tuple[0], "");
|
||||
// see note in SQLTables()
|
||||
// set_tuplefield_string(&row->tuple[1], table_owner);
|
||||
set_tuplefield_string(&row->tuple[1], "");
|
||||
set_tuplefield_string(&row->tuple[2], table_name);
|
||||
set_tuplefield_string(&row->tuple[3], "oid");
|
||||
set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type));
|
||||
set_tuplefield_string(&row->tuple[5], "OID");
|
||||
|
||||
set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, PG_TYPE_OID));
|
||||
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, PG_TYPE_OID));
|
||||
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
|
||||
set_tuplefield_string(&row->tuple[11], "");
|
||||
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC,
|
||||
PG_STATIC));
|
||||
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC,
|
||||
PG_STATIC));
|
||||
|
||||
set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type));
|
||||
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
|
||||
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
|
||||
set_tuplefield_string(&row->tuple[11], "");
|
||||
|
||||
QR_add_tuple(stmt->result, row);
|
||||
}
|
||||
|
||||
QR_add_tuple(stmt->result, row);
|
||||
}
|
||||
|
||||
while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) {
|
||||
|
@ -1484,10 +1514,36 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
|
|||
if(result != SQL_NO_DATA_FOUND) {
|
||||
stmt->errormsg = SC_create_errormsg(hcol_stmt);
|
||||
stmt->errornumber = col_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(hcol_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
// Put the row version column at the end so it might not be
|
||||
// mistaken for a key field.
|
||||
if ( ! stmt->internal && atoi(ci->row_versioning)) {
|
||||
/* For Row Versioning fields */
|
||||
the_type = PG_TYPE_INT4;
|
||||
|
||||
row = (TupleNode *)malloc(sizeof(TupleNode) +
|
||||
(12 - 1) * sizeof(TupleField));
|
||||
|
||||
set_tuplefield_string(&row->tuple[0], "");
|
||||
set_tuplefield_string(&row->tuple[1], "");
|
||||
set_tuplefield_string(&row->tuple[2], table_name);
|
||||
set_tuplefield_string(&row->tuple[3], "xmin");
|
||||
set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type));
|
||||
set_tuplefield_string(&row->tuple[5], pgtype_to_name(stmt, the_type));
|
||||
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
|
||||
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
|
||||
set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type));
|
||||
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
|
||||
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
|
||||
set_tuplefield_string(&row->tuple[11], "");
|
||||
|
||||
QR_add_tuple(stmt->result, row);
|
||||
}
|
||||
|
||||
// also, things need to think that this statement is finished so
|
||||
// the results can be retrieved.
|
||||
stmt->status = STMT_FINISHED;
|
||||
|
@ -1513,14 +1569,20 @@ RETCODE SQL_API SQLSpecialColumns(
|
|||
UWORD fScope,
|
||||
UWORD fNullable)
|
||||
{
|
||||
char *func = "SQLSpecialColumns";
|
||||
TupleNode *row;
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
ConnInfo *ci;
|
||||
|
||||
|
||||
mylog("**** SQLSpecialColumns(): ENTER, stmt=%u\n", stmt);
|
||||
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
ci = &stmt->hdbc->connInfo;
|
||||
|
||||
stmt->manual_result = TRUE;
|
||||
stmt->result = QR_Constructor();
|
||||
extend_bindings(stmt, 8);
|
||||
|
@ -1551,11 +1613,24 @@ mylog("**** SQLSpecialColumns(): ENTER, stmt=%u\n", stmt);
|
|||
QR_add_tuple(stmt->result, row);
|
||||
|
||||
} else if(fColType == SQL_ROWVER) {
|
||||
/* can columns automatically update? */
|
||||
/* for now assume no. */
|
||||
/* return an empty result. */
|
||||
}
|
||||
|
||||
Int2 the_type = PG_TYPE_INT4;
|
||||
|
||||
if (atoi(ci->row_versioning)) {
|
||||
row = (TupleNode *)malloc(sizeof(TupleNode) + (8 - 1) * sizeof(TupleField));
|
||||
|
||||
set_tuplefield_null(&row->tuple[0]);
|
||||
set_tuplefield_string(&row->tuple[1], "xmin");
|
||||
set_tuplefield_int2(&row->tuple[2], pgtype_to_sqltype(stmt, the_type));
|
||||
set_tuplefield_string(&row->tuple[3], pgtype_to_name(stmt, the_type));
|
||||
set_tuplefield_int4(&row->tuple[4], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
|
||||
set_tuplefield_int4(&row->tuple[5], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
|
||||
set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, the_type));
|
||||
set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO);
|
||||
|
||||
QR_add_tuple(stmt->result, row);
|
||||
}
|
||||
}
|
||||
stmt->status = STMT_FINISHED;
|
||||
stmt->currTuple = -1;
|
||||
stmt->current_col = -1;
|
||||
|
@ -1575,6 +1650,7 @@ RETCODE SQL_API SQLStatistics(
|
|||
UWORD fUnique,
|
||||
UWORD fAccuracy)
|
||||
{
|
||||
char *func="SQLStatistics";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char index_query[MAX_STATEMENT_LEN];
|
||||
HSTMT hindx_stmt;
|
||||
|
@ -1599,6 +1675,7 @@ char buf[256];
|
|||
mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt);
|
||||
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
@ -1611,6 +1688,7 @@ mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt);
|
|||
if(!stmt->result) {
|
||||
stmt->errormsg = "Couldn't allocate memory for SQLStatistics result.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1641,6 +1719,7 @@ mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt);
|
|||
if ( ! table_name) {
|
||||
stmt->errormsg = "No table name passed to SQLStatistics.";
|
||||
stmt->errornumber = STMT_INTERNAL_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1887,8 +1966,10 @@ SEEYA:
|
|||
|
||||
mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt);
|
||||
|
||||
if (error)
|
||||
if (error) {
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
else
|
||||
return SQL_SUCCESS;
|
||||
}
|
||||
|
@ -1904,13 +1985,17 @@ RETCODE SQL_API SQLColumnPrivileges(
|
|||
UCHAR FAR * szColumnName,
|
||||
SWORD cbColumnName)
|
||||
{
|
||||
char *func="SQLColumnPrivileges";
|
||||
/* Neither Access or Borland care about this. */
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
RETCODE
|
||||
getPrimaryKeyString(StatementClass *stmt, char *szTableName, SWORD cbTableName, char *svKey, int *nKey)
|
||||
{
|
||||
char *func = "getPrimaryKeyString";
|
||||
HSTMT htbl_stmt;
|
||||
StatementClass *tbl_stmt;
|
||||
RETCODE result;
|
||||
|
@ -1930,6 +2015,7 @@ int nk = 0;
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Couldn't allocate statement for Primary Key result.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
tbl_stmt = (StatementClass *) htbl_stmt;
|
||||
|
@ -1940,6 +2026,7 @@ int nk = 0;
|
|||
|
||||
stmt->errormsg = "No Table specified to getPrimaryKeyString.";
|
||||
stmt->errornumber = STMT_INTERNAL_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1950,6 +2037,7 @@ int nk = 0;
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = SC_create_errormsg(htbl_stmt);
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1959,6 +2047,7 @@ int nk = 0;
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -1977,6 +2066,7 @@ int nk = 0;
|
|||
if(result != SQL_NO_DATA_FOUND) {
|
||||
stmt->errormsg = SC_create_errormsg(htbl_stmt);
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2034,6 +2124,7 @@ RETCODE SQL_API SQLPrimaryKeys(
|
|||
UCHAR FAR * szTableName,
|
||||
SWORD cbTableName)
|
||||
{
|
||||
char *func = "SQLPrimaryKeys";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
TupleNode *row;
|
||||
RETCODE result;
|
||||
|
@ -2043,6 +2134,7 @@ int seq = 1, nkeys = 0;
|
|||
mylog("**** SQLPrimaryKeys(): ENTER, stmt=%u\n", stmt);
|
||||
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
stmt->manual_result = TRUE;
|
||||
|
@ -2068,6 +2160,7 @@ mylog("**** SQLPrimaryKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if(!stmt->result) {
|
||||
stmt->errormsg = "Couldn't allocate memory for SQLPrimaryKeys result.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2137,6 +2230,7 @@ RETCODE SQL_API SQLForeignKeys(
|
|||
UCHAR FAR * szFkTableName,
|
||||
SWORD cbFkTableName)
|
||||
{
|
||||
char *func = "SQLForeignKeys";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
TupleNode *row;
|
||||
HSTMT htbl_stmt;
|
||||
|
@ -2156,6 +2250,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
memset(primaryKey, 0, sizeof(primaryKey));
|
||||
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
stmt->manual_result = TRUE;
|
||||
|
@ -2165,6 +2260,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
stmt->errormsg = "Couldn't allocate statement for SQLForeignKeys result.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2224,6 +2320,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
else {
|
||||
stmt->errormsg = "No tables specified to SQLForeignKeys.";
|
||||
stmt->errornumber = STMT_INTERNAL_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2232,6 +2329,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = SC_create_errormsg(htbl_stmt);
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2241,6 +2339,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2249,6 +2348,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2258,6 +2358,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
|
||||
stmt->errormsg = tbl_stmt->errormsg;
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2266,6 +2367,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if(!stmt->result) {
|
||||
stmt->errormsg = "Couldn't allocate memory for SQLForeignKeys result.";
|
||||
stmt->errornumber = STMT_NO_MEMORY_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2356,6 +2458,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
|
|||
if(result != SQL_NO_DATA_FOUND) {
|
||||
stmt->errormsg = SC_create_errormsg(htbl_stmt);
|
||||
stmt->errornumber = tbl_stmt->errornumber;
|
||||
SC_log_error(func, "", stmt);
|
||||
SQLFreeStmt(htbl_stmt, SQL_DROP);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
@ -2387,6 +2490,9 @@ RETCODE SQL_API SQLProcedureColumns(
|
|||
UCHAR FAR * szColumnName,
|
||||
SWORD cbColumnName)
|
||||
{
|
||||
char *func="SQLProcedureColumns";
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2399,6 +2505,9 @@ RETCODE SQL_API SQLProcedures(
|
|||
UCHAR FAR * szProcName,
|
||||
SWORD cbProcName)
|
||||
{
|
||||
char *func="SQLProcedures";
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2411,5 +2520,8 @@ RETCODE SQL_API SQLTablePrivileges(
|
|||
UCHAR FAR * szTableName,
|
||||
SWORD cbTableName)
|
||||
{
|
||||
char *func="SQLTablePrivileges";
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,14 @@ RETCODE SQL_API SQLSetConnectOption(
|
|||
UWORD fOption,
|
||||
UDWORD vParam)
|
||||
{
|
||||
char *func="SQLSetConnectOption";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
|
||||
if ( ! conn)
|
||||
if ( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
switch (fOption) {
|
||||
case SQL_AUTOCOMMIT:
|
||||
|
@ -46,6 +50,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||
if (CC_is_in_trans(conn)) {
|
||||
conn->errormsg = "Cannot switch commit mode while a transaction is in progres";
|
||||
conn->errornumber = CONN_TRANSACT_IN_PROGRES;
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
*/
|
||||
|
@ -64,6 +69,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||
default:
|
||||
conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT";
|
||||
conn->errornumber = CONN_INVALID_ARGUMENT_NO;
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -76,9 +82,14 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char option[32];
|
||||
conn->errormsg = "This option is currently unsupported by the driver";
|
||||
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
||||
sprintf(option, "fOption=%d", fOption);
|
||||
CC_log_error(func, option, conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
return SQL_SUCCESS;
|
||||
|
@ -92,10 +103,13 @@ RETCODE SQL_API SQLGetConnectOption(
|
|||
UWORD fOption,
|
||||
PTR pvParam)
|
||||
{
|
||||
char *func="SQLGetConnectOption";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
|
||||
if (! conn)
|
||||
if (! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
switch (fOption) {
|
||||
case SQL_AUTOCOMMIT:
|
||||
|
@ -111,10 +125,15 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
|
|||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char option[32];
|
||||
conn->errormsg = "This option is currently unsupported by the driver";
|
||||
conn->errornumber = CONN_UNSUPPORTED_OPTION;
|
||||
sprintf(option, "fOption=%d", fOption);
|
||||
CC_log_error(func, option, conn);
|
||||
return SQL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -128,6 +147,7 @@ RETCODE SQL_API SQLSetStmtOption(
|
|||
UWORD fOption,
|
||||
UDWORD vParam)
|
||||
{
|
||||
char *func="SQLSetStmtOption";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char changed = FALSE;
|
||||
|
||||
|
@ -135,8 +155,10 @@ char changed = FALSE;
|
|||
// all the time, but it tries to set a huge value for SQL_MAX_LENGTH
|
||||
// and expects the driver to reduce it to the real value
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
switch(fOption) {
|
||||
case SQL_QUERY_TIMEOUT:
|
||||
|
@ -170,6 +192,7 @@ char changed = FALSE;
|
|||
else {
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
stmt->errormsg = "Driver does not support keyset size option";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
@ -214,12 +237,18 @@ char changed = FALSE;
|
|||
case SQL_SIMULATE_CURSOR:
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
default:
|
||||
{
|
||||
char option[32];
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
stmt->errormsg = "Driver does not support this statement option";
|
||||
sprintf(option, "fOption=%d", fOption);
|
||||
SC_log_error(func, option, stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
|
@ -239,14 +268,17 @@ RETCODE SQL_API SQLGetStmtOption(
|
|||
UWORD fOption,
|
||||
PTR pvParam)
|
||||
{
|
||||
char *func="SQLGetStmtOption";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
// thought we could fake Access out by just returning SQL_SUCCESS
|
||||
// all the time, but it tries to set a huge value for SQL_MAX_LENGTH
|
||||
// and expects the driver to reduce it to the real value
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
switch(fOption) {
|
||||
case SQL_QUERY_TIMEOUT:
|
||||
|
@ -289,12 +321,18 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
case SQL_SIMULATE_CURSOR:
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
default:
|
||||
{
|
||||
char option[32];
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
stmt->errormsg = "Driver does not support this statement option";
|
||||
sprintf(option, "fOption=%d", fOption);
|
||||
SC_log_error(func, option, stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return SQL_SUCCESS;
|
||||
|
|
|
@ -46,7 +46,9 @@ Int4 pgtypes_defined[] = {
|
|||
PG_TYPE_BPCHAR,
|
||||
PG_TYPE_DATE,
|
||||
PG_TYPE_TIME,
|
||||
PG_TYPE_DATETIME,
|
||||
PG_TYPE_ABSTIME, /* a timestamp, sort of */
|
||||
PG_TYPE_TIMESTAMP,
|
||||
PG_TYPE_TEXT,
|
||||
PG_TYPE_INT2,
|
||||
PG_TYPE_INT4,
|
||||
|
@ -55,7 +57,6 @@ Int4 pgtypes_defined[] = {
|
|||
PG_TYPE_OID,
|
||||
PG_TYPE_MONEY,
|
||||
PG_TYPE_BOOL,
|
||||
PG_TYPE_DATETIME,
|
||||
PG_TYPE_BYTEA,
|
||||
PG_TYPE_LO,
|
||||
0 };
|
||||
|
@ -97,7 +98,8 @@ Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type)
|
|||
case PG_TYPE_DATE: return SQL_DATE;
|
||||
case PG_TYPE_TIME: return SQL_TIME;
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME: return SQL_TIMESTAMP;
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP: return SQL_TIMESTAMP;
|
||||
case PG_TYPE_MONEY: return SQL_FLOAT;
|
||||
case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_CHAR : SQL_BIT;
|
||||
|
||||
|
@ -124,7 +126,8 @@ Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type)
|
|||
case PG_TYPE_DATE: return SQL_C_DATE;
|
||||
case PG_TYPE_TIME: return SQL_C_TIME;
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME: return SQL_C_TIMESTAMP;
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP: return SQL_C_TIMESTAMP;
|
||||
case PG_TYPE_MONEY: return SQL_C_FLOAT;
|
||||
case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
|
||||
|
||||
|
@ -161,6 +164,7 @@ char *pgtype_to_name(StatementClass *stmt, Int4 type)
|
|||
case PG_TYPE_TIME: return "time";
|
||||
case PG_TYPE_ABSTIME: return "abstime";
|
||||
case PG_TYPE_DATETIME: return "datetime";
|
||||
case PG_TYPE_TIMESTAMP: return "timestamp";
|
||||
case PG_TYPE_MONEY: return "money";
|
||||
case PG_TYPE_BOOL: return "bool";
|
||||
case PG_TYPE_BYTEA: return "bytea";
|
||||
|
@ -269,7 +273,8 @@ Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unkno
|
|||
case PG_TYPE_TIME: return 8;
|
||||
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME: return 19;
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP: return 19;
|
||||
|
||||
case PG_TYPE_BOOL: return 1;
|
||||
|
||||
|
@ -327,7 +332,8 @@ Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_
|
|||
case PG_TYPE_TIME: return 6;
|
||||
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME: return 16;
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP: return 16;
|
||||
|
||||
|
||||
/* Character types use the default precision */
|
||||
|
@ -350,7 +356,8 @@ Int2 pgtype_scale(StatementClass *stmt, Int4 type)
|
|||
|
||||
/* Number of digits to the right of the decimal point in "yyyy-mm=dd hh:mm:ss[.f...]" */
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME: return 0;
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP: return 0;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
|
@ -391,7 +398,8 @@ Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type)
|
|||
case PG_TYPE_DATE:
|
||||
case PG_TYPE_TIME:
|
||||
case PG_TYPE_ABSTIME:
|
||||
case PG_TYPE_DATETIME: return FALSE;
|
||||
case PG_TYPE_DATETIME:
|
||||
case PG_TYPE_TIMESTAMP: return FALSE;
|
||||
|
||||
default: return -1;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#define PG_TYPE_DATE 1082
|
||||
#define PG_TYPE_TIME 1083
|
||||
#define PG_TYPE_DATETIME 1184
|
||||
#define PG_TYPE_TIMESTAMP 1296
|
||||
|
||||
extern Int4 pgtypes_defined[];
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@ typedef UInt4 Oid;
|
|||
/* Driver stuff */
|
||||
#define DRIVERNAME "PostgreSQL ODBC"
|
||||
#define DBMS_NAME "PostgreSQL"
|
||||
#define DBMS_VERSION "06.30.0244 PostgreSQL 6.3"
|
||||
#define POSTGRESDRIVERVERSION "06.30.0244"
|
||||
#define DBMS_VERSION "06.30.0246 PostgreSQL 6.3"
|
||||
#define POSTGRESDRIVERVERSION "06.30.0246"
|
||||
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
|
||||
|
||||
|
||||
|
|
|
@ -137,6 +137,8 @@ BEGIN
|
|||
WS_TABSTOP,130,10,60,14
|
||||
CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,25,30,85,10
|
||||
CONTROL "Row &Versioning",DS_ROWVERSIONING,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,130,30,85,10
|
||||
GROUPBOX "OID Options",IDC_STATIC,15,50,180,25
|
||||
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
|
||||
WS_GROUP | WS_TABSTOP,25,60,59,10
|
||||
|
@ -198,8 +200,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 6,30,2,44
|
||||
PRODUCTVERSION 6,30,2,44
|
||||
FILEVERSION 6,30,2,46
|
||||
PRODUCTVERSION 6,30,2,46
|
||||
FILEFLAGSMASK 0x3L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -217,12 +219,12 @@ BEGIN
|
|||
VALUE "Comments", "PostgreSQL ODBC driver for Windows 95\0"
|
||||
VALUE "CompanyName", "Insight Distribution Systems\0"
|
||||
VALUE "FileDescription", "PostgreSQL Driver\0"
|
||||
VALUE "FileVersion", " 6.30.0244\0"
|
||||
VALUE "FileVersion", " 6.30.0246\0"
|
||||
VALUE "InternalName", "psqlodbc\0"
|
||||
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
|
||||
VALUE "OriginalFilename", "psqlodbc.dll\0"
|
||||
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
|
||||
VALUE "ProductVersion", " 6.30.0244\0"
|
||||
VALUE "ProductVersion", " 6.30.0246\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#define DRV_BOOLS_CHAR 1050
|
||||
#define DS_SHOWSYSTEMTABLES 1051
|
||||
#define DRV_EXTRASYSTABLEPREFIXES 1051
|
||||
#define DS_ROWVERSIONING 1052
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
|
|
@ -36,12 +36,15 @@ RETCODE SQL_API SQLRowCount(
|
|||
HSTMT hstmt,
|
||||
SDWORD FAR *pcrow)
|
||||
{
|
||||
char *func="SQLRowCount";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
QResultClass *res;
|
||||
char *msg, *ptr;
|
||||
|
||||
if ( ! stmt)
|
||||
return SQL_ERROR;
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if(stmt->statement_type == STMT_TYPE_SELECT) {
|
||||
if (stmt->status == STMT_FINISHED) {
|
||||
|
@ -74,6 +77,7 @@ char *msg, *ptr;
|
|||
}
|
||||
}
|
||||
|
||||
SC_log_error(func, "Bad return value", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -86,11 +90,14 @@ RETCODE SQL_API SQLNumResultCols(
|
|||
HSTMT hstmt,
|
||||
SWORD FAR *pccol)
|
||||
{
|
||||
char *func="SQLNumResultCols";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
QResultClass *result;
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
|
@ -109,6 +116,7 @@ QResultClass *result;
|
|||
/* no query has been executed on this statement */
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "No query has been executed with that handle";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -133,6 +141,7 @@ RETCODE SQL_API SQLDescribeCol(
|
|||
SWORD FAR *pibScale,
|
||||
SWORD FAR *pfNullable)
|
||||
{
|
||||
char *func="SQLDescribeCol";
|
||||
/* gets all the information about a specific column */
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
QResultClass *result;
|
||||
|
@ -141,8 +150,10 @@ Int4 fieldtype;
|
|||
int p;
|
||||
ConnInfo *ci;
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
ci = &(stmt->hdbc->connInfo);
|
||||
|
||||
|
@ -162,6 +173,7 @@ ConnInfo *ci;
|
|||
/* no query has been executed on this statement */
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "No query has been assigned to this statement.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -169,6 +181,7 @@ ConnInfo *ci;
|
|||
// we do not support bookmarks
|
||||
stmt->errormsg = "Bookmarks are not currently supported.";
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -255,14 +268,17 @@ RETCODE SQL_API SQLColAttributes(
|
|||
SWORD FAR *pcbDesc,
|
||||
SDWORD FAR *pfDesc)
|
||||
{
|
||||
char *func = "SQLColAttributes";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
char *value;
|
||||
Int4 field_type;
|
||||
ConnInfo *ci;
|
||||
int unknown_sizes;
|
||||
|
||||
if( ! stmt)
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
ci = &(stmt->hdbc->connInfo);
|
||||
|
||||
|
@ -277,6 +293,7 @@ int unknown_sizes;
|
|||
if ( (NULL == stmt->result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)) ) {
|
||||
stmt->errormsg = "Can't get column attributes: no result found.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -284,6 +301,7 @@ int unknown_sizes;
|
|||
// we do not support bookmarks
|
||||
stmt->errormsg = "Bookmarks are not currently supported.";
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -436,6 +454,7 @@ RETCODE SQL_API SQLGetData(
|
|||
SDWORD cbValueMax,
|
||||
SDWORD FAR *pcbValue)
|
||||
{
|
||||
char *func="SQLGetData";
|
||||
QResultClass *res;
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
int num_cols, num_rows;
|
||||
|
@ -448,6 +467,7 @@ char multiple;
|
|||
mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
||||
|
||||
if( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
res = stmt->result;
|
||||
|
@ -455,18 +475,21 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
if (STMT_EXECUTING == stmt->status) {
|
||||
stmt->errormsg = "Can't get data while statement is still executing.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
return 0;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if (stmt->status != STMT_FINISHED) {
|
||||
stmt->errornumber = STMT_STATUS_ERROR;
|
||||
stmt->errormsg = "GetData can only be called after the successful execution on a SQL statement";
|
||||
return 0;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if (icol == 0) {
|
||||
stmt->errormsg = "Bookmarks are not currently supported.";
|
||||
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -478,6 +501,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
if (icol >= num_cols) {
|
||||
stmt->errormsg = "Invalid column number.";
|
||||
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -488,6 +512,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
(stmt->currTuple >= num_rows)) {
|
||||
stmt->errormsg = "Not positioned on a valid row for GetData.";
|
||||
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
mylog(" num_rows = %d\n", num_rows);
|
||||
|
@ -503,6 +528,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
if (stmt->currTuple == -1 || ! res || QR_end_tuples(res)) {
|
||||
stmt->errormsg = "Not positioned on a valid row for GetData.";
|
||||
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -531,11 +557,13 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
case COPY_UNSUPPORTED_TYPE:
|
||||
stmt->errormsg = "Received an unsupported type from Postgres.";
|
||||
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
case COPY_UNSUPPORTED_CONVERSION:
|
||||
stmt->errormsg = "Couldn't handle the necessary data type conversion.";
|
||||
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
case COPY_RESULT_TRUNCATED:
|
||||
|
@ -544,14 +572,17 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
return SQL_SUCCESS_WITH_INFO;
|
||||
|
||||
case COPY_GENERAL_ERROR: /* error msg already filled in */
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
case COPY_NO_DATA_FOUND:
|
||||
SC_log_error(func, "no data found", stmt);
|
||||
return SQL_NO_DATA_FOUND;
|
||||
|
||||
default:
|
||||
stmt->errormsg = "Unrecognized return value from copy_and_convert_field.";
|
||||
stmt->errornumber = STMT_INTERNAL_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -562,6 +593,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
|
|||
RETCODE SQL_API SQLFetch(
|
||||
HSTMT hstmt)
|
||||
{
|
||||
char *func = "SQLFetch";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
QResultClass *res;
|
||||
int retval;
|
||||
|
@ -571,14 +603,17 @@ char *value;
|
|||
ColumnInfoClass *ci;
|
||||
// TupleField *tupleField;
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
SC_clear_error(stmt);
|
||||
|
||||
if ( ! (res = stmt->result)) {
|
||||
stmt->errormsg = "Null statement result in SQLFetch.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -587,6 +622,7 @@ ColumnInfoClass *ci;
|
|||
if (stmt->status == STMT_EXECUTING) {
|
||||
stmt->errormsg = "Can't fetch while statement is still executing.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -594,6 +630,7 @@ ColumnInfoClass *ci;
|
|||
if (stmt->status != STMT_FINISHED) {
|
||||
stmt->errornumber = STMT_STATUS_ERROR;
|
||||
stmt->errormsg = "Fetch can only be called after the successful execution on a SQL statement";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -602,6 +639,7 @@ ColumnInfoClass *ci;
|
|||
// function even if SQL_ExecDirect has reported an Error
|
||||
stmt->errormsg = "Bindings were not allocated properly.";
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -638,6 +676,7 @@ ColumnInfoClass *ci;
|
|||
mylog("SQLFetch: error\n");
|
||||
stmt->errornumber = STMT_EXEC_ERROR;
|
||||
stmt->errormsg = "Error fetching next row";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -675,11 +714,13 @@ ColumnInfoClass *ci;
|
|||
if(retval == COPY_UNSUPPORTED_TYPE) {
|
||||
stmt->errormsg = "Received an unsupported type from Postgres.";
|
||||
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
} else if(retval == COPY_UNSUPPORTED_CONVERSION) {
|
||||
stmt->errormsg = "Couldn't handle the necessary data type conversion.";
|
||||
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
} else if(retval == COPY_RESULT_TRUNCATED) {
|
||||
|
@ -692,6 +733,7 @@ ColumnInfoClass *ci;
|
|||
} else if(retval != COPY_OK) {
|
||||
stmt->errormsg = "Unrecognized return value from copy_and_convert_field.";
|
||||
stmt->errornumber = STMT_INTERNAL_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
}
|
||||
|
@ -710,6 +752,7 @@ RETCODE SQL_API SQLExtendedFetch(
|
|||
UDWORD FAR *pcrow,
|
||||
UWORD FAR *rgfRowStatus)
|
||||
{
|
||||
char *func = "SQLExtendedFetch";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
int num_tuples;
|
||||
RETCODE result;
|
||||
|
@ -717,11 +760,15 @@ RETCODE result;
|
|||
|
||||
mylog("SQLExtendedFetch: stmt=%u\n", stmt);
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if ( globals.use_declarefetch)
|
||||
if ( globals.use_declarefetch) {
|
||||
SC_log_error(func, "SQLExtendedFetch with UseDeclareFetch not yet supported", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize to no rows fetched */
|
||||
if (rgfRowStatus)
|
||||
|
@ -776,6 +823,7 @@ mylog("SQLExtendedFetch: stmt=%u\n", stmt);
|
|||
break;
|
||||
|
||||
default:
|
||||
SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt);
|
||||
return SQL_ERROR;
|
||||
|
||||
}
|
||||
|
@ -803,7 +851,7 @@ mylog("SQLExtendedFetch: stmt=%u\n", stmt);
|
|||
RETCODE SQL_API SQLMoreResults(
|
||||
HSTMT hstmt)
|
||||
{
|
||||
return SQL_NO_DATA_FOUND;
|
||||
return SQL_NO_DATA_FOUND;
|
||||
}
|
||||
|
||||
// This positions the cursor within a block of data.
|
||||
|
@ -814,7 +862,10 @@ RETCODE SQL_API SQLSetPos(
|
|||
UWORD fOption,
|
||||
UWORD fLock)
|
||||
{
|
||||
return SQL_ERROR;
|
||||
char *func = "SQLSetPos";
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
// Sets options that control the behavior of cursors.
|
||||
|
@ -825,7 +876,10 @@ RETCODE SQL_API SQLSetScrollOptions(
|
|||
SDWORD crowKeyset,
|
||||
UWORD crowRowset)
|
||||
{
|
||||
return SQL_ERROR;
|
||||
char *func = "SQLSetScrollOptions";
|
||||
|
||||
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -836,20 +890,24 @@ RETCODE SQL_API SQLSetCursorName(
|
|||
UCHAR FAR *szCursor,
|
||||
SWORD cbCursor)
|
||||
{
|
||||
char *func="SQLSetCursorName";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
int len;
|
||||
|
||||
mylog("SQLSetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n",
|
||||
hstmt, szCursor, cbCursor);
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
len = (cbCursor == SQL_NTS) ? strlen(szCursor) : cbCursor;
|
||||
mylog("cursor len = %d\n", len);
|
||||
if (len <= 0 || len > sizeof(stmt->cursor_name) - 1) {
|
||||
stmt->errornumber = STMT_INVALID_CURSOR_NAME;
|
||||
stmt->errormsg = "Invalid Cursor Name";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
strncpy_null(stmt->cursor_name, szCursor, cbCursor);
|
||||
|
@ -864,18 +922,22 @@ RETCODE SQL_API SQLGetCursorName(
|
|||
SWORD cbCursorMax,
|
||||
SWORD FAR *pcbCursor)
|
||||
{
|
||||
char *func="SQLGetCursorName";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n",
|
||||
hstmt, szCursor, cbCursorMax, pcbCursor);
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
if ( stmt->cursor_name[0] == '\0') {
|
||||
stmt->errornumber = STMT_NO_CURSOR_NAME;
|
||||
stmt->errormsg = "No Cursor name available";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,11 +46,14 @@ static struct {
|
|||
RETCODE SQL_API SQLAllocStmt(HDBC hdbc,
|
||||
HSTMT FAR *phstmt)
|
||||
{
|
||||
char *func="SQLAllocStmt";
|
||||
ConnectionClass *conn = (ConnectionClass *) hdbc;
|
||||
StatementClass *stmt;
|
||||
|
||||
if( ! conn)
|
||||
if( ! conn) {
|
||||
CC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
stmt = SC_Constructor();
|
||||
|
||||
|
@ -60,12 +63,14 @@ StatementClass *stmt;
|
|||
conn->errornumber = CONN_STMT_ALLOC_ERROR;
|
||||
conn->errormsg = "No more memory to allocate a further SQL-statement";
|
||||
*phstmt = SQL_NULL_HSTMT;
|
||||
CC_log_error(func, "", conn);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
if ( ! CC_add_statement(conn, stmt)) {
|
||||
conn->errormsg = "Maximum number of connections exceeded.";
|
||||
conn->errornumber = CONN_STMT_ALLOC_ERROR;
|
||||
CC_log_error(func, "", conn);
|
||||
SC_Destructor(stmt);
|
||||
*phstmt = SQL_NULL_HSTMT;
|
||||
return SQL_ERROR;
|
||||
|
@ -80,12 +85,15 @@ StatementClass *stmt;
|
|||
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
|
||||
UWORD fOption)
|
||||
{
|
||||
char *func="SQLFreeStmt";
|
||||
StatementClass *stmt = (StatementClass *) hstmt;
|
||||
|
||||
mylog("**** enter SQLFreeStmt: hstmt=%u, fOption=%d\n", hstmt, fOption);
|
||||
|
||||
if ( ! stmt)
|
||||
if ( ! stmt) {
|
||||
SC_log_error(func, "", NULL);
|
||||
return SQL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (fOption == SQL_DROP) {
|
||||
ConnectionClass *conn = stmt->hdbc;
|
||||
|
@ -95,6 +103,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
if ( ! CC_remove_statement(conn, stmt)) {
|
||||
stmt->errornumber = STMT_SEQUENCE_ERROR;
|
||||
stmt->errormsg = "Statement is currently executing a transaction.";
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR; /* stmt may be executing a transaction */
|
||||
}
|
||||
|
||||
|
@ -116,9 +125,11 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
|
||||
/* this should discard all the results, but leave the statement */
|
||||
/* itself in place (it can be executed again) */
|
||||
if (!SC_recycle_statement(stmt))
|
||||
if (!SC_recycle_statement(stmt)) {
|
||||
// errormsg passed in above
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
} else if(fOption == SQL_RESET_PARAMS) {
|
||||
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
|
||||
|
@ -126,6 +137,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
|
|||
} else {
|
||||
stmt->errormsg = "Invalid option passed to SQLFreeStmt.";
|
||||
stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;
|
||||
SC_log_error(func, "", stmt);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -447,6 +459,7 @@ char rv;
|
|||
|
||||
RETCODE SC_execute(StatementClass *self)
|
||||
{
|
||||
char *func="SC_execute";
|
||||
ConnectionClass *conn;
|
||||
QResultClass *res;
|
||||
char ok, was_ok, was_nonfatal;
|
||||
|
@ -466,6 +479,7 @@ Int2 oldstatus, numcols;
|
|||
if ( ! res) {
|
||||
self->errormsg = "Could not begin a transaction";
|
||||
self->errornumber = STMT_EXEC_ERROR;
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -478,6 +492,7 @@ Int2 oldstatus, numcols;
|
|||
if (!ok) {
|
||||
self->errormsg = "Could not begin a transaction";
|
||||
self->errornumber = STMT_EXEC_ERROR;
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
else
|
||||
|
@ -554,6 +569,7 @@ Int2 oldstatus, numcols;
|
|||
if (self->bindings == NULL) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -582,6 +598,43 @@ Int2 oldstatus, numcols;
|
|||
else if (self->errornumber == STMT_INFO_ONLY)
|
||||
return SQL_SUCCESS_WITH_INFO;
|
||||
|
||||
else
|
||||
else {
|
||||
SC_log_error(func, "", self);
|
||||
return SQL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SC_log_error(char *func, char *desc, StatementClass *self)
|
||||
{
|
||||
if (self) {
|
||||
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
|
||||
qlog(" ------------------------------------------------------------\n");
|
||||
qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, self->result);
|
||||
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);
|
||||
qlog(" statement_type=%d, statement='%s'\n", self->statement_type, self->statement);
|
||||
qlog(" stmt_with_params='%s'\n", self->stmt_with_params);
|
||||
qlog(" data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data);
|
||||
qlog(" currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd);
|
||||
qlog(" maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->maxRows, self->rowset_size, self->keyset_size, self->cursor_type, self->scroll_concurrency);
|
||||
qlog(" cursor_name='%s'\n", self->cursor_name);
|
||||
|
||||
qlog(" ----------------QResult Info -------------------------------\n");
|
||||
|
||||
if (self->result) {
|
||||
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, res->cursor);
|
||||
qlog(" message='%s', command='%s', notice='%s'\n", res->message, res->command, res->notice);
|
||||
qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples);
|
||||
}
|
||||
|
||||
// Log the connection error if there is one
|
||||
CC_log_error(func, desc, self->hdbc);
|
||||
}
|
||||
else
|
||||
qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,5 +132,6 @@ char SC_get_error(StatementClass *self, int *number, char **message);
|
|||
char *SC_create_errormsg(StatementClass *self);
|
||||
RETCODE SC_execute(StatementClass *stmt);
|
||||
void SC_free_params(StatementClass *self, char option);
|
||||
void SC_log_error(char *func, char *desc, StatementClass *self);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue