diff options
Diffstat (limited to 'src/interfaces/odbc/execute.c')
-rw-r--r-- | src/interfaces/odbc/execute.c | 629 |
1 files changed, 274 insertions, 355 deletions
diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index ac7f2ee30f4..ac5d0b19c38 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -1,14 +1,15 @@ -/* Module: execute.c + +/* Module: execute.c * - * Description: This module contains routines related to - * preparing and executing an SQL statement. + * Description: This module contains routines related to + * preparing and executing an SQL statement. * - * Classes: n/a + * Classes: n/a * - * API functions: SQLPrepare, SQLExecute, SQLExecDirect, SQLTransact, - * SQLCancel, SQLNativeSql, SQLParamData, SQLPutData + * API functions: SQLPrepare, SQLExecute, SQLExecDirect, SQLTransact, + * SQLCancel, SQLNativeSql, SQLParamData, SQLPutData * - * Comments: See "notice.txt" for copyright and license information. + * Comments: See "notice.txt" for copyright and license information. * */ @@ -38,74 +39,66 @@ extern GLOBAL_VALUES globals; -/* Perform a Prepare on the SQL statement */ -RETCODE SQL_API -SQLPrepare(HSTMT hstmt, - UCHAR FAR *szSqlStr, - SDWORD cbSqlStr) +/* Perform a Prepare on the SQL statement */ +RETCODE SQL_API SQLPrepare(HSTMT hstmt, + UCHAR FAR *szSqlStr, + SDWORD cbSqlStr) { - static char *func = "SQLPrepare"; - StatementClass *self = (StatementClass *) hstmt; +static char *func = "SQLPrepare"; +StatementClass *self = (StatementClass *) hstmt; - mylog("%s: entering...\n", func); + mylog( "%s: entering...\n", func); - 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 + */ - /* - * 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 - */ - - switch (self->status) - { - case STMT_PREMATURE: - mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n"); - SC_recycle_statement(self); /* recycle the statement, but do - * not remove parameter bindings */ - break; + switch(self->status) { + case STMT_PREMATURE: + mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n"); + SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */ + break; - case STMT_FINISHED: - mylog("**** SQLPrepare: STMT_FINISHED, recycle\n"); - SC_recycle_statement(self); /* recycle the statement, but do - * not remove parameter bindings */ - break; + case STMT_FINISHED: + mylog("**** SQLPrepare: STMT_FINISHED, recycle\n"); + SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */ + break; - case STMT_ALLOCATED: - mylog("**** SQLPrepare: STMT_ALLOCATED, copy\n"); - self->status = STMT_READY; - break; + case STMT_ALLOCATED: + mylog("**** SQLPrepare: STMT_ALLOCATED, copy\n"); + self->status = STMT_READY; + break; - case STMT_READY: - mylog("**** SQLPrepare: STMT_READY, change SQL\n"); - break; + case STMT_READY: + mylog("**** SQLPrepare: STMT_READY, change SQL\n"); + break; - case STMT_EXECUTING: - mylog("**** SQLPrepare: STMT_EXECUTING, error!\n"); + case STMT_EXECUTING: + mylog("**** SQLPrepare: STMT_EXECUTING, error!\n"); - 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); + 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; + 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; + default: + self->errornumber = STMT_INTERNAL_ERROR; + self->errormsg = "An Internal Error has occured -- Unknown statement status."; + SC_log_error(func, "", self); + return SQL_ERROR; } if (self->statement) free(self->statement); self->statement = make_string(szSqlStr, cbSqlStr, NULL); - if (!self->statement) - { + if ( ! self->statement) { self->errornumber = STMT_NO_MEMORY_ERROR; self->errormsg = "No memory available to store statement"; SC_log_error(func, "", self); @@ -115,9 +108,8 @@ SQLPrepare(HSTMT hstmt, self->prepare = TRUE; self->statement_type = statement_type(self->statement); - /* Check if connection is onlyread (only selects are allowed) */ - if (CC_is_onlyread(self->hdbc) && STMT_UPDATE(self)) - { + /* Check if connection is onlyread (only selects are allowed) */ + if ( CC_is_onlyread(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); @@ -129,24 +121,22 @@ SQLPrepare(HSTMT hstmt, } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */ +/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */ -RETCODE SQL_API -SQLExecDirect( - HSTMT hstmt, - UCHAR FAR *szSqlStr, - SDWORD cbSqlStr) +RETCODE SQL_API SQLExecDirect( + HSTMT hstmt, + UCHAR FAR *szSqlStr, + SDWORD cbSqlStr) { - StatementClass *stmt = (StatementClass *) hstmt; - RETCODE result; - static char *func = "SQLExecDirect"; +StatementClass *stmt = (StatementClass *) hstmt; +RETCODE result; +static char *func = "SQLExecDirect"; - mylog("%s: entering...\n", func); - - if (!stmt) - { + mylog( "%s: entering...\n", func); + + if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } @@ -157,8 +147,7 @@ SQLExecDirect( /* keep a copy of the un-parametrized statement, in case */ /* they try to execute this statement again */ stmt->statement = make_string(szSqlStr, cbSqlStr, NULL); - if (!stmt->statement) - { + if ( ! stmt->statement) { stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errormsg = "No memory available to store statement"; SC_log_error(func, "", stmt); @@ -172,20 +161,19 @@ SQLExecDirect( /* If an SQLPrepare was performed prior to this, but was left in */ /* the premature state because an error occurred prior to SQLExecute */ /* then set the statement to finished so it can be recycled. */ - if (stmt->status == STMT_PREMATURE) + if ( stmt->status == STMT_PREMATURE ) stmt->status = STMT_FINISHED; stmt->statement_type = statement_type(stmt->statement); - /* Check if connection is onlyread (only selects are allowed) */ - if (CC_is_onlyread(stmt->hdbc) && STMT_UPDATE(stmt)) - { + /* Check if connection is onlyread (only selects are allowed) */ + if ( CC_is_onlyread(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; } - + mylog("%s: calling SQLExecute...\n", func); result = SQLExecute(hstmt); @@ -194,55 +182,47 @@ SQLExecDirect( return result; } -/* Execute a prepared SQL statement */ -RETCODE SQL_API -SQLExecute( - HSTMT hstmt) +/* Execute a prepared SQL statement */ +RETCODE SQL_API SQLExecute( + HSTMT hstmt) { - static char *func = "SQLExecute"; - StatementClass *stmt = (StatementClass *) hstmt; - ConnectionClass *conn; - int i, - retval; +static char *func="SQLExecute"; +StatementClass *stmt = (StatementClass *) hstmt; +ConnectionClass *conn; +int i, retval; mylog("%s: entering...\n", func); - if (!stmt) - { + if ( ! stmt) { SC_log_error(func, "", NULL); mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func); return SQL_INVALID_HANDLE; } - /* - * If the statement is premature, it means we already executed it from - * an SQLPrepare/SQLDescribeCol type of scenario. So just return - * success. - */ - if (stmt->prepare && stmt->status == STMT_PREMATURE) - { - stmt->status = STMT_FINISHED; - if (stmt->errormsg == NULL) - { + /* If the statement is premature, it means we already executed + it from an SQLPrepare/SQLDescribeCol type of scenario. So + just return success. + */ + if ( stmt->prepare && stmt->status == STMT_PREMATURE) { + stmt->status = STMT_FINISHED; + if (stmt->errormsg == NULL) { mylog("%s: premature statement but return SQL_SUCCESS\n", func); return SQL_SUCCESS; } - else - { + else { SC_log_error(func, "", stmt); mylog("%s: premature statement so return SQL_ERROR\n", func); return SQL_ERROR; } - } + } mylog("%s: clear errors...\n", func); SC_clear_error(stmt); conn = SC_get_conn(stmt); - if (conn->status == CONN_EXECUTING) - { + if (conn->status == CONN_EXECUTING) { stmt->errormsg = "Connection is already in use."; stmt->errornumber = STMT_SEQUENCE_ERROR; SC_log_error(func, "", stmt); @@ -250,8 +230,7 @@ SQLExecute( return SQL_ERROR; } - if (!stmt->statement) - { + 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); @@ -259,21 +238,19 @@ SQLExecute( return SQL_ERROR; } - /* - * If SQLExecute is being called again, recycle the statement. Note - * this should have been done by the application in a call to - * SQLFreeStmt(SQL_CLOSE) or SQLCancel. - */ - if (stmt->status == STMT_FINISHED) - { + /* If SQLExecute is being called again, recycle the statement. + Note this should have been done by the application in a call + to SQLFreeStmt(SQL_CLOSE) or SQLCancel. + */ + if (stmt->status == STMT_FINISHED) { mylog("%s: recycling statement (should have been done by app)...\n", func); SC_recycle_statement(stmt); } - /* Check if the statement is in the correct state */ - if ((stmt->prepare && stmt->status != STMT_READY) || - (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) - { + /* Check if the statement is in the correct state */ + if ((stmt->prepare && stmt->status != STMT_READY) || + (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) { + 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); @@ -282,37 +259,30 @@ SQLExecute( } - /* - * The bound parameters could have possibly changed since the last - * execute of this statement? Therefore check for params and re-copy. - */ + /* The bound parameters could have possibly changed since the last execute + of this statement? Therefore check for params and re-copy. + */ stmt->data_at_exec = -1; - for (i = 0; i < stmt->parameters_allocated; i++) - { - /* Check for data at execution parameters */ - if (stmt->parameters[i].data_at_exec == TRUE) - { + for (i = 0; i < stmt->parameters_allocated; i++) { + /* Check for data at execution parameters */ + if ( stmt->parameters[i].data_at_exec == TRUE) { if (stmt->data_at_exec < 0) stmt->data_at_exec = 1; else stmt->data_at_exec++; } } - /* If there are some data at execution parameters, return need data */ - - /* - * SQLParamData and SQLPutData will be used to send params and execute - * the statement. - */ + /* If there are some data at execution parameters, return need data */ + /* SQLParamData and SQLPutData will be used to send params and execute the statement. */ if (stmt->data_at_exec > 0) return SQL_NEED_DATA; mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement); - /* Create the statement with parameters substituted. */ + /* Create the statement with parameters substituted. */ retval = copy_statement_with_parameters(stmt); - if (retval != SQL_SUCCESS) + if( retval != SQL_SUCCESS) /* error msg passed from above */ return retval; @@ -320,144 +290,131 @@ SQLExecute( return SC_execute(stmt); + } -/* - - - - - - - - - */ -RETCODE SQL_API -SQLTransact( - HENV henv, - HDBC hdbc, - UWORD fType) +/* - - - - - - - - - */ +RETCODE SQL_API SQLTransact( + HENV henv, + HDBC hdbc, + UWORD fType) { - static char *func = "SQLTransact"; - extern ConnectionClass *conns[]; - ConnectionClass *conn; - QResultClass *res; - char ok, - *stmt_string; - int lf; +static char *func = "SQLTransact"; +extern ConnectionClass *conns[]; +ConnectionClass *conn; +QResultClass *res; +char ok, *stmt_string; +int lf; mylog("entering %s: hdbc=%u, henv=%u\n", func, 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. - */ - if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) - { - for (lf = 0; lf < MAX_CONNECTIONS; lf++) - { + /* If hdbc is null and henv is valid, + it means transact all connections on that henv. + */ + if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) { + for (lf=0; lf <MAX_CONNECTIONS; lf++) { conn = conns[lf]; if (conn && conn->henv == henv) - if (SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS) + if ( SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS) return SQL_ERROR; + } - return SQL_SUCCESS; + return SQL_SUCCESS; } conn = (ConnectionClass *) hdbc; - if (fType == SQL_COMMIT) + if (fType == SQL_COMMIT) { stmt_string = "COMMIT"; - else if (fType == SQL_ROLLBACK) + + } else if (fType == SQL_ROLLBACK) { stmt_string = "ROLLBACK"; - else - { + + } else { conn->errornumber = CONN_INVALID_ARGUMENT_NO; - conn->errormsg = "SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"; + conn->errormsg ="SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"; CC_log_error(func, "", conn); return SQL_ERROR; - } + } + + /* If manual commit and in transaction, then proceed. */ + if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { - /* If manual commit and in transaction, then proceed. */ - if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) - { mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string); res = CC_send_query(conn, stmt_string, NULL); CC_set_no_trans(conn); - if (!res) - { - /* error msg will be in the connection */ + if ( ! res) { + /* error msg will be in the connection */ CC_log_error(func, "", conn); return SQL_ERROR; } - ok = QR_command_successful(res); + ok = QR_command_successful(res); QR_Destructor(res); - if (!ok) - { + if (!ok) { CC_log_error(func, "", conn); return SQL_ERROR; } - } + } return SQL_SUCCESS; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -RETCODE SQL_API -SQLCancel( - HSTMT hstmt) /* Statement to cancel. */ +RETCODE SQL_API SQLCancel( + HSTMT hstmt) /* Statement to cancel. */ { - static char *func = "SQLCancel"; - StatementClass *stmt = (StatementClass *) hstmt; - RETCODE result; - +static char *func="SQLCancel"; +StatementClass *stmt = (StatementClass *) hstmt; +RETCODE result; #ifdef WIN32 - HMODULE hmodule; - FARPROC addr; - +HMODULE hmodule; +FARPROC addr; #endif - mylog("%s: entering...\n", func); + mylog( "%s: entering...\n", func); - /* Check if this can handle canceling in the middle of a SQLPutData? */ - if (!stmt) - { + /* Check if this can handle canceling in the middle of a SQLPutData? */ + 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) - { - - /* - * MAJOR HACK for Windows to reset the driver manager's cursor - * state: Because of what seems like a bug in the Odbc driver - * manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as - * many applications depend on this behavior. So, this brute - * force method calls the driver manager's function on behalf of - * the application. - */ + /* Not in the middle of SQLParamData/SQLPutData so cancel like a close. */ + if (stmt->data_at_exec < 0) { + + + /* MAJOR HACK for Windows to reset the driver manager's cursor state: + Because of what seems like a bug in the Odbc driver manager, + SQLCancel does not act like a SQLFreeStmt(CLOSE), as many + applications depend on this behavior. So, this + brute force method calls the driver manager's function on + behalf of the application. + */ #ifdef WIN32 - if (globals.cancel_as_freestmt) - { + if (globals.cancel_as_freestmt) { hmodule = GetModuleHandle("ODBC32"); addr = GetProcAddress(hmodule, "SQLFreeStmt"); - result = addr((char *) (stmt->phstmt) - 96, SQL_CLOSE); + result = addr( (char *) (stmt->phstmt) - 96, SQL_CLOSE); + } + else { + result = SQLFreeStmt( hstmt, SQL_CLOSE); } - else - result = SQLFreeStmt(hstmt, SQL_CLOSE); #else - result = SQLFreeStmt(hstmt, SQL_CLOSE); + result = SQLFreeStmt( hstmt, SQL_CLOSE); #endif mylog("SQLCancel: SQLFreeStmt returned %d\n", result); @@ -466,46 +423,41 @@ SQLCancel( return SQL_SUCCESS; } - /* In the middle of SQLParamData/SQLPutData, so cancel that. */ - - /* - * Note, any previous data-at-exec buffers will be freed in the - * recycle - */ - /* if they call SQLExecDirect or SQLExecute again. */ + /* In the middle of SQLParamData/SQLPutData, so cancel that. */ + /* Note, any previous data-at-exec buffers will be freed in the recycle */ + /* if they call SQLExecDirect or SQLExecute again. */ stmt->data_at_exec = -1; stmt->current_exec_param = -1; stmt->put_data = FALSE; return SQL_SUCCESS; + } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -/* Returns the SQL string as modified by the driver. */ +/* Returns the SQL string as modified by the driver. */ /* Currently, just copy the input string without modification */ /* observing buffer limits and truncation. */ -RETCODE SQL_API -SQLNativeSql( - HDBC hdbc, - UCHAR FAR *szSqlStrIn, - SDWORD cbSqlStrIn, - UCHAR FAR *szSqlStr, - SDWORD cbSqlStrMax, - SDWORD FAR *pcbSqlStr) +RETCODE SQL_API SQLNativeSql( + HDBC hdbc, + UCHAR FAR *szSqlStrIn, + SDWORD cbSqlStrIn, + UCHAR FAR *szSqlStr, + SDWORD cbSqlStrMax, + SDWORD FAR *pcbSqlStr) { - static char *func = "SQLNativeSql"; - int len = 0; - char *ptr; - ConnectionClass *conn = (ConnectionClass *) hdbc; - RETCODE result; +static char *func="SQLNativeSql"; +int len = 0; +char *ptr; +ConnectionClass *conn = (ConnectionClass *) hdbc; +RETCODE result; - mylog("%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn); + mylog( "%s: entering...cbSqlStrIn=%d\n", func, cbSqlStrIn); ptr = (cbSqlStrIn == 0) ? "" : make_string(szSqlStrIn, cbSqlStrIn, NULL); - if (!ptr) - { + if ( ! ptr) { conn->errornumber = CONN_NO_MEMORY_ERROR; conn->errormsg = "No memory available to store native sql string"; CC_log_error(func, "", conn); @@ -515,12 +467,10 @@ SQLNativeSql( result = SQL_SUCCESS; len = strlen(ptr); - if (szSqlStr) - { + if (szSqlStr) { strncpy_null(szSqlStr, ptr, cbSqlStrMax); - if (len >= cbSqlStrMax) - { + if (len >= cbSqlStrMax) { result = SQL_SUCCESS_WITH_INFO; conn->errornumber = STMT_TRUNCATED; conn->errormsg = "The buffer was too small for the result."; @@ -532,44 +482,39 @@ SQLNativeSql( free(ptr); - return result; + return result; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -/* Supplies parameter data at execution time. Used in conjuction with */ -/* SQLPutData. */ +/* Supplies parameter data at execution time. Used in conjuction with */ +/* SQLPutData. */ -RETCODE SQL_API -SQLParamData( - HSTMT hstmt, - PTR FAR *prgbValue) +RETCODE SQL_API SQLParamData( + HSTMT hstmt, + PTR FAR *prgbValue) { - static char *func = "SQLParamData"; - StatementClass *stmt = (StatementClass *) hstmt; - int i, - retval; +static char *func = "SQLParamData"; +StatementClass *stmt = (StatementClass *) hstmt; +int i, retval; - mylog("%s: entering...\n", func); + mylog( "%s: entering...\n", func); - if (!stmt) - { + if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, stmt->parameters_allocated); - if (stmt->data_at_exec < 0) - { + 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) - { + 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); @@ -577,19 +522,16 @@ SQLParamData( } /* close the large object */ - if (stmt->lobj_fd >= 0) - { + if ( stmt->lobj_fd >= 0) { lo_close(stmt->hdbc, stmt->lobj_fd); /* commit transaction if needed */ - if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) - { + if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) { QResultClass *res; - char ok; + char ok; res = CC_send_query(stmt->hdbc, "COMMIT", NULL); - if (!res) - { + if (!res) { stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; SC_log_error(func, "", stmt); @@ -597,8 +539,7 @@ SQLParamData( } ok = QR_command_successful(res); QR_Destructor(res); - if (!ok) - { + if (!ok) { stmt->errormsg = "Could not commit (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; SC_log_error(func, "", stmt); @@ -612,9 +553,8 @@ SQLParamData( } - /* Done, now copy the params and then execute the statement */ - if (stmt->data_at_exec == 0) - { + /* Done, now copy the params and then execute the statement */ + if (stmt->data_at_exec == 0) { retval = copy_statement_with_parameters(stmt); if (retval != SQL_SUCCESS) return retval; @@ -624,17 +564,14 @@ SQLParamData( return SC_execute(stmt); } - /* - * Set beginning param; if first time SQLParamData is called , start - * at 0. Otherwise, start at the last parameter + 1. - */ - i = stmt->current_exec_param >= 0 ? stmt->current_exec_param + 1 : 0; - - /* At least 1 data at execution parameter, so Fill in the token value */ - for (; i < stmt->parameters_allocated; i++) - { - if (stmt->parameters[i].data_at_exec == TRUE) - { + /* Set beginning param; if first time SQLParamData is called , start at 0. + Otherwise, start at the last parameter + 1. + */ + i = stmt->current_exec_param >= 0 ? stmt->current_exec_param+1 : 0; + + /* At least 1 data at execution parameter, so Fill in the token value */ + for ( ; i < stmt->parameters_allocated; i++) { + if (stmt->parameters[i].data_at_exec == TRUE) { stmt->data_at_exec--; stmt->current_exec_param = i; stmt->put_data = FALSE; @@ -646,35 +583,31 @@ SQLParamData( return SQL_NEED_DATA; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -/* Supplies parameter data at execution time. Used in conjunction with */ -/* SQLParamData. */ +/* Supplies parameter data at execution time. Used in conjunction with */ +/* SQLParamData. */ -RETCODE SQL_API -SQLPutData( - HSTMT hstmt, - PTR rgbValue, - SDWORD cbValue) +RETCODE SQL_API SQLPutData( + HSTMT hstmt, + PTR rgbValue, + SDWORD cbValue) { - static char *func = "SQLPutData"; - StatementClass *stmt = (StatementClass *) hstmt; - int old_pos, - retval; - ParameterInfoClass *current_param; - char *buffer; +static char *func = "SQLPutData"; +StatementClass *stmt = (StatementClass *) hstmt; +int old_pos, retval; +ParameterInfoClass *current_param; +char *buffer; - mylog("%s: entering...\n", func); + mylog( "%s: entering...\n", func); - if (!stmt) - { + if ( ! stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } - - if (stmt->current_exec_param < 0) - { + + 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); @@ -683,16 +616,14 @@ SQLPutData( current_param = &(stmt->parameters[stmt->current_exec_param]); - if (!stmt->put_data) - { /* first call */ + if ( ! stmt->put_data) { /* first call */ mylog("SQLPutData: (1) cbValue = %d\n", cbValue); stmt->put_data = TRUE; current_param->EXEC_used = (SDWORD *) malloc(sizeof(SDWORD)); - if (!current_param->EXEC_used) - { + if ( ! current_param->EXEC_used) { stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errormsg = "Out of memory in SQLPutData (1)"; SC_log_error(func, "", stmt); @@ -705,18 +636,16 @@ SQLPutData( return SQL_SUCCESS; - /* Handle Long Var Binary with Large Objects */ - if (current_param->SQLType == SQL_LONGVARBINARY) - { + /* Handle Long Var Binary with Large Objects */ + if ( current_param->SQLType == SQL_LONGVARBINARY) { + /* begin transaction if needed */ - if (!CC_is_in_trans(stmt->hdbc)) - { + if(!CC_is_in_trans(stmt->hdbc)) { QResultClass *res; - char ok; + char ok; res = CC_send_query(stmt->hdbc, "BEGIN", NULL); - if (!res) - { + if (!res) { stmt->errormsg = "Could not begin (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; SC_log_error(func, "", stmt); @@ -724,8 +653,7 @@ SQLPutData( } ok = QR_command_successful(res); QR_Destructor(res); - if (!ok) - { + if (!ok) { stmt->errormsg = "Could not begin (in-line) a transaction"; stmt->errornumber = STMT_EXEC_ERROR; SC_log_error(func, "", stmt); @@ -735,24 +663,22 @@ SQLPutData( CC_set_in_trans(stmt->hdbc); } - /* store the oid */ + /* store the oid */ current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE); - if (current_param->lobj_oid == 0) - { + 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; } - /* major hack -- to allow convert to see somethings there */ - /* have to modify convert to handle this better */ + /* major hack -- to allow convert to see somethings there */ + /* have to modify convert to handle this better */ current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid; - /* store the fd */ + /* store the fd */ stmt->lobj_fd = lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE); - if (stmt->lobj_fd < 0) - { + if ( stmt->lobj_fd < 0) { stmt->errornumber = STMT_EXEC_ERROR; stmt->errormsg = "Couldnt open large object for writing."; SC_log_error(func, "", stmt); @@ -761,27 +687,22 @@ SQLPutData( retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue); mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval); + } - else - { /* for handling text fields and small - * binaries */ + else { /* for handling text fields and small binaries */ - if (cbValue == SQL_NTS) - { + if (cbValue == SQL_NTS) { current_param->EXEC_buffer = strdup(rgbValue); - if (!current_param->EXEC_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; } } - else - { + else { current_param->EXEC_buffer = malloc(cbValue + 1); - if (!current_param->EXEC_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); @@ -793,28 +714,25 @@ SQLPutData( } } - else - { /* calling SQLPutData more than once */ + else { /* calling SQLPutData more than once */ mylog("SQLPutData: (>1) cbValue = %d\n", cbValue); - if (current_param->SQLType == SQL_LONGVARBINARY) - { + if (current_param->SQLType == SQL_LONGVARBINARY) { + /* the large object fd is in EXEC_buffer */ retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue); mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval); *current_param->EXEC_used += cbValue; - } - else - { + + } else { + buffer = current_param->EXEC_buffer; - if (cbValue == SQL_NTS) - { + if (cbValue == SQL_NTS) { buffer = realloc(buffer, strlen(buffer) + strlen(rgbValue) + 1); - if (!buffer) - { + if ( ! buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errormsg = "Out of memory in SQLPutData (3)"; SC_log_error(func, "", stmt); @@ -826,11 +744,12 @@ SQLPutData( *current_param->EXEC_used = cbValue; - /* reassign buffer incase realloc moved it */ + /* reassign buffer incase realloc moved it */ current_param->EXEC_buffer = buffer; + } - else if (cbValue > 0) - { + else if (cbValue > 0) { + old_pos = *current_param->EXEC_used; *current_param->EXEC_used += cbValue; @@ -839,8 +758,7 @@ SQLPutData( /* dont lose the old pointer in case out of memory */ buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1); - if (!buffer) - { + if ( ! buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errormsg = "Out of memory in SQLPutData (3)"; SC_log_error(func, "", stmt); @@ -850,14 +768,15 @@ SQLPutData( memcpy(&buffer[old_pos], rgbValue, cbValue); buffer[*current_param->EXEC_used] = '\0'; - /* reassign buffer incase realloc moved it */ + /* reassign buffer incase realloc moved it */ current_param->EXEC_buffer = buffer; + } - else - { + else { SC_log_error(func, "bad cbValue", stmt); return SQL_ERROR; } + } } |