diff options
Diffstat (limited to 'src/interfaces/odbc/bind.c')
-rw-r--r-- | src/interfaces/odbc/bind.c | 345 |
1 files changed, 153 insertions, 192 deletions
diff --git a/src/interfaces/odbc/bind.c b/src/interfaces/odbc/bind.c index 16a375301fb..6ec25f80d63 100644 --- a/src/interfaces/odbc/bind.c +++ b/src/interfaces/odbc/bind.c @@ -1,14 +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. * */ @@ -33,44 +34,39 @@ #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); @@ -80,23 +76,18 @@ 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; @@ -112,8 +103,7 @@ 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; @@ -125,83 +115,74 @@ 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) -{ - StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "SQLBindCol"; +/* - - - - - - - - - */ - mylog("%s: entering...\n", func); +/* 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"; - mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); + mylog( "%s: entering...\n", func); + +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 (rgbValue == NULL) - { + /* If the bookmark column is being bound, then just save it */ + if (icol == 0) { + + 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); @@ -214,42 +195,37 @@ SQLBindCol( 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); @@ -258,37 +234,34 @@ SQLBindCol( 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); @@ -297,45 +270,41 @@ 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 */ @@ -344,49 +313,43 @@ 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 - { - for (i = 0; i < strlen(stmt->statement); i++) - { - if (stmt->statement[i] == '?' && !in_quote) + } else { + + for(i=0; i < strlen(stmt->statement); i++) { + + if(stmt->statement[i] == '?' && !in_quote) (*pcpar)++; - else - { + else { if (stmt->statement[i] == '\'') in_quote = (in_quote ? FALSE : TRUE); } @@ -397,20 +360,20 @@ 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; @@ -423,23 +386,21 @@ create_empty_bindings(int num_columns) 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; } @@ -447,9 +408,8 @@ extend_bindings(StatementClass *stmt, int num_columns) 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); @@ -457,14 +417,15 @@ extend_bindings(StatementClass *stmt, int num_columns) 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. */ - /* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */ - /* SQLExecDirect(...) # returns 5 cols */ - /* SQLExecDirect(...) # returns 10 cols (now OK) */ + } + /* 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"); } |