Gateway fixes
[csql.git] / src / odbc / odbcStmt.cxx
blob98eae1d652f3adfba51e4a6a2179347180afff85
2 // Class CSqlOdbcStmt
3 // Description: Statement Handle manager.
5 #include "odbcCommon.h"
7 // Constructor
8 CSqlOdbcStmt::CSqlOdbcStmt( void ) :
9 handleType_( SQL_HANDLE_STMT ),
10 parentDbc_( 0 ),
11 state_( S1 ),
12 err_( SQL_HANDLE_STMT ),
13 rowsAffected_( -1 ),
14 isParamBound_( true ),
15 isPrepared_( false ),
16 apd_(SQL_DESC_APP),
17 ipd_(SQL_DESC_IMP),
18 ard_(SQL_DESC_APP),
19 ird_(SQL_DESC_IMP)
20 //HACK::
21 //fetchMode_(SQL_FETCH_SINGLE_TUPLE)
23 cursorName_[0] = '\0';
26 SQLRETURN SQLAllocStmt(
27 SQLHDBC ConnectionHandle,
28 SQLHSTMT *StatementHandle)
30 return( CSqlOdbcStmt::SQLAllocHandle( ConnectionHandle, StatementHandle ) );
33 SQLRETURN CSqlOdbcStmt::SQLAllocHandle(
34 SQLHANDLE inputHandle, // IN
35 SQLHANDLE *outputHandle ) // OUT
37 CSqlOdbcDbc *inputDbc = (CSqlOdbcDbc*) inputHandle;
39 // Is Dbc valid ?
40 if( isValidHandle( inputDbc, SQL_HANDLE_DBC ) != SQL_SUCCESS )
41 return( SQL_INVALID_HANDLE );
43 // Is Dbc connected ?
44 if( inputDbc->state_ < C4 )
46 globalError.set( ERROR_CONNOTOPEN );
47 globalError.printStr( SQL_OV_ODBC3 );
48 return( SQL_ERROR );
51 // Allocate Statement object.
52 *outputHandle = (SQLHANDLE*) new CSqlOdbcStmt;
53 if( *outputHandle == NULL )
55 globalError.set( ERROR_MEMALLOC );
56 globalError.printStr( SQL_OV_ODBC3 );
57 return( SQL_ERROR );
60 // Initialize relation b/w Stmt and Dbc
61 inputDbc->stmtList_.insert( inputDbc->stmtList_.begin(), (CSqlOdbcStmt*) *outputHandle );
62 if( inputDbc->state_ <= C4 )
63 inputDbc->state_ = C5;
64 ((CSqlOdbcStmt*) *outputHandle)->parentDbc_ = inputDbc;
65 //CSqlOdbcError::printDbg("proxy:stmt:setConnection");
66 //((CSqlOdbcStmt*) *outputHandle)->fsqlStmt_->setConnection( inputDbc->fsqlConn_ );
68 return( SQL_SUCCESS );
71 SQLRETURN CSqlOdbcStmt::SQLFreeHandle(
72 SQLHANDLE inputHandle) // IN
74 CSqlOdbcStmt *inputStmt = (CSqlOdbcStmt*) inputHandle;
76 // Is Stmt valid ?
77 if( isValidHandle( inputStmt, SQL_HANDLE_STMT ) != SQL_SUCCESS )
78 return( SQL_INVALID_HANDLE );
80 // Can we proceed ?
81 if( inputStmt->chkStateForSQLFreeHandle() != SQL_SUCCESS )
82 return( SQL_ERROR );
84 // Free resultset
85 inputStmt->resetStmt();
87 // Remove Stmt from Parent Dbc.
88 std::vector<CSqlOdbcStmt*>::iterator iter;
89 iter = inputStmt->parentDbc_->stmtList_.begin();
90 while( iter != inputStmt->parentDbc_->stmtList_.end() )
92 if( *iter == inputStmt )
94 inputStmt->parentDbc_->stmtList_.erase( iter );
95 break;
97 iter++;
100 // Set Dbc state_ = no statement.
101 if( inputStmt->parentDbc_->stmtList_.size() == 0 )
102 if( inputStmt->parentDbc_->state_ == C5 )
103 inputStmt->parentDbc_->state_ = C4;
105 inputStmt->handleType_ = -1; // Make object invalid.
106 delete inputStmt; // Delete Stmt.
108 return( SQL_SUCCESS );
111 SQLRETURN SQLFreeStmt(
112 SQLHSTMT StatementHandle, // IN
113 SQLUSMALLINT Option) // IN
115 // Is Stmt valid ?
116 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
117 return( SQL_INVALID_HANDLE );
119 // Free Handle
120 if( Option == SQL_DROP )
121 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle ) );
123 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFreeStmt( Option ) );
126 SQLRETURN CSqlOdbcStmt::SQLFreeStmt(
127 SQLUSMALLINT option)
129 // Start with NO_ERR
130 err_.set( NO_ERR );
132 // Can we proceed
133 if( chkStateForSQLFreeStmt() != SQL_SUCCESS )
134 return( SQL_ERROR );
135 if (!fsqlStmt_) return (SQL_SUCCESS);
136 switch( option )
138 case SQL_CLOSE: // // Free resultset
139 // if( fsqlStmt_->isSelect() == true ) // CSQL
140 // {
141 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
142 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
143 // if( resultSet_ && resultSet_->isOpen() == true )
144 // {
145 // resultSet_->close();
146 // }
147 // }
149 // cursor states
150 if( isPrepared_ )
152 if( fsqlStmt_->isSelect() == true ) // CSQL
153 state_ = S3; // With Cursor
154 else
155 state_ = S2; // Without Cursor
157 else
159 ard_.freeAllDesc();
160 apd_.freeAllDesc();
161 ipd_.freeAllDesc();
162 ird_.freeAllDesc();
163 fsqlStmt_->free(); // CSQL
164 state_ = S1;
167 break;
169 case SQL_UNBIND: ard_.freeAllDesc();
170 ird_.freeAllDesc();
171 break;
173 case SQL_RESET_PARAMS: apd_.freeAllDesc();
174 ipd_.freeAllDesc();
175 //isParamBound_ = false;
176 break;
178 default: err_.set( ERROR_OPTRANGE );
179 return( SQL_ERROR );
181 return( SQL_SUCCESS );
184 SQLRETURN SQLBindCol(
185 SQLHSTMT StatementHandle,
186 SQLUSMALLINT ColumnNumber,
187 SQLSMALLINT TargetType,
188 SQLPOINTER TargetValue,
189 SQLINTEGER BufferLength,
190 SQLINTEGER *StrLen_or_Ind)
192 // Is Stmt valid ?
193 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
194 return( SQL_INVALID_HANDLE );
196 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindCol( ColumnNumber,
197 TargetType, TargetValue, BufferLength, StrLen_or_Ind ) );
200 SQLRETURN CSqlOdbcStmt::SQLBindCol(
201 SQLUSMALLINT columnNumber,
202 SQLSMALLINT targetType,
203 SQLPOINTER targetValue,
204 SQLINTEGER bufferLength,
205 SQLINTEGER *ind)
207 CSqlOdbcDesc *bindDesc = 0;
208 CSqlOdbcDesc *inputDesc = 0;
209 SQLRETURN found = SQL_ERROR;
211 // Start with NO_ERR
212 err_.set( NO_ERR );
214 // Can we proceed ?
215 if( chkStateForSQLBindCol() != SQL_SUCCESS )
216 return( SQL_ERROR );
218 // Invalid Buffer Length.
219 switch( targetType )
221 // switch is in order to support more types.
222 case SQL_C_CHAR:
223 if( bufferLength < 0 && bufferLength != SQL_NTS )
225 err_.set( ERROR_BUFLEN );
226 return( SQL_ERROR );
228 break;
229 case SQL_C_BINARY:
230 if( bufferLength < 0 && bufferLength != SQL_NTS )
232 err_.set( ERROR_BUFLEN );
233 return( SQL_ERROR );
235 break;
238 // Invalid Column Number
239 if( columnNumber < 1 )
241 err_.set( ERROR_COLNUM );
242 return( SQL_ERROR );
245 // Get the Descriptor if already exists
246 found = ard_.getDescWithColNum( columnNumber , &bindDesc );
248 // UNBIND
249 if( targetValue == 0 )
251 if( found != SQL_SUCCESS )
253 err_.set( ERROR_COLNUM );
254 return( SQL_ERROR );
256 ard_.delDesc( bindDesc ); // UNBIND
258 return( SQL_SUCCESS );
261 // Validate target Type, Value and Column no.
262 if( targetValue == 0 || isValidCType( targetType ) != SQL_SUCCESS )
264 err_.set( ERROR_INVBUFTYPE );
265 return( SQL_ERROR );
268 // Add new descriptor
269 if( found != SQL_SUCCESS )
271 bindDesc = new CSqlOdbcDesc();
272 ard_.insert( ard_.begin(), bindDesc );
275 // Initialize Descriptor.
276 bindDesc->col_ = columnNumber;
277 bindDesc->cType_ = targetType;
278 bindDesc->dataPtr_ = targetValue;
279 bindDesc->length_ = (SQLUINTEGER) bufferLength;
280 bindDesc->indPtr_ = (SQLPOINTER) ind;
282 found = ird_.getDescWithColNum( columnNumber , &inputDesc );
284 // Add new descriptor
285 if( found != SQL_SUCCESS )
287 inputDesc = new CSqlOdbcDesc();
288 ird_.insert(ird_.begin(),inputDesc);
291 // Initialize input Descriptor.
292 DataType sourceType = getCSqlType( targetType );
293 inputDesc->col_ = columnNumber;
294 inputDesc->cType_ = targetType;
295 getInputBuffer(&inputDesc->dataPtr_ ,sourceType,(SQLUINTEGER) bufferLength);
296 inputDesc->length_ = (SQLUINTEGER) bufferLength;
297 inputDesc->indPtr_ = (SQLPOINTER) ind;
299 return( SQL_SUCCESS );
302 SQLRETURN SQLSetParam(
303 SQLHSTMT StatementHandle,
304 SQLUSMALLINT ParameterNumber,
305 SQLSMALLINT ValueType,
306 SQLSMALLINT ParameterType,
307 SQLUINTEGER LengthPrecision,
308 SQLSMALLINT ParameterScale,
309 SQLPOINTER ParameterValue,
310 SQLINTEGER *StrLen_or_Ind)
312 return( SQLBindParameter( StatementHandle, ParameterNumber,
313 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
314 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
317 SQLRETURN SQLBindParam(
318 SQLHSTMT StatementHandle,
319 SQLUSMALLINT ParameterNumber,
320 SQLSMALLINT ValueType,
321 SQLSMALLINT ParameterType,
322 SQLUINTEGER LengthPrecision,
323 SQLSMALLINT ParameterScale,
324 SQLPOINTER ParameterValue,
325 SQLINTEGER *StrLen_or_Ind)
327 return( SQLBindParameter( StatementHandle, ParameterNumber,
328 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
329 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
332 SQLRETURN SQLBindParameter(
333 SQLHSTMT StatementHandle,
334 SQLUSMALLINT ParameterNumber,
335 SQLSMALLINT InputOutputType,
336 SQLSMALLINT ValueType,
337 SQLSMALLINT ParameterType,
338 SQLUINTEGER LengthPrecision,
339 SQLSMALLINT ParameterScale,
340 SQLPOINTER ParameterValue,
341 SQLINTEGER BufferLength,
342 SQLINTEGER *StrLen_or_Ind)
344 // Is Stmt valid ?
345 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
346 return( SQL_INVALID_HANDLE );
348 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindParameter( ParameterNumber,
349 InputOutputType, ValueType,
350 ParameterType, LengthPrecision,
351 ParameterScale, ParameterValue,
352 BufferLength, StrLen_or_Ind ) );
355 SQLRETURN CSqlOdbcStmt::SQLBindParameter(
356 SQLUSMALLINT parameterNumber,
357 SQLSMALLINT inputOutputType,
358 SQLSMALLINT valueType,
359 SQLSMALLINT parameterType,
360 SQLUINTEGER lengthPrecision,
361 SQLSMALLINT parameterScale,
362 SQLPOINTER parameterValue,
363 SQLINTEGER bufferLength,
364 SQLINTEGER *ind)
366 CSqlOdbcDesc *bindDesc = 0;
367 CSqlOdbcDesc *inputDesc =0;
368 SQLRETURN found;
370 // Start with NO_ERR
371 err_.set( NO_ERR );
373 // Can we proceed ?
374 if( chkStateForSQLBindParameter() != SQL_SUCCESS )
375 return( SQL_ERROR );
377 // Invalid Buffer Length.
378 switch( valueType )
380 // switch is in order to support more types.
381 case SQL_C_CHAR:
382 if( bufferLength < 0 && bufferLength != SQL_NTS )
384 err_.set( ERROR_BUFLEN );
385 return( SQL_ERROR );
387 break;
388 case SQL_C_BINARY:
389 if( bufferLength < 0 && bufferLength != SQL_NTS )
391 err_.set( ERROR_BUFLEN );
392 return( SQL_ERROR );
394 break;
397 // Validate parameters
398 switch( inputOutputType )
400 case SQL_PARAM_INPUT:
401 case SQL_PARAM_OUTPUT:
402 case SQL_PARAM_INPUT_OUTPUT: break;
403 default: err_.set( ERROR_INV_PARAMTYPE );
404 return( SQL_ERROR );
406 if( isValidCType( valueType ) != SQL_SUCCESS ||
407 isValidSQLType( parameterType ) != SQL_SUCCESS )
409 err_.set( ERROR_INVBUFTYPE );
410 return( SQL_ERROR );
412 if( parameterNumber < 1 )
414 err_.set( ERROR_COLNUM );
415 return( SQL_ERROR );
418 // Get the Descriptor if already exists
419 found = apd_.getDescWithColNum( parameterNumber , &bindDesc );
420 if( found != SQL_SUCCESS )
422 bindDesc = new CSqlOdbcDesc();
423 apd_.insert( apd_.end(), bindDesc );
424 // Initialize Descriptor.
425 bindDesc->col_ = parameterNumber;
426 bindDesc->paramType_ = inputOutputType;
427 bindDesc->cType_ = valueType;
428 bindDesc->sqlType_ = parameterType;
429 bindDesc->dataPtr_ = parameterValue;
430 bindDesc->length_ = (SQLUINTEGER) bufferLength;
431 bindDesc->precision_ =(short) lengthPrecision;
432 bindDesc->scale_ = parameterScale;
433 bindDesc->indPtr_ = (SQLPOINTER) ind;
435 found = ipd_.getDescWithColNum (parameterNumber, &inputDesc);
436 if( found != SQL_SUCCESS )
438 inputDesc = new CSqlOdbcDesc();
439 ipd_.insert(ipd_.end(),inputDesc);
440 //Initialize inputDescriptor
441 DataType destType=getCSqlType(valueType);
442 inputDesc->col_ = parameterNumber;
443 inputDesc->paramType_ = inputOutputType;
444 inputDesc->cType_ = valueType;
445 inputDesc->sqlType_ = parameterType;
446 inputDesc->dataPtr_= NULL;
447 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
448 inputDesc->length_ = (SQLUINTEGER) bufferLength;
449 inputDesc->precision_ = (short)lengthPrecision;
450 inputDesc->scale_ = parameterScale;
451 inputDesc->indPtr_ = (SQLPOINTER) ind;
453 //isParamBound_ = false;
454 return( SQL_SUCCESS );
457 SQLRETURN SQLPrepare(
458 SQLHSTMT StatementHandle, // IN
459 SQLCHAR *StatementText, // IN
460 SQLINTEGER TextLength) // IN
462 // Is Stmt valid ?
463 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
464 return( SQL_INVALID_HANDLE );
466 // Prepare
467 return( ((CSqlOdbcStmt*) StatementHandle)->SQLPrepare( StatementText, TextLength ) );
470 SQLRETURN CSqlOdbcStmt::SQLPrepare(
471 SQLCHAR *statementText, // IN
472 SQLINTEGER textLength) // IN
474 // Start with NO_ERR
475 err_.set( NO_ERR );
477 // Can we proceed ?
478 if( chkStateForSQLPrepare() != SQL_SUCCESS )
479 return( SQL_ERROR );
481 // Invalid Buffer Length.
482 if( textLength < 0 && textLength != SQL_NTS )
484 err_.set( ERROR_BUFLEN );
485 return( SQL_ERROR );
488 // If Stmt is already prepared.
489 if( state_ >= S2 ) {
490 resetStmt();
493 if (parentDbc_->mode_ ==1)
494 fsqlStmt_ = SqlFactory::createStatement(CSql);
495 else if (parentDbc_->mode_ ==2)
496 fsqlStmt_ = SqlFactory::createStatement(CSqlGateway);
497 else if (parentDbc_->mode_ ==3)
498 fsqlStmt_ = SqlFactory::createStatement(CSqlAdapter);
499 fsqlStmt_->setConnection( parentDbc_->fsqlConn_ );
501 // Prepare
502 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
503 DbRetVal rv=OK;
504 if( (rv=fsqlStmt_->prepare( (char*) statementText ))!= OK) // CSQL
506 state_ = S1;
507 err_.set(ERROR_GENERAL);
508 /*switch(rv)
510 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
511 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
512 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
513 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
514 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
515 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
516 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
517 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
518 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
519 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
520 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
521 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
522 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
523 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
524 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
525 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
526 default:
528 return( SQL_ERROR );
530 if( fsqlStmt_->isSelect() != true ) // CSQL
531 state_ = S2; // With cursor
532 else
533 state_ = S3; // Without cursor
535 //parentDbc_->state_ = C6;
536 isPrepared_ = true;
537 return( SQL_SUCCESS );
540 SQLRETURN SQLExecute(SQLHSTMT StatementHandle) // IN
542 // Is Stmt valid ?
543 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
544 return( SQL_INVALID_HANDLE );
546 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecute() );
549 SQLRETURN CSqlOdbcStmt::SQLExecute() // TODO
551 // Start with NO_ERR
552 err_.set( NO_ERR );
554 // Can we proceed ?
555 if( chkStateForSQLExecute() != SQL_SUCCESS )
556 return( SQL_ERROR );
558 if( fsqlStmt_->noOfParamFields() > 0 )
561 // Iterate through all apd_;
562 CSqlOdbcDesc *appParamDesc;
563 CSqlOdbcDescList::iterator apdIter;
564 apdIter = apd_.begin();
565 CSqlOdbcDesc *csqlParamDesc;
566 CSqlOdbcDescList::iterator ipdIter;
567 ipdIter = ipd_.begin();
569 //Get the source and the destination type
570 DataType sourceType = typeUnknown,destType = typeUnknown;
571 int paramNum=1,sourceLength=-1,destLength=-1;
572 bool nullFlag=false;
574 while( (apdIter != apd_.end()) || (ipdIter != ipd_.end()) )
576 appParamDesc=*apdIter;
577 csqlParamDesc=*ipdIter;
578 if((paramNum) <= fsqlStmt_->noOfParamFields())
580 FieldInfo *finfo = new FieldInfo();
581 if( fsqlStmt_->getParamFldInfo(paramNum, finfo ) != OK ) return( SQL_ERROR );
582 sourceType=getCSqlType(appParamDesc->cType_);
583 destType=finfo->type;
584 sourceLength=(int)appParamDesc->length_;
585 destLength=finfo->length;
586 delete finfo;
587 if(sourceType != typeUnknown && destType != typeUnknown)
589 //Check if NULL is inserted
590 if((appParamDesc->indPtr_ != NULL ) && (*(SQLINTEGER *)appParamDesc->indPtr_) == SQL_NULL_DATA)
592 nullFlag=true;
593 //finfo->isNull = true; CSQL TODO - need to understand how to set null
595 else
597 //Only if both types are not the same, then we need to copy it onto intermediate buffer
598 //Else no need
599 if( (sourceType == typeString || sourceType == typeBinary) && (sourceLength <= 0))
601 if((appParamDesc->indPtr_!= NULL) && *(SQLINTEGER *)appParamDesc->indPtr_ > 0)
602 sourceLength=(int)(*(SQLINTEGER *)appParamDesc->indPtr_);
603 else if (appParamDesc->precision_ > 0)
604 sourceLength=appParamDesc->precision_;
605 else
607 err_.set( ERROR_BUFLEN );
608 return SQL_ERROR;
611 if(destType == typeString) //|| destType == typeVarString)
613 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
614 destLength=sourceLength;
616 if(sourceType == destType)
617 //|| (sourceType == typeString && destType == typeVarString)
618 //|| (sourceType == typeBinary && destType == typeVarBinary))
620 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength,destType); // CSQL TODO
621 } else
623 getInputBuffer(&csqlParamDesc->dataPtr_ ,sourceType,sourceLength);
624 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength, sourceType);
625 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
629 else
631 err_.set(ERROR_GENERAL);
632 return SQL_ERROR;
635 paramNum++;
636 apdIter++;
637 ipdIter++;
642 // Get the result
643 int rowsAffected=0;
644 DbRetVal rv = fsqlStmt_->execute( rowsAffected );
645 if( rowsAffected < 0 )
647 if( isPrepared_ ) state_ = S2; else resetStmt();
648 err_.set( ERROR_GENERAL );
649 /*switch(rv)
651 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
652 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
653 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
654 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
655 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
656 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
657 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
658 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
659 default:
660 err_.set( ERROR_GENERAL );break;
661 } */
662 return( SQL_ERROR );
665 // Set Stmt State
666 if( fsqlStmt_->isSelect() == true )
668 rowsAffected_ = -1;
669 state_ = S5;
671 else
673 rowsAffected_ = rowsAffected;
674 state_ = S4;
677 // Set Dbc State to Transaction Mode.
678 parentDbc_->state_ = C6;
680 // AutoCommit Mode
681 if( parentDbc_->autoCommit_ == SQL_AUTOCOMMIT_ON )
682 parentDbc_->SQLEndTran( SQL_COMMIT );
684 return( SQL_SUCCESS );
687 SQLRETURN SQLExecDirect(
688 SQLHSTMT StatementHandle,
689 SQLCHAR *StatementText,
690 SQLINTEGER TextLength)
692 // Is Stmt valid ?
693 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
694 return( SQL_INVALID_HANDLE );
696 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecDirect( StatementText, TextLength ) );
699 SQLRETURN CSqlOdbcStmt::SQLExecDirect(
700 SQLCHAR *statementText,
701 SQLINTEGER textLength)
703 SQLRETURN ret;
705 // Can we proceed ?
706 if( chkStateForSQLExecDirect() != SQL_SUCCESS )
707 return( SQL_ERROR );
709 // SQLExecDirect = SQLPrepare + SQLExecute.
710 if( SQLPrepare( statementText, textLength ) != SQL_SUCCESS )
711 return( SQL_ERROR );
713 ret = SQLExecute();
714 isPrepared_ = false; // Set Stmt as non-prepared stmt.
716 if( ret != SQL_SUCCESS )
717 return( SQL_ERROR );
719 return( SQL_SUCCESS );
722 SQLRETURN SQLSetStmtOption(
723 SQLHSTMT StatementHandle,
724 SQLUSMALLINT Option,
725 SQLUINTEGER Value)
727 return (SQLSetStmtAttr(StatementHandle, Option, (SQLPOINTER) Value, 0));
730 SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
731 SQLINTEGER Attribute, SQLPOINTER Value,
732 SQLINTEGER StringLength)
734 return (((CSqlOdbcStmt*)StatementHandle)->SQLSetStmtAttr(Attribute, Value,StringLength));
737 SQLRETURN CSqlOdbcStmt::SQLSetStmtAttr(
738 SQLINTEGER Attribute,
739 SQLPOINTER Value,
740 SQLINTEGER stringLength)
742 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
743 //HACK
744 /*switch(Attribute)
746 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
747 //Default is SQL_FETCH_SINGLE_TUPLE.
748 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
749 //is sent from server to client in a single packet whatever be
750 //the packet size. If a tuple size is 50 and network packet size
751 //is 500, the remaining 450 bytes can also be used to send more
752 //in a single packet so that in the next SQLFetch call one network
753 //packet transfer overhead is reduced.
754 case SQL_FETCH_MODE:
755 if(state_ <= S5)
756 //state_ > S5 means Fetch has already started on this statement.
757 fetchMode_ = (SQLINTEGER)Value;
758 else
759 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
760 break;
761 default:
762 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
764 return (SQL_SUCCESS);
767 SQLRETURN SQLFetch(SQLHSTMT StatementHandle)
769 // Is Stmt valid ?
770 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
771 return( SQL_INVALID_HANDLE );
773 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFetch() );
776 SQLRETURN CSqlOdbcStmt::SQLFetch()
778 // Start with NO_ERR
779 err_.set( NO_ERR );
781 // Can we proceed ?
782 if( chkStateForSQLFetch() != SQL_SUCCESS )
783 return( SQL_ERROR );
785 void *tuple;
786 tuple = fsqlStmt_->next();
788 if( ! tuple ) // IF Row not found.
790 rowsAffected_ = 0;
791 state_ = S6;
792 return( SQL_NO_DATA_FOUND );
794 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
796 rowsAffected_ = -1;
797 err_.set( ERROR_GENERAL );
798 return( SQL_ERROR );
800 else // IF Row found.
802 rowsAffected_ = 1;
804 // Iterate through all ard_;
805 CSqlOdbcDesc *appColDesc;
806 CSqlOdbcDescList::iterator ardIter;
807 ardIter = ard_.begin();
808 //Get the input parameter data
809 CSqlOdbcDesc *csqlColDesc;
810 CSqlOdbcDescList::iterator irdIter;
811 irdIter = ird_.begin();
813 DataType sourceType = typeUnknown,destType = typeUnknown;
814 int colNum=-1,sourceLength=-1,destLength=-1;
815 SQLINTEGER ind;
816 void* sourceData = NULL;
817 FieldInfo *info = new FieldInfo();
818 while( (ardIter != ard_.end()) || (irdIter != ird_.end()) )
820 appColDesc = *ardIter;
821 csqlColDesc = *irdIter;
823 colNum = appColDesc->col_ - 1;
824 fsqlStmt_->getProjFldInfo(colNum, info);
825 sourceType = info->type;
826 destType = getCSqlType(appColDesc->cType_);
827 sourceLength = info->length;
828 destLength = (int)appColDesc->length_;
830 if( sourceType != typeUnknown && destType != typeUnknown )
832 sourceData = fsqlStmt_->getFieldValuePtr( colNum );
833 if(sourceData == NULL)
835 if (appColDesc->indPtr_ != NULL)
836 *((SQLINTEGER *)(appColDesc->indPtr_))=SQL_NULL_DATA;
838 else
840 /*if( sourceType == csqlSqlTvarBinary)
841 sourceLength=resultSet_->getDataLength(colNum); */
842 if (sourceType == typeString ) // CSQL TODO - handle varchar also
844 sourceLength=(int)(strlen((char *) sourceData ));
845 if(appColDesc->indPtr_ != NULL)
846 *((SQLINTEGER *)(appColDesc->indPtr_))=copyToOdbc(appColDesc->dataPtr_,destLength,
847 sourceData,sourceLength, sourceType);
848 else
849 copyToOdbc(appColDesc->dataPtr_,destLength,sourceData,
850 sourceLength, sourceType);
852 else
854 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
855 if(appColDesc->indPtr_ != NULL)
856 *((SQLINTEGER *)(appColDesc->indPtr_))=
857 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
858 else
859 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
862 // CSQL TODO - handle varstring, binary, varbinary
863 if( sourceType == typeString && sourceLength > destLength )
864 err_.set( ERROR_DATATRUNC );
867 ardIter++;
868 irdIter++;
870 state_ = S6;
872 if(err_.csqlErrCode == ERROR_DATATRUNC)
873 return (SQL_SUCCESS_WITH_INFO);
875 return( SQL_SUCCESS );
878 SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle)
880 // Is Stmt valid ?
881 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
882 return( SQL_INVALID_HANDLE );
884 return( ((CSqlOdbcStmt*) StatementHandle)->SQLCloseCursor() );
887 SQLRETURN CSqlOdbcStmt::SQLCloseCursor()
889 // Start with NO_ERR
890 err_.set( NO_ERR );
892 // Can we proceed ?
893 if( chkStateForSQLCloseCursor() != SQL_SUCCESS )
894 return( SQL_ERROR );
896 // Close the cursor
897 fsqlStmt_->close();
898 state_ = S3;
899 return( SQL_SUCCESS );
902 SQLRETURN SQLSetCursorName(
903 SQLHSTMT StatementHandle,
904 SQLCHAR *CursorName,
905 SQLSMALLINT NameLength)
907 // Is Stmt valid ?
908 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
909 return( SQL_INVALID_HANDLE );
911 return( ((CSqlOdbcStmt*) StatementHandle)->SQLSetCursorName( CursorName, NameLength ) );
914 SQLRETURN CSqlOdbcStmt::SQLSetCursorName(
915 SQLCHAR *cursorName,
916 SQLSMALLINT nameLength)
918 // Start with NO_ERR
919 err_.set( NO_ERR );
921 // Can we proceed ?
922 if( chkStateForSQLSetCursorName() != SQL_SUCCESS )
923 return( SQL_ERROR );
925 // Invalid Stmt Length.
926 if( nameLength < 0 && nameLength != SQL_NTS )
928 err_.set( ERROR_INVARGVAL );
929 return( SQL_ERROR );
932 // Validate Parameters
933 if( cursorName == 0 || cursorName[0] == '\0' || strlen( (char*) cursorName ) > SQL_MAX_CURSOR_NAME_LEN ||
934 nameLength > SQL_MAX_CURSOR_NAME_LEN )
936 err_.set( ERROR_CURNAME );
937 return( SQL_ERROR );
940 // Check for duplicate Name
941 std::vector<CSqlOdbcStmt*>::iterator iter;
942 iter = parentDbc_->stmtList_.begin();
943 while( iter != parentDbc_->stmtList_.end() )
945 if( *iter != this )
947 if( strcmp( (char*) cursorName, (char*) (*iter)->cursorName_ ) == 0 )
949 err_.set( ERROR_DUP_CURNAME );
950 return( SQL_ERROR );
953 iter++;
956 // Copy name
957 strcpy( (char*) cursorName_, (char*) cursorName );
959 return( SQL_SUCCESS );
962 SQLRETURN SQLGetCursorName(
963 SQLHSTMT StatementHandle,
964 SQLCHAR *CursorName,
965 SQLSMALLINT BufferLength,
966 SQLSMALLINT *NameLength)
968 // Is Stmt valid ?
969 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
970 return( SQL_INVALID_HANDLE );
972 return( ((CSqlOdbcStmt*) StatementHandle)->SQLGetCursorName( CursorName, BufferLength, NameLength ) );
974 SQLRETURN CSqlOdbcStmt::SQLGetCursorName(
975 SQLCHAR *cursorName,
976 SQLSMALLINT bufferLength,
977 SQLSMALLINT *nameLength)
979 // Can we proceed ?
980 if( chkStateForSQLGetCursorName() != SQL_SUCCESS )
981 return( SQL_ERROR );
983 if( cursorName_[0] == '\0' )
985 err_.set( ERROR_NOCURNAME );
986 return( SQL_ERROR );
989 // Copy
990 *nameLength = (short)strlen( (char*) cursorName_ );
991 if( *nameLength > bufferLength ) *nameLength = bufferLength;
992 strncpy( (char*) cursorName, (char*) cursorName_, *nameLength );
993 cursorName[ *nameLength ] = '\0';
995 // Did truncate ?
996 if( bufferLength < strlen( (char*) cursorName_ ) )
998 err_.set( ERROR_DATATRUNC );
999 return( SQL_SUCCESS_WITH_INFO );
1002 return( SQL_SUCCESS );
1005 SQLRETURN SQLNumResultCols(
1006 SQLHSTMT StatementHandle, // IN
1007 SQLSMALLINT *ColumnCount) // OUT
1009 // Is Stmt valid ?
1010 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1011 return( SQL_INVALID_HANDLE );
1013 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumResultCols( ColumnCount ) );
1016 SQLRETURN CSqlOdbcStmt::SQLNumResultCols(
1017 SQLSMALLINT *columnCount) // OUT
1019 // Start with NO_ERR
1020 err_.set( NO_ERR );
1022 // Can we proceed ?
1023 if( chkStateForSQLNumResultCols() != SQL_SUCCESS )
1024 return( SQL_ERROR );
1026 // If DML
1027 if( fsqlStmt_->isSelect() == false )
1029 *columnCount=0;
1030 return (SQL_SUCCESS);
1033 // If Select
1034 SQLSMALLINT count = fsqlStmt_->noOfProjFields();
1035 if( count < 1 ) // Assume atleast one column is projected
1036 return( SQL_ERROR );
1038 // Fill Column Count
1039 *columnCount = count;
1041 return( SQL_SUCCESS );
1044 SQLRETURN SQL_API SQLRowCount(
1045 SQLHSTMT StatementHandle, // IN
1046 SQLINTEGER *RowCount) // OUT
1048 // Is Stmt valid ?
1049 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1050 return( SQL_INVALID_HANDLE );
1052 return( ((CSqlOdbcStmt*) StatementHandle)->SQLRowCount( RowCount ) );
1055 SQLRETURN CSqlOdbcStmt::SQLRowCount(
1056 SQLINTEGER *rowCount) // OUT
1057 { // TODO
1058 // Start with NO_ERR
1059 err_.set( NO_ERR );
1061 // Can we proceed ?
1062 if( chkStateForSQLRowCount() != SQL_SUCCESS )
1063 return( SQL_ERROR );
1065 if(rowCount == NULL)
1066 return SQL_SUCCESS;
1068 if( state_ == S4 ) // For INSERT/DELETE/UPDATE
1069 *rowCount = (SQLINTEGER) rowsAffected_;
1070 else if( state_ == S5 ) // For SELECT before SQLFetch()
1072 *rowCount = (SQLINTEGER) 0;
1073 // CSQL TODO - Think if you really want to do this!!!
1075 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1076 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1077 if( resultSet_->next() != csqlSqlErrNoTuple )
1078 *rowCount = (SQLINTEGER) 1;
1080 resultSet_->close();
1081 resultSet_->open(); */
1083 else if( state_ == S6 ) // For SELECT after SQLFetch();
1084 *rowCount = (SQLINTEGER) rowsAffected_;
1086 return( SQL_SUCCESS );
1089 SQLRETURN SQLDescribeCol(
1090 SQLHSTMT StatementHandle,
1091 SQLUSMALLINT ColumnNumber,
1092 SQLCHAR *ColumnName,
1093 SQLSMALLINT BufferLength,
1094 SQLSMALLINT *NameLength,
1095 SQLSMALLINT *DataType,
1096 SQLUINTEGER *ColumnSize,
1097 SQLSMALLINT *DecimalDigits,
1098 SQLSMALLINT *Nullable)
1100 // Is Stmt valid ?
1101 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1102 return( SQL_INVALID_HANDLE );
1104 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeCol( ColumnNumber, ColumnName, BufferLength,
1105 NameLength, DataType, ColumnSize, DecimalDigits, Nullable) );
1108 SQLRETURN CSqlOdbcStmt::SQLDescribeCol(
1109 SQLUSMALLINT columnNumber,
1110 SQLCHAR *columnName,
1111 SQLSMALLINT bufferLength,
1112 SQLSMALLINT *nameLength,
1113 SQLSMALLINT *dataType,
1114 SQLUINTEGER *columnSize,
1115 SQLSMALLINT *decimalDigits,
1116 SQLSMALLINT *nullable)
1118 int nameLen;
1119 int type;
1120 int colSize;
1121 int deciDigits;
1122 int isNullable;
1124 // Start with NO_ERR
1125 err_.set( NO_ERR );
1127 // Can we proceed ?
1128 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1129 return( SQL_ERROR );
1131 if( columnNumber < 1 )
1133 err_.set( ERROR_COLNUM );
1134 return( SQL_ERROR );
1137 // If DML
1138 if( fsqlStmt_->isSelect() == false )
1139 return( SQL_ERROR );
1141 // If SELECT
1142 if(columnNumber > fsqlStmt_->noOfProjFields())
1144 err_.set( ERROR_COLNUM );
1145 return( SQL_ERROR );
1147 if(columnName == NULL) {
1148 err_.set( ERROR_COLNUM );
1149 return( SQL_ERROR );
1151 FieldInfo *info = new FieldInfo();
1152 fsqlStmt_->getProjFldInfo(columnNumber, info);
1153 strncpy( (char*)columnName, (char*)info->fldName, bufferLength );
1154 if(nameLength != NULL)
1155 *nameLength=(short)strlen((const char*)info->fldName); // HARDCODED - TO DO, need support for n/w layer & sql layer
1156 if(dataType != NULL)
1157 *dataType = (SQLSMALLINT) getSQLType(info->type); // Need to convert from SQL<->ODBC - TO DO
1158 if(columnSize != NULL)
1160 *columnSize = (SQLUINTEGER) info->length;
1161 SQLSMALLINT sqlType=getSQLType(info->type);
1162 if(sqlType == SQL_CHAR )
1163 *columnSize = *columnSize -1;
1166 /*if(decimalDigits != NULL) // CSQL TODO
1167 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1168 if(nullable != NULL)
1169 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1170 if(strlen((char*)info->fldName) > bufferLength)
1172 err_.set( ERROR_DATATRUNC );
1173 return( SQL_SUCCESS_WITH_INFO );
1175 else
1176 return( SQL_SUCCESS );
1179 SQLRETURN SQLColAttributes(
1180 SQLHSTMT StatementHandle,
1181 SQLUSMALLINT ColumnNumber,
1182 SQLUSMALLINT FieldIdentifier,
1183 SQLPOINTER CharacterAttributePtr,
1184 SQLSMALLINT BufferLength,
1185 SQLSMALLINT *StringLengthPtr,
1186 SQLINTEGER *NumericAttributePtr)
1188 // Is Stmt valid ?
1189 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1190 return( SQL_INVALID_HANDLE );
1192 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1193 CharacterAttributePtr, BufferLength, StringLengthPtr, (SQLPOINTER)NumericAttributePtr) );
1196 SQLRETURN SQLColAttribute(
1197 SQLHSTMT StatementHandle,
1198 SQLUSMALLINT ColumnNumber,
1199 SQLUSMALLINT FieldIdentifier,
1200 SQLPOINTER CharacterAttributePtr,
1201 SQLSMALLINT BufferLength,
1202 SQLSMALLINT * StringLengthPtr,
1203 SQLPOINTER NumericAttributePtr)
1205 // Is Stmt valid ?
1206 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1207 return( SQL_INVALID_HANDLE );
1209 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1210 CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr) );
1213 SQLRETURN CSqlOdbcStmt::SQLColAttribute(
1214 SQLUSMALLINT columnNumber,
1215 SQLUSMALLINT fieldIdentifier,
1216 SQLPOINTER characterAttributePtr,
1217 SQLSMALLINT bufferLength,
1218 SQLSMALLINT * stringLengthPtr,
1219 SQLPOINTER numericAttributePtr)
1221 int nameLen;
1222 int type;
1223 int colSize;
1224 int deciDigits;
1225 int isNullable;
1227 // Start with NO_ERR
1228 err_.set( NO_ERR );
1230 // Can we proceed ?
1231 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1232 return( SQL_ERROR );
1234 if( columnNumber < 1 )
1236 err_.set( ERROR_COLNUM );
1237 return( SQL_ERROR );
1239 // If DML
1240 if( fsqlStmt_->isSelect() == false )
1241 return( SQL_ERROR );
1243 FieldInfo *info = new FieldInfo();
1244 fsqlStmt_->getProjFldInfo(columnNumber, info);
1246 // If SELECT
1247 if(columnNumber > fsqlStmt_->noOfProjFields())
1249 err_.set( ERROR_COLNUM );
1250 return( SQL_ERROR );
1252 switch(fieldIdentifier)
1254 case SQL_DESC_NAME:
1255 case SQL_COLUMN_NAME:
1256 if(characterAttributePtr != NULL)
1258 strncpy( (char*)characterAttributePtr, (char*)info->fldName, bufferLength);
1259 if(stringLengthPtr != NULL)
1260 *stringLengthPtr=(short)strlen((char*)info->fldName);
1262 break;
1263 case SQL_DESC_COUNT:
1264 case SQL_COLUMN_COUNT:
1265 if(numericAttributePtr != NULL)
1266 *(SQLINTEGER*)numericAttributePtr=fsqlStmt_->noOfProjFields();
1267 break;
1268 case SQL_DESC_TYPE:
1269 case SQL_COLUMN_TYPE:
1270 if(numericAttributePtr != NULL)
1271 *(SQLINTEGER *)numericAttributePtr=getSQLType(info->type);
1272 break;
1273 case SQL_DESC_LENGTH:
1274 case SQL_COLUMN_LENGTH:
1275 if(numericAttributePtr != NULL)
1277 SQLSMALLINT sqlType=getSQLType(info->type);
1278 *(SQLINTEGER *)numericAttributePtr=(SQLUINTEGER) info->length;
1279 if(sqlType == SQL_CHAR)
1280 *(SQLINTEGER *)numericAttributePtr=*(SQLINTEGER *)numericAttributePtr -1;
1282 break;
1283 case SQL_DESC_PRECISION:
1284 case SQL_COLUMN_PRECISION:
1285 /*if(numericAttributePtr != NULL) // CSQL TODO
1286 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1287 break;
1288 case SQL_DESC_SCALE:
1289 case SQL_COLUMN_SCALE:
1290 /*if(numericAttributePtr != NULL) // CSQL TODO
1291 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1292 break;
1293 case SQL_DESC_NULLABLE:
1294 case SQL_COLUMN_NULLABLE:
1295 /*if(numericAttributePtr != NULL) // CSQL TODO
1296 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1297 break;
1298 case SQL_DESC_UNSIGNED:
1299 if(numericAttributePtr != NULL)
1301 SQLSMALLINT sqlType=getSQLType(info->type);
1302 if((sqlType != SQL_TIME) && (sqlType != SQL_DATE) && (sqlType != SQL_TIMESTAMP)
1303 && (sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR) && (sqlType != SQL_BINARY)
1304 && (sqlType != SQL_VARBINARY) && (sqlType != SQL_BIT))
1305 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1306 else
1307 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1309 break;
1310 case SQL_DESC_FIXED_PREC_SCALE:
1311 if(numericAttributePtr != NULL)
1312 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1313 break;
1314 case SQL_DESC_TYPE_NAME:
1315 if(characterAttributePtr != NULL)
1317 SQLSMALLINT sqlType=getSQLType(info->type);
1318 strncpy((char*)characterAttributePtr,(char *)(getSQLTypeName(sqlType)),bufferLength);
1319 if(stringLengthPtr != NULL)
1320 *stringLengthPtr=(int)strlen((char *)getSQLTypeName(sqlType));
1322 break;
1323 case SQL_DESC_UPDATABLE:
1324 if(numericAttributePtr != NULL)
1325 *(SQLINTEGER*)numericAttributePtr=SQL_ATTR_READWRITE_UNKNOWN;
1326 break;
1327 case SQL_DESC_AUTO_UNIQUE_VALUE:
1328 if(numericAttributePtr != NULL)
1329 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1330 break;
1331 case SQL_DESC_CASE_SENSITIVE:
1332 if(numericAttributePtr != NULL)
1334 SQLSMALLINT sqlType=getSQLType(info->type);
1335 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1336 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1337 else
1338 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1340 break;
1341 case SQL_DESC_SEARCHABLE:
1342 if(numericAttributePtr != NULL)
1344 SQLSMALLINT sqlType=getSQLType(info->type);
1345 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1346 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_BASIC;
1347 else
1348 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_SEARCHABLE;
1350 break;
1351 default:
1352 break;
1354 if(stringLengthPtr != NULL)
1356 if(*stringLengthPtr > bufferLength)
1358 err_.set( ERROR_DATATRUNC );
1359 return( SQL_SUCCESS_WITH_INFO );
1362 return( SQL_SUCCESS );
1365 SQLRETURN SQLNumParams(
1366 SQLHSTMT StatementHandle,
1367 SQLSMALLINT * ParameterCountPtr)
1369 // Is Stmt valid ?
1370 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1371 return( SQL_INVALID_HANDLE );
1373 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumParams(ParameterCountPtr) );
1376 SQLRETURN CSqlOdbcStmt::SQLNumParams(
1377 SQLSMALLINT * ParameterCount)
1379 // Start with NO_ERR
1380 err_.set( NO_ERR );
1382 // Can we proceed ?
1383 if( chkStateForSQLNumParams() != SQL_SUCCESS )
1384 return( SQL_ERROR );
1385 if(ParameterCount == NULL)
1386 return (SQL_ERROR);
1387 *ParameterCount=(int)apd_.size();
1389 return SQL_SUCCESS;
1392 SQLRETURN SQLDescribeParam(
1393 SQLHSTMT StatementHandle,
1394 SQLUSMALLINT ParameterNumber,
1395 SQLSMALLINT * DataTypePtr,
1396 SQLUINTEGER * ParameterSizePtr,
1397 SQLSMALLINT * DecimalDigitsPtr,
1398 SQLSMALLINT * NullablePtr)
1400 // Is Stmt valid ?
1401 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1402 return( SQL_INVALID_HANDLE );
1404 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeParam(ParameterNumber,DataTypePtr,
1405 ParameterSizePtr,DecimalDigitsPtr,NullablePtr ) );
1407 SQLRETURN CSqlOdbcStmt::SQLDescribeParam(
1408 SQLUSMALLINT paramNumber,
1409 SQLSMALLINT * dataType,
1410 SQLUINTEGER * paramSize,
1411 SQLSMALLINT * decimalDigits,
1412 SQLSMALLINT * isNullable)
1415 // Start with NO_ERR
1416 err_.set( NO_ERR );
1418 // Can we proceed ?
1419 if( chkStateForSQLDescribeParam() != SQL_SUCCESS )
1420 return( SQL_ERROR );
1422 if( paramNumber < 1 )
1424 err_.set( ERROR_PARAMNUM);
1425 return( SQL_ERROR );
1428 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1429 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1430 if(paramNumber > fsqlStmt_->noOfParamFields())
1432 err_.set( ERROR_PARAMNUM );
1433 return( SQL_ERROR );
1436 FieldInfo *finfo = new FieldInfo();
1437 if( fsqlStmt_->getParamFldInfo( paramNumber-1, finfo ) != OK ) return( SQL_ERROR );
1438 if(dataType != NULL)
1439 *dataType = (SQLSMALLINT) getSQLType(finfo->type);
1440 if(paramSize != NULL)
1442 *paramSize = (SQLUINTEGER) finfo->length;
1443 SQLSMALLINT sqlType=getSQLType(finfo->type);
1444 if(sqlType == SQL_CHAR )
1445 *paramSize= *paramSize -1;
1447 /*if(decimalDigits != NULL) // CSQL TODO
1448 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1449 if(isNullable != NULL)
1450 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1451 return( SQL_SUCCESS );
1454 // Resets the Stmt to initial state. As if newly allocated.
1455 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1457 SQLFreeStmt( SQL_CLOSE );
1458 SQLFreeStmt( SQL_UNBIND );
1459 SQLFreeStmt( SQL_RESET_PARAMS );
1460 if (fsqlStmt_) fsqlStmt_->free();
1461 delete fsqlStmt_;
1462 fsqlStmt_ = NULL;
1463 isPrepared_ = false;
1464 state_ = S1;