prepare.c
上传用户:jmzj888
上传日期:2007-01-02
资源大小:220k
文件大小:8k
- /* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
- This file is public domain and comes with NO WARRANTY of any kind */
- /*
- ** PREPARE.C - This is the ODBC sample driver code for
- ** preparing SQL Commands and other functions prior to execution.
- */
- #include "myodbc.h"
- #ifndef _UNIX_
- #include <dos.h>
- #endif /* IS NOT UNIX */
- #include <list.h>
- // Allocate a SQL statement
- RETCODE SQL_API SQLAllocStmt(HDBC hdbc,HSTMT FAR *phstmt)
- {
- #ifndef _UNIX_
- HGLOBAL hstmt;
- #endif /* IS NOT UNIX */
- STMT FAR* stmt;
- DBC FAR *dbc=(DBC FAR*) hdbc;
- DBUG_ENTER("SQLAllocStmt");
- #ifndef _UNIX_
- hstmt = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (STMT));
- if (!hstmt || (*phstmt = (HSTMT)GlobalLock (hstmt)) == SQL_NULL_HSTMT)
- {
- GlobalFree (hstmt); // Free it if lock fails
- *phstmt = SQL_NULL_HSTMT;
- DBUG_RETURN(SQL_ERROR);
- }
- #endif /* IS NOT UNIX */
- #ifdef _UNIX_
- *phstmt = (HSTMT)my_malloc(sizeof (STMT), MYF(16));
- if (*phstmt == SQL_NULL_HSTMT)
- {
- *phstmt = SQL_NULL_HSTMT;
- DBUG_RETURN(SQL_ERROR);
- }
- memset( *phstmt, 0, sizeof(STMT) );
- #endif /* IS UNIX */
- stmt= *phstmt;
- stmt->dbc=hdbc;
- dbc->statements=list_add(dbc->statements,&stmt->list);
- stmt->list.data=stmt;
- stmt->stmt_options=dbc->stmt_options;
- init_dynamic_array(&stmt->params,sizeof(PARAM_BIND),32,64);
- DBUG_RETURN(SQL_SUCCESS);
- }
- RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,UWORD fOption)
- {
- STMT FAR *stmt=(STMT FAR*) hstmt;
- uint i;
- DBUG_ENTER("SQLFreeStmt");
- DBUG_PRINT("enter",("stmt: %lx option: %d",hstmt,fOption));
- if (fOption == SQL_UNBIND)
- {
- x_free(stmt->bind);
- stmt->bind=0;
- stmt->bound_columns=0;
- DBUG_RETURN(SQL_SUCCESS);
- }
- for (i=0 ; i < stmt->params.elements ; i++)
- {
- PARAM_BIND *param=dynamic_element(&stmt->params,i,PARAM_BIND*);
- if (param->alloced)
- {
- my_free(param->value,MYF(0));
- param->alloced=0;
- }
- if (fOption == SQL_RESET_PARAMS)
- param->used=0;
- }
- if (fOption == SQL_RESET_PARAMS)
- {
- delete_dynamic(&stmt->params);
- DBUG_RETURN(SQL_SUCCESS);
- }
- mysql_free_result(stmt->result);
- x_free((gptr) stmt->fields); /* Don't write zero free's to debug log */
- x_free((gptr) stmt->array);
- x_free((gptr) stmt->result_array);
- x_free((gptr) stmt->odbc_types);
- stmt->result=0;
- stmt->result_lengths=0;
- stmt->fields=0;
- stmt->array=0;
- stmt->result_array=0;
- stmt->odbc_types=0;
- stmt->current_values=0; /* For SQLGetData */
- stmt->fix_fields=0;
- stmt->current_row=stmt->rows_found_in_set=stmt->position_in_set=0;
- stmt->state=ST_UNKNOWN;
- /* Free data used by parameters */
- if (fOption != MYSQL_RESET_BUFFERS && fOption != SQL_CLOSE)
- {
- x_free((gptr) stmt->query);
- x_free((gptr) stmt->bind);
- stmt->bind=0;
- stmt->bound_columns=0;
- stmt->query=0;
- stmt->param_count=0;
- }
- if (fOption == SQL_DROP)
- {
- delete_dynamic(&stmt->params);
- stmt->dbc->statements=list_delete(stmt->dbc->statements,&stmt->list);
- #ifndef _UNIX_
- GlobalUnlock (GlobalHandle ((HGLOBAL) hstmt));
- GlobalFree (GlobalHandle((HGLOBAL) hstmt));
- #endif /* IS NOT UNIX */
- #ifdef _UNIX_
- free( hstmt);
- #endif /* IS UNIX */
- }
- DBUG_RETURN(SQL_SUCCESS);
- }
- // Perform a Prepare on the SQL statement
- RETCODE SQL_API SQLPrepare(HSTMT hstmt,UCHAR FAR *szSqlStr, SDWORD cbSqlStr)
- {
- return my_SQLPrepare(hstmt,szSqlStr,cbSqlStr);
- }
- RETCODE my_SQLPrepare(HSTMT hstmt,UCHAR FAR *szSqlStr, SDWORD cbSqlStr)
- {
- STMT FAR *stmt=(STMT FAR*) hstmt;
- char in_string,*pos;
- uint param_count;
- DBUG_ENTER("my_SQLPrepare");
- if (stmt->query)
- my_free(stmt->query,MYF(0));
- /* SQLFreeStmt(hstmt,SQL_UNBIND); */ /* Not needed according to VB 5.0 */
- if (!(stmt->query=dupp_str((char*) szSqlStr, cbSqlStr)))
- {
- DBUG_RETURN(set_error(stmt->dbc,"S1001","Not enough memory",4001));
- }
- DBUG_PRINT("enter",("Query: %s",stmt->query));
- /* Count number of parameters and save position for each parameter */
- /* change also newline and return to space (for easy logging) */
- in_string=0;
- param_count=0;
- for (pos=stmt->query; *pos ; pos++)
- {
- if (*pos == '\' && pos[1]) /* Next char is escaped */
- {
- pos++;
- continue;
- }
- if (*pos == in_string)
- {
- in_string=0;
- continue;
- }
- if (*pos == ''' || *pos == '"') /* Start of string */
- {
- in_string= *pos;
- continue;
- }
- if (!in_string && *pos == '?')
- {
- PARAM_BIND *param;
- if (param_count >= stmt->params.elements)
- {
- PARAM_BIND tmp_param;
- bzero((gptr) &tmp_param,sizeof(tmp_param));
- if (push_dynamic(&stmt->params,(gptr) &tmp_param))
- {
- DBUG_RETURN(set_error(stmt->dbc,"S1001","Not enough memory",4001));
- }
- }
- param=dynamic_element(&stmt->params,param_count,PARAM_BIND*);
- param->pos_in_query=pos;
- param_count++;
- }
- }
- stmt->param_count=param_count;
- stmt->query_end=pos;
- stmt->state=ST_PREPARED;
- DBUG_PRINT("exit",("Parameter count: %ld",stmt->param_count));
- DBUG_RETURN(SQL_SUCCESS);
- }
- // 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)
- {
- STMT FAR *stmt=(STMT FAR*) hstmt;
- PARAM_BIND param;
- DBUG_ENTER("SQLBindParameter");
- DBUG_PRINT("enter",
- ("ipar: %d Ctype: %d SQLtype: %d ValueMax: %ld Value: %ld",
- ipar,fCType,fSqlType,cbValueMax,pcbValue ? *pcbValue : 0L));
- if (ipar-- < 1)
- {
- DBUG_RETURN(set_error(stmt->dbc,"S1093","Invalid parameter number",0));
- }
- if (stmt->params.elements > ipar)
- { /* Change old bind parameter */
- PARAM_BIND *old=dynamic_element(&stmt->params,ipar,PARAM_BIND*);
- if (old->alloced)
- {
- my_free(old->value,MYF(0));
- old->alloced=0;
- }
- memcpy((gptr) ¶m,(gptr) old,sizeof(param));
- }
- else
- bzero(¶m, sizeof(param));
- /* Simply record the values. These are used later (SQLExecute) */
- param.used= 1;
- param.SqlType = fSqlType;
- param.CType = (fCType == SQL_C_DEFAULT ? default_c_type(fSqlType) : fCType);
- param.buffer = rgbValue;
- param.ValueMax = cbValueMax;
- param.actual_len= pcbValue;
- if (set_dynamic(&stmt->params,(gptr) ¶m,ipar))
- {
- DBUG_RETURN(set_error(stmt->dbc,"S1001","Not enough memory",4001));
- }
- DBUG_RETURN(SQL_SUCCESS);
- }
- /*
- ** Returns the description of a parameter marker.
- ** As we can't detect this easily, but MySQL can use strings anywhere
- ** we simple say that all parameters can be strings.
- */
- RETCODE SQL_API SQLDescribeParam(HSTMT hstmt, UWORD ipar, SWORD FAR *pfSqlType,
- UDWORD FAR *pcbColDef, SWORD FAR *pibScale,
- SWORD FAR *pfNullable)
- {
- DBUG_ENTER("SQLDescribeParam");
- if (pfSqlType)
- *pfSqlType=SQL_VARCHAR;
- if (pcbColDef)
- *pcbColDef=255;
- if (pfNullable)
- *pfNullable=SQL_NULLABLE_UNKNOWN;
- DBUG_RETURN(SQL_SUCCESS);
- }
- // Sets multiple values (arrays) for the set of parameter markers.
- RETCODE SQL_API SQLParamOptions(HSTMT hstmt, UDWORD crow, UDWORD FAR *pirow)
- {
- DBUG_ENTER("SQLParamOptions");
- DBUG_PRINT("info",("Command ignored"));
- DBUG_RETURN(SQL_SUCCESS);
- }
- // Returns the number of parameter markers.
- RETCODE SQL_API SQLNumParams(HSTMT hstmt, SWORD FAR *pcpar)
- {
- STMT FAR *stmt=(STMT FAR*) hstmt;
- DBUG_ENTER("SQLNumParams");
- if (pcpar)
- *pcpar=stmt->param_count;
- DBUG_RETURN(SQL_SUCCESS);
- }
- // Sets options that control the behavior of cursors.
- RETCODE SQL_API SQLSetScrollOptions(HSTMT hstmt, UWORD fConcurrency,
- SDWORD crowKeyset, UWORD crowRowset)
- {
- STMT FAR *stmt=(STMT FAR*) hstmt;
- DBUG_ENTER("SQLSetScrollOptions");
- stmt->stmt_options.rows_in_set=crowRowset;
- DBUG_RETURN(SQL_SUCCESS);
- }
- // Set the cursor name on a statement handle
- RETCODE SQL_API SQLSetCursorName(HSTMT hstmt, UCHAR FAR *szCursor,
- SWORD cbCursor)
- {
- DBUG_ENTER("SQLSetCursorName");
- DBUG_PRINT("info",("Command ignored as MyODBC doesn't support cursors"));
- DBUG_RETURN(SQL_SUCCESS);
- }
- // Return the cursor name for a statement handle
- RETCODE SQL_API SQLGetCursorName(HSTMT hstmt, UCHAR FAR *szCursor,
- SWORD cbCursorMax, SWORD FAR *pcbCursor)
- {
- DBUG_ENTER("SQLGetCursorName");
- copy_result(((STMT FAR*) hstmt)->dbc,szCursor,cbCursorMax,pcbCursor,"NO_NAME");
- DBUG_RETURN(SQL_SUCCESS);
- }