unique support for tree index
[csql.git] / src / odbc / odbcStmt.cxx
blob6ad5c51a566d4b6f5c82af87136472e07c3d2db0
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 inputStmt->parentDbc_->state_ = C4;
104 inputStmt->handleType_ = -1; // Make object invalid.
105 delete inputStmt; // Delete Stmt.
107 return( SQL_SUCCESS );
110 SQLRETURN SQLFreeStmt(
111 SQLHSTMT StatementHandle, // IN
112 SQLUSMALLINT Option) // IN
114 // Is Stmt valid ?
115 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
116 return( SQL_INVALID_HANDLE );
118 // Free Handle
119 if( Option == SQL_DROP )
120 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle ) );
122 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFreeStmt( Option ) );
125 SQLRETURN CSqlOdbcStmt::SQLFreeStmt(
126 SQLUSMALLINT option)
128 // Start with NO_ERR
129 err_.set( NO_ERR );
131 // Can we proceed
132 if( chkStateForSQLFreeStmt() != SQL_SUCCESS )
133 return( SQL_ERROR );
134 if (!fsqlStmt_) return (SQL_SUCCESS);
135 switch( option )
137 case SQL_CLOSE: // // Free resultset
138 // if( fsqlStmt_->isSelect() == true ) // CSQL
139 // {
140 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
141 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
142 // if( resultSet_ && resultSet_->isOpen() == true )
143 // {
144 // resultSet_->close();
145 // }
146 // }
148 // cursor states
149 if( isPrepared_ )
151 if( fsqlStmt_->isSelect() == true ) // CSQL
152 state_ = S3; // With Cursor
153 else
154 state_ = S2; // Without Cursor
156 else
158 ard_.freeAllDesc();
159 apd_.freeAllDesc();
160 ipd_.freeAllDesc();
161 ird_.freeAllDesc();
162 fsqlStmt_->free(); // CSQL
163 state_ = S1;
166 break;
168 case SQL_UNBIND: ard_.freeAllDesc();
169 ird_.freeAllDesc();
170 break;
172 case SQL_RESET_PARAMS: apd_.freeAllDesc();
173 ipd_.freeAllDesc();
174 //isParamBound_ = false;
175 break;
177 default: err_.set( ERROR_OPTRANGE );
178 return( SQL_ERROR );
180 return( SQL_SUCCESS );
183 SQLRETURN SQLBindCol(
184 SQLHSTMT StatementHandle,
185 SQLUSMALLINT ColumnNumber,
186 SQLSMALLINT TargetType,
187 SQLPOINTER TargetValue,
188 SQLINTEGER BufferLength,
189 SQLINTEGER *StrLen_or_Ind)
191 // Is Stmt valid ?
192 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
193 return( SQL_INVALID_HANDLE );
195 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindCol( ColumnNumber,
196 TargetType, TargetValue, BufferLength, StrLen_or_Ind ) );
199 SQLRETURN CSqlOdbcStmt::SQLBindCol(
200 SQLUSMALLINT columnNumber,
201 SQLSMALLINT targetType,
202 SQLPOINTER targetValue,
203 SQLINTEGER bufferLength,
204 SQLINTEGER *ind)
206 CSqlOdbcDesc *bindDesc = 0;
207 CSqlOdbcDesc *inputDesc = 0;
208 SQLRETURN found = SQL_ERROR;
210 // Start with NO_ERR
211 err_.set( NO_ERR );
213 // Can we proceed ?
214 if( chkStateForSQLBindCol() != SQL_SUCCESS )
215 return( SQL_ERROR );
217 // Invalid Buffer Length.
218 switch( targetType )
220 // switch is in order to support more types.
221 case SQL_C_CHAR:
222 if( bufferLength < 0 && bufferLength != SQL_NTS )
224 err_.set( ERROR_BUFLEN );
225 return( SQL_ERROR );
227 break;
228 case SQL_C_BINARY:
229 if( bufferLength < 0 && bufferLength != SQL_NTS )
231 err_.set( ERROR_BUFLEN );
232 return( SQL_ERROR );
234 break;
237 // Invalid Column Number
238 if( columnNumber < 1 )
240 err_.set( ERROR_COLNUM );
241 return( SQL_ERROR );
244 // Get the Descriptor if already exists
245 found = ard_.getDescWithColNum( columnNumber , &bindDesc );
247 // UNBIND
248 if( targetValue == 0 )
250 if( found != SQL_SUCCESS )
252 err_.set( ERROR_COLNUM );
253 return( SQL_ERROR );
255 ard_.delDesc( bindDesc ); // UNBIND
257 return( SQL_SUCCESS );
260 // Validate target Type, Value and Column no.
261 if( targetValue == 0 || isValidCType( targetType ) != SQL_SUCCESS )
263 err_.set( ERROR_INVBUFTYPE );
264 return( SQL_ERROR );
267 // Add new descriptor
268 if( found != SQL_SUCCESS )
270 bindDesc = new CSqlOdbcDesc();
271 ard_.insert( ard_.begin(), bindDesc );
274 // Initialize Descriptor.
275 bindDesc->col_ = columnNumber;
276 bindDesc->cType_ = targetType;
277 bindDesc->dataPtr_ = targetValue;
278 bindDesc->length_ = (SQLUINTEGER) bufferLength;
279 bindDesc->indPtr_ = (SQLPOINTER) ind;
281 found = ird_.getDescWithColNum( columnNumber , &inputDesc );
283 // Add new descriptor
284 if( found != SQL_SUCCESS )
286 inputDesc = new CSqlOdbcDesc();
287 ird_.insert(ird_.begin(),inputDesc);
290 // Initialize input Descriptor.
291 DataType sourceType = getCSqlType( targetType );
292 inputDesc->col_ = columnNumber;
293 inputDesc->cType_ = targetType;
294 getInputBuffer(&inputDesc->dataPtr_ ,sourceType,(SQLUINTEGER) bufferLength);
295 inputDesc->length_ = (SQLUINTEGER) bufferLength;
296 inputDesc->indPtr_ = (SQLPOINTER) ind;
298 return( SQL_SUCCESS );
301 SQLRETURN SQLSetParam(
302 SQLHSTMT StatementHandle,
303 SQLUSMALLINT ParameterNumber,
304 SQLSMALLINT ValueType,
305 SQLSMALLINT ParameterType,
306 SQLUINTEGER LengthPrecision,
307 SQLSMALLINT ParameterScale,
308 SQLPOINTER ParameterValue,
309 SQLINTEGER *StrLen_or_Ind)
311 return( SQLBindParameter( StatementHandle, ParameterNumber,
312 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
313 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
316 SQLRETURN SQLBindParam(
317 SQLHSTMT StatementHandle,
318 SQLUSMALLINT ParameterNumber,
319 SQLSMALLINT ValueType,
320 SQLSMALLINT ParameterType,
321 SQLUINTEGER LengthPrecision,
322 SQLSMALLINT ParameterScale,
323 SQLPOINTER ParameterValue,
324 SQLINTEGER *StrLen_or_Ind)
326 return( SQLBindParameter( StatementHandle, ParameterNumber,
327 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
328 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
331 SQLRETURN SQLBindParameter(
332 SQLHSTMT StatementHandle,
333 SQLUSMALLINT ParameterNumber,
334 SQLSMALLINT InputOutputType,
335 SQLSMALLINT ValueType,
336 SQLSMALLINT ParameterType,
337 SQLUINTEGER LengthPrecision,
338 SQLSMALLINT ParameterScale,
339 SQLPOINTER ParameterValue,
340 SQLINTEGER BufferLength,
341 SQLINTEGER *StrLen_or_Ind)
343 // Is Stmt valid ?
344 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
345 return( SQL_INVALID_HANDLE );
347 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindParameter( ParameterNumber,
348 InputOutputType, ValueType,
349 ParameterType, LengthPrecision,
350 ParameterScale, ParameterValue,
351 BufferLength, StrLen_or_Ind ) );
354 SQLRETURN CSqlOdbcStmt::SQLBindParameter(
355 SQLUSMALLINT parameterNumber,
356 SQLSMALLINT inputOutputType,
357 SQLSMALLINT valueType,
358 SQLSMALLINT parameterType,
359 SQLUINTEGER lengthPrecision,
360 SQLSMALLINT parameterScale,
361 SQLPOINTER parameterValue,
362 SQLINTEGER bufferLength,
363 SQLINTEGER *ind)
365 CSqlOdbcDesc *bindDesc = 0;
366 CSqlOdbcDesc *inputDesc =0;
367 SQLRETURN found;
369 // Start with NO_ERR
370 err_.set( NO_ERR );
372 // Can we proceed ?
373 if( chkStateForSQLBindParameter() != SQL_SUCCESS )
374 return( SQL_ERROR );
376 // Invalid Buffer Length.
377 switch( valueType )
379 // switch is in order to support more types.
380 case SQL_C_CHAR:
381 if( bufferLength < 0 && bufferLength != SQL_NTS )
383 err_.set( ERROR_BUFLEN );
384 return( SQL_ERROR );
386 break;
387 case SQL_C_BINARY:
388 if( bufferLength < 0 && bufferLength != SQL_NTS )
390 err_.set( ERROR_BUFLEN );
391 return( SQL_ERROR );
393 break;
396 // Validate parameters
397 switch( inputOutputType )
399 case SQL_PARAM_INPUT:
400 case SQL_PARAM_OUTPUT:
401 case SQL_PARAM_INPUT_OUTPUT: break;
402 default: err_.set( ERROR_INV_PARAMTYPE );
403 return( SQL_ERROR );
405 if( isValidCType( valueType ) != SQL_SUCCESS ||
406 isValidSQLType( parameterType ) != SQL_SUCCESS )
408 err_.set( ERROR_INVBUFTYPE );
409 return( SQL_ERROR );
411 if( parameterNumber < 1 )
413 err_.set( ERROR_COLNUM );
414 return( SQL_ERROR );
417 // Get the Descriptor if already exists
418 found = apd_.getDescWithColNum( parameterNumber , &bindDesc );
419 if( found != SQL_SUCCESS )
421 bindDesc = new CSqlOdbcDesc();
422 apd_.insert( apd_.end(), bindDesc );
423 // Initialize Descriptor.
424 bindDesc->col_ = parameterNumber;
425 bindDesc->paramType_ = inputOutputType;
426 bindDesc->cType_ = valueType;
427 bindDesc->sqlType_ = parameterType;
428 bindDesc->dataPtr_ = parameterValue;
429 bindDesc->length_ = (SQLUINTEGER) bufferLength;
430 bindDesc->precision_ =(short) lengthPrecision;
431 bindDesc->scale_ = parameterScale;
432 bindDesc->indPtr_ = (SQLPOINTER) ind;
434 found = ipd_.getDescWithColNum (parameterNumber, &inputDesc);
435 if( found != SQL_SUCCESS )
437 inputDesc = new CSqlOdbcDesc();
438 ipd_.insert(ipd_.end(),inputDesc);
439 //Initialize inputDescriptor
440 DataType destType=getCSqlType(valueType);
441 inputDesc->col_ = parameterNumber;
442 inputDesc->paramType_ = inputOutputType;
443 inputDesc->cType_ = valueType;
444 inputDesc->sqlType_ = parameterType;
445 inputDesc->dataPtr_= NULL;
446 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
447 inputDesc->length_ = (SQLUINTEGER) bufferLength;
448 inputDesc->precision_ = (short)lengthPrecision;
449 inputDesc->scale_ = parameterScale;
450 inputDesc->indPtr_ = (SQLPOINTER) ind;
452 //isParamBound_ = false;
453 return( SQL_SUCCESS );
456 SQLRETURN SQLPrepare(
457 SQLHSTMT StatementHandle, // IN
458 SQLCHAR *StatementText, // IN
459 SQLINTEGER TextLength) // IN
461 // Is Stmt valid ?
462 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
463 return( SQL_INVALID_HANDLE );
465 // Prepare
466 return( ((CSqlOdbcStmt*) StatementHandle)->SQLPrepare( StatementText, TextLength ) );
469 SQLRETURN CSqlOdbcStmt::SQLPrepare(
470 SQLCHAR *statementText, // IN
471 SQLINTEGER textLength) // IN
473 // Start with NO_ERR
474 err_.set( NO_ERR );
476 // Can we proceed ?
477 if( chkStateForSQLPrepare() != SQL_SUCCESS )
478 return( SQL_ERROR );
480 // Invalid Buffer Length.
481 if( textLength < 0 && textLength != SQL_NTS )
483 err_.set( ERROR_BUFLEN );
484 return( SQL_ERROR );
487 // If Stmt is already prepared.
488 if( state_ >= S2 ) {
489 resetStmt();
492 if (parentDbc_->mode_ ==1)
493 fsqlStmt_ = SqlFactory::createStatement(CSql);
494 else if (parentDbc_->mode_ ==2)
495 fsqlStmt_ = SqlFactory::createStatement(CSqlGateway);
496 else if (parentDbc_->mode_ ==3)
497 fsqlStmt_ = SqlFactory::createStatement(CSqlAdapter);
498 fsqlStmt_->setConnection( parentDbc_->fsqlConn_ );
500 // Prepare
501 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
502 DbRetVal rv=OK;
503 if( (rv=fsqlStmt_->prepare( (char*) statementText ))!= OK) // CSQL
505 state_ = S1;
506 err_.set(ERROR_GENERAL);
507 /*switch(rv)
509 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
510 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
511 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
512 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
513 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
514 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
515 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
516 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
517 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
518 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
519 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
520 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
521 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
522 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
523 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
524 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
525 default:
527 return( SQL_ERROR );
529 if( fsqlStmt_->isSelect() != true ) // CSQL
530 state_ = S2; // With cursor
531 else
532 state_ = S3; // Without cursor
534 //parentDbc_->state_ = C6;
535 isPrepared_ = true;
536 return( SQL_SUCCESS );
539 SQLRETURN SQLExecute(SQLHSTMT StatementHandle) // IN
541 // Is Stmt valid ?
542 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
543 return( SQL_INVALID_HANDLE );
545 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecute() );
548 SQLRETURN CSqlOdbcStmt::SQLExecute() // TODO
550 // Start with NO_ERR
551 err_.set( NO_ERR );
553 // Can we proceed ?
554 if( chkStateForSQLExecute() != SQL_SUCCESS )
555 return( SQL_ERROR );
557 if( fsqlStmt_->noOfParamFields() > 0 )
560 // Iterate through all apd_;
561 CSqlOdbcDesc *appParamDesc;
562 CSqlOdbcDescList::iterator apdIter;
563 apdIter = apd_.begin();
564 CSqlOdbcDesc *csqlParamDesc;
565 CSqlOdbcDescList::iterator ipdIter;
566 ipdIter = ipd_.begin();
568 //Get the source and the destination type
569 DataType sourceType = typeUnknown,destType = typeUnknown;
570 int paramNum=1,sourceLength=-1,destLength=-1;
571 bool nullFlag=false;
573 while( (apdIter != apd_.end()) || (ipdIter != ipd_.end()) )
575 appParamDesc=*apdIter;
576 csqlParamDesc=*ipdIter;
577 if((paramNum) <= fsqlStmt_->noOfParamFields())
579 FieldInfo *finfo = new FieldInfo();
580 if( fsqlStmt_->getParamFldInfo(paramNum, finfo ) != OK ) return( SQL_ERROR );
581 sourceType=getCSqlType(appParamDesc->cType_);
582 destType=finfo->type;
583 sourceLength=(int)appParamDesc->length_;
584 destLength=finfo->length;
585 delete finfo;
586 if(sourceType != typeUnknown && destType != typeUnknown)
588 //Check if NULL is inserted
589 if((appParamDesc->indPtr_ != NULL ) && (*(SQLINTEGER *)appParamDesc->indPtr_) == SQL_NULL_DATA)
591 nullFlag=true;
592 //finfo->isNull = true; CSQL TODO - need to understand how to set null
594 else
596 //Only if both types are not the same, then we need to copy it onto intermediate buffer
597 //Else no need
598 if( (sourceType == typeString || sourceType == typeBinary) && (sourceLength <= 0))
600 if((appParamDesc->indPtr_!= NULL) && *(SQLINTEGER *)appParamDesc->indPtr_ > 0)
601 sourceLength=(int)(*(SQLINTEGER *)appParamDesc->indPtr_);
602 else if (appParamDesc->precision_ > 0)
603 sourceLength=appParamDesc->precision_;
604 else
606 err_.set( ERROR_BUFLEN );
607 return SQL_ERROR;
610 if(destType == typeString) //|| destType == typeVarString)
612 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
613 destLength=sourceLength;
615 if(sourceType == destType)
616 //|| (sourceType == typeString && destType == typeVarString)
617 //|| (sourceType == typeBinary && destType == typeVarBinary))
619 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength,destType); // CSQL TODO
620 } else
622 getInputBuffer(&csqlParamDesc->dataPtr_ ,sourceType,sourceLength);
623 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength, sourceType);
624 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
628 else
630 err_.set(ERROR_GENERAL);
631 return SQL_ERROR;
634 paramNum++;
635 apdIter++;
636 ipdIter++;
641 // Get the result
642 int rowsAffected=0;
643 DbRetVal rv = fsqlStmt_->execute( rowsAffected );
644 if( rowsAffected < 0 )
646 if( isPrepared_ ) state_ = S2; else resetStmt();
647 err_.set( ERROR_GENERAL );
648 /*switch(rv)
650 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
651 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
652 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
653 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
654 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
655 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
656 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
657 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
658 default:
659 err_.set( ERROR_GENERAL );break;
660 } */
661 return( SQL_ERROR );
664 // Set Stmt State
665 if( fsqlStmt_->isSelect() == true )
667 rowsAffected_ = -1;
668 state_ = S5;
670 else
672 rowsAffected_ = rowsAffected;
673 state_ = S4;
676 // Set Dbc State to Transaction Mode.
677 parentDbc_->state_ = C6;
679 // AutoCommit Mode
680 if( parentDbc_->autoCommit_ == SQL_AUTOCOMMIT_ON )
681 parentDbc_->SQLEndTran( SQL_COMMIT );
683 return( SQL_SUCCESS );
686 SQLRETURN SQLExecDirect(
687 SQLHSTMT StatementHandle,
688 SQLCHAR *StatementText,
689 SQLINTEGER TextLength)
691 // Is Stmt valid ?
692 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
693 return( SQL_INVALID_HANDLE );
695 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecDirect( StatementText, TextLength ) );
698 SQLRETURN CSqlOdbcStmt::SQLExecDirect(
699 SQLCHAR *statementText,
700 SQLINTEGER textLength)
702 SQLRETURN ret;
704 // Can we proceed ?
705 if( chkStateForSQLExecDirect() != SQL_SUCCESS )
706 return( SQL_ERROR );
708 // SQLExecDirect = SQLPrepare + SQLExecute.
709 if( SQLPrepare( statementText, textLength ) != SQL_SUCCESS )
710 return( SQL_ERROR );
712 ret = SQLExecute();
713 isPrepared_ = false; // Set Stmt as non-prepared stmt.
715 if( ret != SQL_SUCCESS )
716 return( SQL_ERROR );
718 return( SQL_SUCCESS );
721 SQLRETURN SQLSetStmtOption(
722 SQLHSTMT StatementHandle,
723 SQLUSMALLINT Option,
724 SQLUINTEGER Value)
726 return (SQLSetStmtAttr(StatementHandle, Option, (SQLPOINTER) Value, 0));
729 SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
730 SQLINTEGER Attribute, SQLPOINTER Value,
731 SQLINTEGER StringLength)
733 return (((CSqlOdbcStmt*)StatementHandle)->SQLSetStmtAttr(Attribute, Value,StringLength));
736 SQLRETURN CSqlOdbcStmt::SQLSetStmtAttr(
737 SQLINTEGER Attribute,
738 SQLPOINTER Value,
739 SQLINTEGER stringLength)
741 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
742 //HACK
743 /*switch(Attribute)
745 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
746 //Default is SQL_FETCH_SINGLE_TUPLE.
747 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
748 //is sent from server to client in a single packet whatever be
749 //the packet size. If a tuple size is 50 and network packet size
750 //is 500, the remaining 450 bytes can also be used to send more
751 //in a single packet so that in the next SQLFetch call one network
752 //packet transfer overhead is reduced.
753 case SQL_FETCH_MODE:
754 if(state_ <= S5)
755 //state_ > S5 means Fetch has already started on this statement.
756 fetchMode_ = (SQLINTEGER)Value;
757 else
758 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
759 break;
760 default:
761 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
763 return (SQL_SUCCESS);
766 SQLRETURN SQLFetch(SQLHSTMT StatementHandle)
768 // Is Stmt valid ?
769 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
770 return( SQL_INVALID_HANDLE );
772 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFetch() );
775 SQLRETURN CSqlOdbcStmt::SQLFetch()
777 // Start with NO_ERR
778 err_.set( NO_ERR );
780 // Can we proceed ?
781 if( chkStateForSQLFetch() != SQL_SUCCESS )
782 return( SQL_ERROR );
784 void *tuple;
785 tuple = fsqlStmt_->next();
787 if( ! tuple ) // IF Row not found.
789 rowsAffected_ = 0;
790 state_ = S6;
791 return( SQL_NO_DATA_FOUND );
793 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
795 rowsAffected_ = -1;
796 err_.set( ERROR_GENERAL );
797 return( SQL_ERROR );
799 else // IF Row found.
801 rowsAffected_ = 1;
803 // Iterate through all ard_;
804 CSqlOdbcDesc *appColDesc;
805 CSqlOdbcDescList::iterator ardIter;
806 ardIter = ard_.begin();
807 //Get the input parameter data
808 CSqlOdbcDesc *csqlColDesc;
809 CSqlOdbcDescList::iterator irdIter;
810 irdIter = ird_.begin();
812 DataType sourceType = typeUnknown,destType = typeUnknown;
813 int colNum=-1,sourceLength=-1,destLength=-1;
814 SQLINTEGER ind;
815 void* sourceData = NULL;
816 FieldInfo *info = new FieldInfo();
817 while( (ardIter != ard_.end()) || (irdIter != ird_.end()) )
819 appColDesc = *ardIter;
820 csqlColDesc = *irdIter;
822 colNum = appColDesc->col_ - 1;
823 fsqlStmt_->getProjFldInfo(colNum, info);
824 sourceType = info->type;
825 destType = getCSqlType(appColDesc->cType_);
826 sourceLength = info->length;
827 destLength = (int)appColDesc->length_;
829 if( sourceType != typeUnknown && destType != typeUnknown )
831 sourceData = fsqlStmt_->getFieldValuePtr( colNum );
832 if(sourceData == NULL)
834 if (appColDesc->indPtr_ != NULL)
835 *((SQLINTEGER *)(appColDesc->indPtr_))=SQL_NULL_DATA;
837 else
839 /*if( sourceType == csqlSqlTvarBinary)
840 sourceLength=resultSet_->getDataLength(colNum); */
841 if (sourceType == typeString ) // CSQL TODO - handle varchar also
843 sourceLength=(int)(strlen((char *) sourceData ));
844 if(appColDesc->indPtr_ != NULL)
845 *((SQLINTEGER *)(appColDesc->indPtr_))=copyToOdbc(appColDesc->dataPtr_,destLength,
846 sourceData,sourceLength, sourceType);
847 else
848 copyToOdbc(appColDesc->dataPtr_,destLength,sourceData,
849 sourceLength, sourceType);
851 else
853 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
854 if(appColDesc->indPtr_ != NULL)
855 *((SQLINTEGER *)(appColDesc->indPtr_))=
856 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
857 else
858 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
861 // CSQL TODO - handle varstring, binary, varbinary
862 if( sourceType == typeString && sourceLength > destLength )
863 err_.set( ERROR_DATATRUNC );
866 ardIter++;
867 irdIter++;
869 state_ = S6;
871 if(err_.csqlErrCode == ERROR_DATATRUNC)
872 return (SQL_SUCCESS_WITH_INFO);
874 return( SQL_SUCCESS );
877 SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle)
879 // Is Stmt valid ?
880 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
881 return( SQL_INVALID_HANDLE );
883 return( ((CSqlOdbcStmt*) StatementHandle)->SQLCloseCursor() );
886 SQLRETURN CSqlOdbcStmt::SQLCloseCursor()
888 // Start with NO_ERR
889 err_.set( NO_ERR );
891 // Can we proceed ?
892 if( chkStateForSQLCloseCursor() != SQL_SUCCESS )
893 return( SQL_ERROR );
895 // Close the cursor
896 fsqlStmt_->close();
897 state_ = S3;
898 return( SQL_SUCCESS );
901 SQLRETURN SQLSetCursorName(
902 SQLHSTMT StatementHandle,
903 SQLCHAR *CursorName,
904 SQLSMALLINT NameLength)
906 // Is Stmt valid ?
907 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
908 return( SQL_INVALID_HANDLE );
910 return( ((CSqlOdbcStmt*) StatementHandle)->SQLSetCursorName( CursorName, NameLength ) );
913 SQLRETURN CSqlOdbcStmt::SQLSetCursorName(
914 SQLCHAR *cursorName,
915 SQLSMALLINT nameLength)
917 // Start with NO_ERR
918 err_.set( NO_ERR );
920 // Can we proceed ?
921 if( chkStateForSQLSetCursorName() != SQL_SUCCESS )
922 return( SQL_ERROR );
924 // Invalid Stmt Length.
925 if( nameLength < 0 && nameLength != SQL_NTS )
927 err_.set( ERROR_INVARGVAL );
928 return( SQL_ERROR );
931 // Validate Parameters
932 if( cursorName == 0 || cursorName[0] == '\0' || strlen( (char*) cursorName ) > SQL_MAX_CURSOR_NAME_LEN ||
933 nameLength > SQL_MAX_CURSOR_NAME_LEN )
935 err_.set( ERROR_CURNAME );
936 return( SQL_ERROR );
939 // Check for duplicate Name
940 std::vector<CSqlOdbcStmt*>::iterator iter;
941 iter = parentDbc_->stmtList_.begin();
942 while( iter != parentDbc_->stmtList_.end() )
944 if( *iter != this )
946 if( strcmp( (char*) cursorName, (char*) (*iter)->cursorName_ ) == 0 )
948 err_.set( ERROR_DUP_CURNAME );
949 return( SQL_ERROR );
952 iter++;
955 // Copy name
956 strcpy( (char*) cursorName_, (char*) cursorName );
958 return( SQL_SUCCESS );
961 SQLRETURN SQLGetCursorName(
962 SQLHSTMT StatementHandle,
963 SQLCHAR *CursorName,
964 SQLSMALLINT BufferLength,
965 SQLSMALLINT *NameLength)
967 // Is Stmt valid ?
968 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
969 return( SQL_INVALID_HANDLE );
971 return( ((CSqlOdbcStmt*) StatementHandle)->SQLGetCursorName( CursorName, BufferLength, NameLength ) );
973 SQLRETURN CSqlOdbcStmt::SQLGetCursorName(
974 SQLCHAR *cursorName,
975 SQLSMALLINT bufferLength,
976 SQLSMALLINT *nameLength)
978 // Can we proceed ?
979 if( chkStateForSQLGetCursorName() != SQL_SUCCESS )
980 return( SQL_ERROR );
982 if( cursorName_[0] == '\0' )
984 err_.set( ERROR_NOCURNAME );
985 return( SQL_ERROR );
988 // Copy
989 *nameLength = (short)strlen( (char*) cursorName_ );
990 if( *nameLength > bufferLength ) *nameLength = bufferLength;
991 strncpy( (char*) cursorName, (char*) cursorName_, *nameLength );
992 cursorName[ *nameLength ] = '\0';
994 // Did truncate ?
995 if( bufferLength < strlen( (char*) cursorName_ ) )
997 err_.set( ERROR_DATATRUNC );
998 return( SQL_SUCCESS_WITH_INFO );
1001 return( SQL_SUCCESS );
1004 SQLRETURN SQLNumResultCols(
1005 SQLHSTMT StatementHandle, // IN
1006 SQLSMALLINT *ColumnCount) // OUT
1008 // Is Stmt valid ?
1009 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1010 return( SQL_INVALID_HANDLE );
1012 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumResultCols( ColumnCount ) );
1015 SQLRETURN CSqlOdbcStmt::SQLNumResultCols(
1016 SQLSMALLINT *columnCount) // OUT
1018 // Start with NO_ERR
1019 err_.set( NO_ERR );
1021 // Can we proceed ?
1022 if( chkStateForSQLNumResultCols() != SQL_SUCCESS )
1023 return( SQL_ERROR );
1025 // If DML
1026 if( fsqlStmt_->isSelect() == false )
1028 *columnCount=0;
1029 return (SQL_SUCCESS);
1032 // If Select
1033 SQLSMALLINT count = fsqlStmt_->noOfProjFields();
1034 if( count < 1 ) // Assume atleast one column is projected
1035 return( SQL_ERROR );
1037 // Fill Column Count
1038 *columnCount = count;
1040 return( SQL_SUCCESS );
1043 SQLRETURN SQL_API SQLRowCount(
1044 SQLHSTMT StatementHandle, // IN
1045 SQLINTEGER *RowCount) // OUT
1047 // Is Stmt valid ?
1048 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1049 return( SQL_INVALID_HANDLE );
1051 return( ((CSqlOdbcStmt*) StatementHandle)->SQLRowCount( RowCount ) );
1054 SQLRETURN CSqlOdbcStmt::SQLRowCount(
1055 SQLINTEGER *rowCount) // OUT
1056 { // TODO
1057 // Start with NO_ERR
1058 err_.set( NO_ERR );
1060 // Can we proceed ?
1061 if( chkStateForSQLRowCount() != SQL_SUCCESS )
1062 return( SQL_ERROR );
1064 if(rowCount == NULL)
1065 return SQL_SUCCESS;
1067 if( state_ == S4 ) // For INSERT/DELETE/UPDATE
1068 *rowCount = (SQLINTEGER) rowsAffected_;
1069 else if( state_ == S5 ) // For SELECT before SQLFetch()
1071 *rowCount = (SQLINTEGER) 0;
1072 // CSQL TODO - Think if you really want to do this!!!
1074 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1075 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1076 if( resultSet_->next() != csqlSqlErrNoTuple )
1077 *rowCount = (SQLINTEGER) 1;
1079 resultSet_->close();
1080 resultSet_->open(); */
1082 else if( state_ == S6 ) // For SELECT after SQLFetch();
1083 *rowCount = (SQLINTEGER) rowsAffected_;
1085 return( SQL_SUCCESS );
1088 SQLRETURN SQLDescribeCol(
1089 SQLHSTMT StatementHandle,
1090 SQLUSMALLINT ColumnNumber,
1091 SQLCHAR *ColumnName,
1092 SQLSMALLINT BufferLength,
1093 SQLSMALLINT *NameLength,
1094 SQLSMALLINT *DataType,
1095 SQLUINTEGER *ColumnSize,
1096 SQLSMALLINT *DecimalDigits,
1097 SQLSMALLINT *Nullable)
1099 // Is Stmt valid ?
1100 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1101 return( SQL_INVALID_HANDLE );
1103 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeCol( ColumnNumber, ColumnName, BufferLength,
1104 NameLength, DataType, ColumnSize, DecimalDigits, Nullable) );
1107 SQLRETURN CSqlOdbcStmt::SQLDescribeCol(
1108 SQLUSMALLINT columnNumber,
1109 SQLCHAR *columnName,
1110 SQLSMALLINT bufferLength,
1111 SQLSMALLINT *nameLength,
1112 SQLSMALLINT *dataType,
1113 SQLUINTEGER *columnSize,
1114 SQLSMALLINT *decimalDigits,
1115 SQLSMALLINT *nullable)
1117 int nameLen;
1118 int type;
1119 int colSize;
1120 int deciDigits;
1121 int isNullable;
1123 // Start with NO_ERR
1124 err_.set( NO_ERR );
1126 // Can we proceed ?
1127 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1128 return( SQL_ERROR );
1130 if( columnNumber < 1 )
1132 err_.set( ERROR_COLNUM );
1133 return( SQL_ERROR );
1136 // If DML
1137 if( fsqlStmt_->isSelect() == false )
1138 return( SQL_ERROR );
1140 // If SELECT
1141 if(columnNumber > fsqlStmt_->noOfProjFields())
1143 err_.set( ERROR_COLNUM );
1144 return( SQL_ERROR );
1146 if(columnName == NULL) {
1147 err_.set( ERROR_COLNUM );
1148 return( SQL_ERROR );
1150 FieldInfo *info = new FieldInfo();
1151 fsqlStmt_->getProjFldInfo(columnNumber, info);
1152 strncpy( (char*)columnName, (char*)info->fldName, bufferLength );
1153 if(nameLength != NULL)
1154 *nameLength=(short)strlen((const char*)info->fldName); // HARDCODED - TO DO, need support for n/w layer & sql layer
1155 if(dataType != NULL)
1156 *dataType = (SQLSMALLINT) getSQLType(info->type); // Need to convert from SQL<->ODBC - TO DO
1157 if(columnSize != NULL)
1159 *columnSize = (SQLUINTEGER) info->length;
1160 SQLSMALLINT sqlType=getSQLType(info->type);
1161 if(sqlType == SQL_CHAR )
1162 *columnSize = *columnSize -1;
1165 /*if(decimalDigits != NULL) // CSQL TODO
1166 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1167 if(nullable != NULL)
1168 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1169 if(strlen((char*)info->fldName) > bufferLength)
1171 err_.set( ERROR_DATATRUNC );
1172 return( SQL_SUCCESS_WITH_INFO );
1174 else
1175 return( SQL_SUCCESS );
1178 SQLRETURN SQLColAttributes(
1179 SQLHSTMT StatementHandle,
1180 SQLUSMALLINT ColumnNumber,
1181 SQLUSMALLINT FieldIdentifier,
1182 SQLPOINTER CharacterAttributePtr,
1183 SQLSMALLINT BufferLength,
1184 SQLSMALLINT *StringLengthPtr,
1185 SQLINTEGER *NumericAttributePtr)
1187 // Is Stmt valid ?
1188 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1189 return( SQL_INVALID_HANDLE );
1191 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1192 CharacterAttributePtr, BufferLength, StringLengthPtr, (SQLPOINTER)NumericAttributePtr) );
1195 SQLRETURN SQLColAttribute(
1196 SQLHSTMT StatementHandle,
1197 SQLUSMALLINT ColumnNumber,
1198 SQLUSMALLINT FieldIdentifier,
1199 SQLPOINTER CharacterAttributePtr,
1200 SQLSMALLINT BufferLength,
1201 SQLSMALLINT * StringLengthPtr,
1202 SQLPOINTER NumericAttributePtr)
1204 // Is Stmt valid ?
1205 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1206 return( SQL_INVALID_HANDLE );
1208 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1209 CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr) );
1212 SQLRETURN CSqlOdbcStmt::SQLColAttribute(
1213 SQLUSMALLINT columnNumber,
1214 SQLUSMALLINT fieldIdentifier,
1215 SQLPOINTER characterAttributePtr,
1216 SQLSMALLINT bufferLength,
1217 SQLSMALLINT * stringLengthPtr,
1218 SQLPOINTER numericAttributePtr)
1220 int nameLen;
1221 int type;
1222 int colSize;
1223 int deciDigits;
1224 int isNullable;
1226 // Start with NO_ERR
1227 err_.set( NO_ERR );
1229 // Can we proceed ?
1230 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1231 return( SQL_ERROR );
1233 if( columnNumber < 1 )
1235 err_.set( ERROR_COLNUM );
1236 return( SQL_ERROR );
1238 // If DML
1239 if( fsqlStmt_->isSelect() == false )
1240 return( SQL_ERROR );
1242 FieldInfo *info = new FieldInfo();
1243 fsqlStmt_->getProjFldInfo(columnNumber, info);
1245 // If SELECT
1246 if(columnNumber > fsqlStmt_->noOfProjFields())
1248 err_.set( ERROR_COLNUM );
1249 return( SQL_ERROR );
1251 switch(fieldIdentifier)
1253 case SQL_DESC_NAME:
1254 case SQL_COLUMN_NAME:
1255 if(characterAttributePtr != NULL)
1257 strncpy( (char*)characterAttributePtr, (char*)info->fldName, bufferLength);
1258 if(stringLengthPtr != NULL)
1259 *stringLengthPtr=(short)strlen((char*)info->fldName);
1261 break;
1262 case SQL_DESC_COUNT:
1263 case SQL_COLUMN_COUNT:
1264 if(numericAttributePtr != NULL)
1265 *(SQLINTEGER*)numericAttributePtr=fsqlStmt_->noOfProjFields();
1266 break;
1267 case SQL_DESC_TYPE:
1268 case SQL_COLUMN_TYPE:
1269 if(numericAttributePtr != NULL)
1270 *(SQLINTEGER *)numericAttributePtr=getSQLType(info->type);
1271 break;
1272 case SQL_DESC_LENGTH:
1273 case SQL_COLUMN_LENGTH:
1274 if(numericAttributePtr != NULL)
1276 SQLSMALLINT sqlType=getSQLType(info->type);
1277 *(SQLINTEGER *)numericAttributePtr=(SQLUINTEGER) info->length;
1278 if(sqlType == SQL_CHAR)
1279 *(SQLINTEGER *)numericAttributePtr=*(SQLINTEGER *)numericAttributePtr -1;
1281 break;
1282 case SQL_DESC_PRECISION:
1283 case SQL_COLUMN_PRECISION:
1284 /*if(numericAttributePtr != NULL) // CSQL TODO
1285 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1286 break;
1287 case SQL_DESC_SCALE:
1288 case SQL_COLUMN_SCALE:
1289 /*if(numericAttributePtr != NULL) // CSQL TODO
1290 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1291 break;
1292 case SQL_DESC_NULLABLE:
1293 case SQL_COLUMN_NULLABLE:
1294 /*if(numericAttributePtr != NULL) // CSQL TODO
1295 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1296 break;
1297 case SQL_DESC_UNSIGNED:
1298 if(numericAttributePtr != NULL)
1300 SQLSMALLINT sqlType=getSQLType(info->type);
1301 if((sqlType != SQL_TIME) && (sqlType != SQL_DATE) && (sqlType != SQL_TIMESTAMP)
1302 && (sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR) && (sqlType != SQL_BINARY)
1303 && (sqlType != SQL_VARBINARY) && (sqlType != SQL_BIT))
1304 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1305 else
1306 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1308 break;
1309 case SQL_DESC_FIXED_PREC_SCALE:
1310 if(numericAttributePtr != NULL)
1311 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1312 break;
1313 case SQL_DESC_TYPE_NAME:
1314 if(characterAttributePtr != NULL)
1316 SQLSMALLINT sqlType=getSQLType(info->type);
1317 strncpy((char*)characterAttributePtr,(char *)(getSQLTypeName(sqlType)),bufferLength);
1318 if(stringLengthPtr != NULL)
1319 *stringLengthPtr=(int)strlen((char *)getSQLTypeName(sqlType));
1321 break;
1322 case SQL_DESC_UPDATABLE:
1323 if(numericAttributePtr != NULL)
1324 *(SQLINTEGER*)numericAttributePtr=SQL_ATTR_READWRITE_UNKNOWN;
1325 break;
1326 case SQL_DESC_AUTO_UNIQUE_VALUE:
1327 if(numericAttributePtr != NULL)
1328 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1329 break;
1330 case SQL_DESC_CASE_SENSITIVE:
1331 if(numericAttributePtr != NULL)
1333 SQLSMALLINT sqlType=getSQLType(info->type);
1334 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1335 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1336 else
1337 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1339 break;
1340 case SQL_DESC_SEARCHABLE:
1341 if(numericAttributePtr != NULL)
1343 SQLSMALLINT sqlType=getSQLType(info->type);
1344 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1345 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_BASIC;
1346 else
1347 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_SEARCHABLE;
1349 break;
1350 default:
1351 break;
1353 if(stringLengthPtr != NULL)
1355 if(*stringLengthPtr > bufferLength)
1357 err_.set( ERROR_DATATRUNC );
1358 return( SQL_SUCCESS_WITH_INFO );
1361 return( SQL_SUCCESS );
1364 SQLRETURN SQLNumParams(
1365 SQLHSTMT StatementHandle,
1366 SQLSMALLINT * ParameterCountPtr)
1368 // Is Stmt valid ?
1369 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1370 return( SQL_INVALID_HANDLE );
1372 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumParams(ParameterCountPtr) );
1375 SQLRETURN CSqlOdbcStmt::SQLNumParams(
1376 SQLSMALLINT * ParameterCount)
1378 // Start with NO_ERR
1379 err_.set( NO_ERR );
1381 // Can we proceed ?
1382 if( chkStateForSQLNumParams() != SQL_SUCCESS )
1383 return( SQL_ERROR );
1384 if(ParameterCount == NULL)
1385 return (SQL_ERROR);
1386 *ParameterCount=fsqlStmt_->noOfParamFields();
1388 return SQL_SUCCESS;
1391 SQLRETURN SQLDescribeParam(
1392 SQLHSTMT StatementHandle,
1393 SQLUSMALLINT ParameterNumber,
1394 SQLSMALLINT * DataTypePtr,
1395 SQLUINTEGER * ParameterSizePtr,
1396 SQLSMALLINT * DecimalDigitsPtr,
1397 SQLSMALLINT * NullablePtr)
1399 // Is Stmt valid ?
1400 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1401 return( SQL_INVALID_HANDLE );
1403 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeParam(ParameterNumber,DataTypePtr,
1404 ParameterSizePtr,DecimalDigitsPtr,NullablePtr ) );
1406 SQLRETURN CSqlOdbcStmt::SQLDescribeParam(
1407 SQLUSMALLINT paramNumber,
1408 SQLSMALLINT * dataType,
1409 SQLUINTEGER * paramSize,
1410 SQLSMALLINT * decimalDigits,
1411 SQLSMALLINT * isNullable)
1414 // Start with NO_ERR
1415 err_.set( NO_ERR );
1417 // Can we proceed ?
1418 if( chkStateForSQLDescribeParam() != SQL_SUCCESS )
1419 return( SQL_ERROR );
1421 if( paramNumber < 1 )
1423 err_.set( ERROR_PARAMNUM);
1424 return( SQL_ERROR );
1427 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1428 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1429 if(paramNumber > fsqlStmt_->noOfParamFields())
1431 err_.set( ERROR_PARAMNUM );
1432 return( SQL_ERROR );
1435 FieldInfo *finfo = new FieldInfo();
1436 if( fsqlStmt_->getParamFldInfo( paramNumber-1, finfo ) != OK ) return( SQL_ERROR );
1437 if(dataType != NULL)
1438 *dataType = (SQLSMALLINT) getSQLType(finfo->type);
1439 if(paramSize != NULL)
1441 *paramSize = (SQLUINTEGER) finfo->length;
1442 SQLSMALLINT sqlType=getSQLType(finfo->type);
1443 if(sqlType == SQL_CHAR )
1444 *paramSize= *paramSize -1;
1446 /*if(decimalDigits != NULL) // CSQL TODO
1447 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1448 if(isNullable != NULL)
1449 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1450 return( SQL_SUCCESS );
1453 // Resets the Stmt to initial state. As if newly allocated.
1454 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1456 SQLFreeStmt( SQL_CLOSE );
1457 SQLFreeStmt( SQL_UNBIND );
1458 SQLFreeStmt( SQL_RESET_PARAMS );
1459 if (fsqlStmt_) fsqlStmt_->free();
1460 delete fsqlStmt_;
1461 fsqlStmt_ = NULL;
1462 isPrepared_ = false;
1463 state_ = S1;