Commit a80771f0 authored by Byron Nikolaidis's avatar Byron Nikolaidis

Update to v.0246

parent fd262dac
......@@ -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
This diff is collapsed.
......@@ -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;
}
}
}
......
This diff is collapsed.
......@@ -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
//
......
This diff is collapsed.
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment