diff options
Diffstat (limited to 'src/interfaces/odbc/bind.c')
-rw-r--r-- | src/interfaces/odbc/bind.c | 339 |
1 files changed, 192 insertions, 147 deletions
diff --git a/src/interfaces/odbc/bind.c b/src/interfaces/odbc/bind.c index 6ec25f80d63..a83bd5596b8 100644 --- a/src/interfaces/odbc/bind.c +++ b/src/interfaces/odbc/bind.c @@ -1,15 +1,15 @@ -/* Module: bind.c +/* Module: bind.c * - * Description: This module contains routines related to binding - * columns and parameters. + * Description: This module contains routines related to binding + * columns and parameters. * - * Classes: BindInfoClass, ParameterInfoClass + * Classes: BindInfoClass, ParameterInfoClass * - * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams, - * SQLParamOptions(NI) + * API functions: SQLBindParameter, SQLBindCol, SQLDescribeParam, SQLNumParams, + * SQLParamOptions(NI) * - * Comments: See "notice.txt" for copyright and license information. + * Comments: See "notice.txt" for copyright and license information. * */ @@ -34,39 +34,44 @@ #include "sqlext.h" #endif -/* Bind parameters on a statement handle */ - -RETCODE SQL_API SQLBindParameter( - HSTMT hstmt, - UWORD ipar, - SWORD fParamType, - SWORD fCType, - SWORD fSqlType, - UDWORD cbColDef, - SWORD ibScale, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR *pcbValue) +/* Bind parameters on a statement handle */ + +RETCODE SQL_API +SQLBindParameter( + HSTMT hstmt, + UWORD ipar, + SWORD fParamType, + SWORD fCType, + SWORD fSqlType, + UDWORD cbColDef, + SWORD ibScale, + PTR rgbValue, + SDWORD cbValueMax, + SDWORD FAR *pcbValue) { -StatementClass *stmt = (StatementClass *) hstmt; -static char *func="SQLBindParameter"; + StatementClass *stmt = (StatementClass *) hstmt; + static char *func = "SQLBindParameter"; - 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->parameters_allocated < ipar) { + if (stmt->parameters_allocated < ipar) + { ParameterInfoClass *old_parameters; - int i, old_parameters_allocated; + int i, + old_parameters_allocated; old_parameters = stmt->parameters; old_parameters_allocated = stmt->parameters_allocated; - stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass)*(ipar)); - if ( ! stmt->parameters) { + stmt->parameters = (ParameterInfoClass *) malloc(sizeof(ParameterInfoClass) * (ipar)); + if (!stmt->parameters) + { stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errormsg = "Could not allocate memory for statement parameters"; SC_log_error(func, "", stmt); @@ -76,18 +81,23 @@ static char *func="SQLBindParameter"; stmt->parameters_allocated = ipar; /* copy the old parameters over */ - for(i = 0; i < old_parameters_allocated; i++) { + for (i = 0; i < old_parameters_allocated; i++) + { /* a structure copy should work */ stmt->parameters[i] = old_parameters[i]; } /* get rid of the old parameters, if there were any */ - if(old_parameters) + if (old_parameters) free(old_parameters); - /* zero out the newly allocated parameters (in case they skipped some, */ + /* + * zero out the newly allocated parameters (in case they skipped + * some, + */ /* so we don't accidentally try to use them later) */ - for(; i < stmt->parameters_allocated; i++) { + for (; i < stmt->parameters_allocated; i++) + { stmt->parameters[i].buflen = 0; stmt->parameters[i].buffer = 0; stmt->parameters[i].used = 0; @@ -103,7 +113,8 @@ static char *func="SQLBindParameter"; } } - ipar--; /* use zero based column numbers for the below part */ + ipar--; /* use zero based column numbers for the + * below part */ /* store the given info */ stmt->parameters[ipar].buflen = cbValueMax; @@ -115,74 +126,84 @@ static char *func="SQLBindParameter"; stmt->parameters[ipar].precision = cbColDef; stmt->parameters[ipar].scale = ibScale; - /* If rebinding a parameter that had data-at-exec stuff in it, - then free that stuff - */ - if (stmt->parameters[ipar].EXEC_used) { + /* + * If rebinding a parameter that had data-at-exec stuff in it, then + * free that stuff + */ + if (stmt->parameters[ipar].EXEC_used) + { free(stmt->parameters[ipar].EXEC_used); stmt->parameters[ipar].EXEC_used = NULL; } - if (stmt->parameters[ipar].EXEC_buffer) { + if (stmt->parameters[ipar].EXEC_buffer) + { if (stmt->parameters[ipar].SQLType != SQL_LONGVARBINARY) free(stmt->parameters[ipar].EXEC_buffer); stmt->parameters[ipar].EXEC_buffer = NULL; } - /* Data at exec macro only valid for C char/binary data */ + /* Data at exec macro only valid for C char/binary data */ if ((fSqlType == SQL_LONGVARBINARY || fSqlType == SQL_LONGVARCHAR) && pcbValue && *pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET) stmt->parameters[ipar].data_at_exec = TRUE; else stmt->parameters[ipar].data_at_exec = FALSE; - mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue: -777, stmt->parameters[ipar].data_at_exec); + mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, stmt->parameters[ipar].data_at_exec); return SQL_SUCCESS; } -/* - - - - - - - - - */ - -/* Associate a user-supplied buffer with a database column. */ -RETCODE SQL_API SQLBindCol( - HSTMT hstmt, - UWORD icol, - SWORD fCType, - PTR rgbValue, - SDWORD cbValueMax, - SDWORD FAR *pcbValue) +/* - - - - - - - - - */ + +/* Associate a user-supplied buffer with a database column. */ +RETCODE SQL_API +SQLBindCol( + HSTMT hstmt, + UWORD icol, + SWORD fCType, + PTR rgbValue, + SDWORD cbValueMax, + SDWORD FAR *pcbValue) { -StatementClass *stmt = (StatementClass *) hstmt; -static char *func="SQLBindCol"; + StatementClass *stmt = (StatementClass *) hstmt; + static char *func = "SQLBindCol"; + + mylog("%s: entering...\n", func); - mylog( "%s: entering...\n", func); - -mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); + mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); - if ( ! stmt) { + if (!stmt) + { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } SC_clear_error(stmt); - - if( stmt->status == STMT_EXECUTING) { + + 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; } - /* If the bookmark column is being bound, then just save it */ - if (icol == 0) { + /* If the bookmark column is being bound, then just save it */ + if (icol == 0) + { - if (rgbValue == NULL) { + if (rgbValue == NULL) + { stmt->bookmark.buffer = NULL; stmt->bookmark.used = NULL; } - else { - /* Make sure it is the bookmark data type */ - if ( fCType != SQL_C_BOOKMARK) { + else + { + /* Make sure it is the bookmark data type */ + if (fCType != SQL_C_BOOKMARK) + { stmt->errormsg = "Column 0 is not of type SQL_C_BOOKMARK"; stmt->errornumber = STMT_PROGRAM_TYPE_OUT_OF_RANGE; SC_log_error(func, "", stmt); @@ -195,37 +216,42 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); return SQL_SUCCESS; } - /* 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) + /* 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) { + /* check to see if the bindings were allocated */ + if (!stmt->bindings) + { stmt->errormsg = "Could not allocate memory for bindings."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; } - icol--; /* use zero based col numbers from here out */ + icol--; /* use zero based col numbers from here + * out */ - /* Reset for SQLGetData */ + /* Reset for SQLGetData */ stmt->bindings[icol].data_left = -1; - if (rgbValue == NULL) { + if (rgbValue == NULL) + { /* we have to unbind the column */ stmt->bindings[icol].buflen = 0; stmt->bindings[icol].buffer = NULL; - stmt->bindings[icol].used = NULL; + stmt->bindings[icol].used = NULL; stmt->bindings[icol].returntype = SQL_C_CHAR; - } else { + } + else + { /* ok, bind that column */ - stmt->bindings[icol].buflen = cbValueMax; - stmt->bindings[icol].buffer = rgbValue; - stmt->bindings[icol].used = pcbValue; + stmt->bindings[icol].buflen = cbValueMax; + stmt->bindings[icol].buffer = rgbValue; + stmt->bindings[icol].used = pcbValue; stmt->bindings[icol].returntype = fCType; mylog(" bound buffer[%d] = %u\n", icol, stmt->bindings[icol].buffer); @@ -234,34 +260,37 @@ mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); return SQL_SUCCESS; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -/* Returns the description of a parameter marker. */ +/* Returns the description of a parameter marker. */ /* This function is listed as not being supported by SQLGetFunctions() because it is */ /* used to describe "parameter markers" (not bound parameters), in which case, */ /* the dbms should return info on the markers. Since Postgres doesn't support that, */ /* it is best to say this function is not supported and let the application assume a */ /* data type (most likely varchar). */ -RETCODE SQL_API SQLDescribeParam( - HSTMT hstmt, - UWORD ipar, - SWORD FAR *pfSqlType, - UDWORD FAR *pcbColDef, - SWORD FAR *pibScale, - SWORD FAR *pfNullable) +RETCODE SQL_API +SQLDescribeParam( + HSTMT hstmt, + UWORD ipar, + SWORD FAR *pfSqlType, + UDWORD FAR *pcbColDef, + SWORD FAR *pibScale, + SWORD FAR *pfNullable) { -StatementClass *stmt = (StatementClass *) hstmt; -static char *func = "SQLDescribeParam"; + StatementClass *stmt = (StatementClass *) hstmt; + static char *func = "SQLDescribeParam"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); - if( ! stmt) { + if (!stmt) + { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } - if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) { + 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); @@ -270,41 +299,45 @@ static char *func = "SQLDescribeParam"; ipar--; - /* This implementation is not very good, since it is supposed to describe */ - /* parameter markers, not bound parameters. */ - if(pfSqlType) + /* + * This implementation is not very good, since it is supposed to + * describe + */ + /* parameter markers, not bound parameters. */ + if (pfSqlType) *pfSqlType = stmt->parameters[ipar].SQLType; - if(pcbColDef) + if (pcbColDef) *pcbColDef = stmt->parameters[ipar].precision; - if(pibScale) + if (pibScale) *pibScale = stmt->parameters[ipar].scale; - if(pfNullable) + if (pfNullable) *pfNullable = pgtype_nullable(stmt, stmt->parameters[ipar].paramType); return SQL_SUCCESS; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ -/* Sets multiple values (arrays) for the set of parameter markers. */ +/* Sets multiple values (arrays) for the set of parameter markers. */ -RETCODE SQL_API SQLParamOptions( - HSTMT hstmt, - UDWORD crow, - UDWORD FAR *pirow) +RETCODE SQL_API +SQLParamOptions( + HSTMT hstmt, + UDWORD crow, + UDWORD FAR *pirow) { -static char *func = "SQLParamOptions"; + static char *func = "SQLParamOptions"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } -/* - - - - - - - - - */ +/* - - - - - - - - - */ /* This function should really talk to the dbms to determine the number of */ /* "parameter markers" (not bound parameters) in the statement. But, since */ @@ -313,43 +346,51 @@ static char *func = "SQLParamOptions"; /* like it does for SQLDescribeParam is that some applications don't care and try */ /* to call it anyway. */ /* If the statement does not have parameters, it should just return 0. */ -RETCODE SQL_API SQLNumParams( - HSTMT hstmt, - SWORD FAR *pcpar) +RETCODE SQL_API +SQLNumParams( + HSTMT hstmt, + SWORD FAR *pcpar) { -StatementClass *stmt = (StatementClass *) hstmt; -char in_quote = FALSE; -unsigned int i; -static char *func = "SQLNumParams"; + StatementClass *stmt = (StatementClass *) hstmt; + char in_quote = FALSE; + unsigned int i; + static char *func = "SQLNumParams"; - mylog( "%s: entering...\n", func); + mylog("%s: entering...\n", func); - 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) { + 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 { + } + else + { - for(i=0; i < strlen(stmt->statement); i++) { + for (i = 0; i < strlen(stmt->statement); i++) + { - if(stmt->statement[i] == '?' && !in_quote) + if (stmt->statement[i] == '?' && !in_quote) (*pcpar)++; - else { + else + { if (stmt->statement[i] == '\'') in_quote = (in_quote ? FALSE : TRUE); } @@ -360,20 +401,20 @@ static char *func = "SQLNumParams"; } /******************************************************************** - * Bindings Implementation + * Bindings Implementation */ BindInfoClass * create_empty_bindings(int num_columns) { -BindInfoClass *new_bindings; -int i; + BindInfoClass *new_bindings; + int i; - new_bindings = (BindInfoClass *)malloc(num_columns * sizeof(BindInfoClass)); - if(!new_bindings) { + new_bindings = (BindInfoClass *) malloc(num_columns * sizeof(BindInfoClass)); + if (!new_bindings) return 0; - } - for(i=0; i < num_columns; i++) { + for (i = 0; i < num_columns; i++) + { new_bindings[i].buflen = 0; new_bindings[i].buffer = NULL; new_bindings[i].used = NULL; @@ -386,21 +427,24 @@ int i; void extend_bindings(StatementClass *stmt, int num_columns) { -static char *func="extend_bindings"; -BindInfoClass *new_bindings; -int i; + static char *func = "extend_bindings"; + BindInfoClass *new_bindings; + int i; -mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns); + mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated, num_columns); /* if we have too few, allocate room for more, and copy the old */ /* entries into the new structure */ - if(stmt->bindings_allocated < num_columns) { + if (stmt->bindings_allocated < num_columns) + { new_bindings = create_empty_bindings(num_columns); - if ( ! new_bindings) { - mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated); + if (!new_bindings) + { + mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_columns, stmt->bindings_allocated); - if (stmt->bindings) { + if (stmt->bindings) + { free(stmt->bindings); stmt->bindings = NULL; } @@ -408,8 +452,9 @@ mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, return; } - if(stmt->bindings) { - for(i=0; i<stmt->bindings_allocated; i++) + if (stmt->bindings) + { + for (i = 0; i < stmt->bindings_allocated; i++) new_bindings[i] = stmt->bindings[i]; free(stmt->bindings); @@ -418,14 +463,14 @@ mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt->bindings = new_bindings; stmt->bindings_allocated = num_columns; - } - /* 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. */ + } + /* 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) */ + /* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */ + /* SQLExecDirect(...) # returns 5 cols */ + /* SQLExecDirect(...) # returns 10 cols (now OK) */ mylog("exit extend_bindings\n"); } |