plugged the leaks
[csql.git] / src / odbc / odbcStmt.cxx
blob9d5f80956935c0a084c4de9b93da13bbe68886a9
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 fsqlStmt_( NULL )
21 //HACK::
22 //fetchMode_(SQL_FETCH_SINGLE_TUPLE)
24 cursorName_[0] = '\0';
27 SQLRETURN SQLAllocStmt(
28 SQLHDBC ConnectionHandle,
29 SQLHSTMT *StatementHandle)
31 return( CSqlOdbcStmt::SQLAllocHandle( ConnectionHandle, StatementHandle ) );
34 SQLRETURN CSqlOdbcStmt::SQLAllocHandle(
35 SQLHANDLE inputHandle, // IN
36 SQLHANDLE *outputHandle ) // OUT
38 CSqlOdbcDbc *inputDbc = (CSqlOdbcDbc*) inputHandle;
40 // Is Dbc valid ?
41 if( isValidHandle( inputDbc, SQL_HANDLE_DBC ) != SQL_SUCCESS )
42 return( SQL_INVALID_HANDLE );
44 // Is Dbc connected ?
45 if( inputDbc->state_ < C4 )
47 globalError.set( ERROR_CONNOTOPEN );
48 globalError.printStr( SQL_OV_ODBC3 );
49 return( SQL_ERROR );
52 // Allocate Statement object.
53 *outputHandle = (SQLHANDLE*) new CSqlOdbcStmt;
54 if( *outputHandle == NULL )
56 globalError.set( ERROR_MEMALLOC );
57 globalError.printStr( SQL_OV_ODBC3 );
58 return( SQL_ERROR );
61 // Initialize relation b/w Stmt and Dbc
62 inputDbc->stmtList_.insert( inputDbc->stmtList_.begin(), (CSqlOdbcStmt*) *outputHandle );
63 inputDbc->stmtHdlList_.append(outputHandle);
64 if( inputDbc->state_ <= C4 )
65 inputDbc->state_ = C5;
66 ((CSqlOdbcStmt*) *outputHandle)->parentDbc_ = inputDbc;
67 //CSqlOdbcError::printDbg("proxy:stmt:setConnection");
68 //((CSqlOdbcStmt*) *outputHandle)->fsqlStmt_->setConnection( inputDbc->fsqlConn_ );
70 return( SQL_SUCCESS );
73 SQLRETURN CSqlOdbcStmt::SQLFreeHandle(
74 SQLHANDLE inputHandle) // IN
76 CSqlOdbcStmt *inputStmt = (CSqlOdbcStmt*) inputHandle;
78 // Is Stmt valid ?
79 if( isValidHandle( inputStmt, SQL_HANDLE_STMT ) != SQL_SUCCESS )
80 return( SQL_INVALID_HANDLE );
82 // Can we proceed ?
83 if( inputStmt->chkStateForSQLFreeHandle() != SQL_SUCCESS )
84 return( SQL_ERROR );
86 // Free resultset
87 inputStmt->resetStmt();
89 // Remove Stmt from Parent Dbc.
90 std::vector<CSqlOdbcStmt*>::iterator iter;
91 iter = inputStmt->parentDbc_->stmtList_.begin();
92 while( iter != inputStmt->parentDbc_->stmtList_.end() )
94 if( *iter == inputStmt )
96 inputStmt->parentDbc_->stmtList_.erase( iter );
97 break;
99 iter++;
101 // Set Dbc state_ = no statement.
102 if( inputStmt->parentDbc_->stmtList_.size() == 0 )
103 inputStmt->parentDbc_->state_ = C4;
105 inputStmt->handleType_ = -1; // Make object invalid.
106 SQLHANDLE *elem;
107 ListIterator it = inputStmt->parentDbc_->stmtHdlList_.getIterator();
108 while (it.hasElement()) {
109 elem = (SQLHANDLE *) it.nextElement();
110 if(*elem == inputStmt) *elem = NULL;
112 inputStmt->parentDbc_->stmtHdlList_.remove(elem);
113 delete inputStmt; // Delete Stmt.
114 return( SQL_SUCCESS );
117 SQLRETURN SQLFreeStmt(
118 SQLHSTMT StatementHandle, // IN
119 SQLUSMALLINT Option) // IN
121 // Is Stmt valid ?
122 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
123 return( SQL_INVALID_HANDLE );
125 // Free Handle
126 if( Option == SQL_DROP )
127 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle ) );
129 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFreeStmt( Option ) );
132 SQLRETURN CSqlOdbcStmt::SQLFreeStmt(
133 SQLUSMALLINT option)
135 // Start with NO_ERR
136 err_.set( NO_ERR );
138 // Can we proceed
139 if( chkStateForSQLFreeStmt() != SQL_SUCCESS )
140 return( SQL_ERROR );
141 if (!fsqlStmt_) return (SQL_SUCCESS);
142 switch( option )
144 case SQL_CLOSE: // // Free resultset
145 // if( fsqlStmt_->isSelect() == true ) // CSQL
146 // {
147 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
148 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
149 // if( resultSet_ && resultSet_->isOpen() == true )
150 // {
151 // resultSet_->close();
152 // }
153 // }
155 // cursor states
156 if( isPrepared_ )
158 if( fsqlStmt_->isSelect() == true ) // CSQL
159 state_ = S3; // With Cursor
160 else
161 state_ = S2; // Without Cursor
163 else
165 ard_.freeAllDesc();
166 apd_.freeAllDesc();
167 ipd_.freeAllDesc();
168 ird_.freeAllDesc();
169 fsqlStmt_->free(); // CSQL
170 state_ = S1;
173 break;
175 case SQL_UNBIND: ard_.freeAllDesc();
176 ird_.freeAllDesc();
177 break;
179 case SQL_RESET_PARAMS: apd_.freeAllDesc();
180 ipd_.freeAllDesc();
181 //isParamBound_ = false;
182 break;
184 default: err_.set( ERROR_OPTRANGE );
185 return( SQL_ERROR );
187 return( SQL_SUCCESS );
190 SQLRETURN SQLBindCol(
191 SQLHSTMT StatementHandle,
192 SQLUSMALLINT ColumnNumber,
193 SQLSMALLINT TargetType,
194 SQLPOINTER TargetValue,
195 SQLINTEGER BufferLength,
196 SQLINTEGER *StrLen_or_Ind)
198 // Is Stmt valid ?
199 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
200 return( SQL_INVALID_HANDLE );
202 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindCol( ColumnNumber,
203 TargetType, TargetValue, BufferLength, StrLen_or_Ind ) );
206 SQLRETURN CSqlOdbcStmt::SQLBindCol(
207 SQLUSMALLINT columnNumber,
208 SQLSMALLINT targetType,
209 SQLPOINTER targetValue,
210 SQLINTEGER bufferLength,
211 SQLINTEGER *ind)
213 CSqlOdbcDesc *bindDesc = 0;
214 CSqlOdbcDesc *inputDesc = 0;
215 SQLRETURN found = SQL_ERROR;
217 // Start with NO_ERR
218 err_.set( NO_ERR );
220 // Can we proceed ?
221 if( chkStateForSQLBindCol() != SQL_SUCCESS )
222 return( SQL_ERROR );
224 // Invalid Buffer Length.
225 switch( targetType )
227 // switch is in order to support more types.
228 case SQL_C_CHAR:
229 if( bufferLength < 0 && bufferLength != SQL_NTS )
231 err_.set( ERROR_BUFLEN );
232 return( SQL_ERROR );
234 break;
235 case SQL_C_BINARY:
236 if( bufferLength < 0 && bufferLength != SQL_NTS )
238 err_.set( ERROR_BUFLEN );
239 return( SQL_ERROR );
241 break;
244 // Invalid Column Number
245 if( columnNumber < 1 )
247 err_.set( ERROR_COLNUM );
248 return( SQL_ERROR );
251 // Get the Descriptor if already exists
252 found = ard_.getDescWithColNum( columnNumber , &bindDesc );
254 // UNBIND
255 if( targetValue == 0 )
257 if( found != SQL_SUCCESS )
259 err_.set( ERROR_COLNUM );
260 return( SQL_ERROR );
262 ard_.delDesc( bindDesc ); // UNBIND
264 return( SQL_SUCCESS );
267 // Validate target Type, Value and Column no.
268 if( targetValue == 0 || isValidCType( targetType ) != SQL_SUCCESS )
270 err_.set( ERROR_INVBUFTYPE );
271 return( SQL_ERROR );
274 // Add new descriptor
275 if( found != SQL_SUCCESS )
277 bindDesc = new CSqlOdbcDesc();
278 ard_.insert( ard_.begin(), bindDesc );
281 // Initialize Descriptor.
282 bindDesc->col_ = columnNumber;
283 bindDesc->cType_ = targetType;
284 bindDesc->dataPtr_ = targetValue;
285 bindDesc->length_ = (SQLUINTEGER) bufferLength;
286 bindDesc->indPtr_ = (SQLPOINTER) ind;
288 found = ird_.getDescWithColNum( columnNumber , &inputDesc );
290 // Add new descriptor
291 if( found != SQL_SUCCESS )
293 inputDesc = new CSqlOdbcDesc();
294 ird_.insert(ird_.begin(),inputDesc);
297 //Get Field Information from CSQL
298 FieldInfo *info = new FieldInfo();
299 fsqlStmt_->getProjFldInfo(columnNumber, info);
300 // Initialize input Descriptor.
301 //DataType sourceType = getCSqlType( targetType );
302 inputDesc->col_ = columnNumber;
303 inputDesc->cType_ = info->type;
304 getInputBuffer(&inputDesc->dataPtr_ ,info->type,(SQLUINTEGER) bufferLength);
305 inputDesc->length_ = info->length;
306 inputDesc->indPtr_ = (SQLPOINTER) ind;
307 delete info;
308 return( SQL_SUCCESS );
311 SQLRETURN SQLSetParam(
312 SQLHSTMT StatementHandle,
313 SQLUSMALLINT ParameterNumber,
314 SQLSMALLINT ValueType,
315 SQLSMALLINT ParameterType,
316 SQLUINTEGER LengthPrecision,
317 SQLSMALLINT ParameterScale,
318 SQLPOINTER ParameterValue,
319 SQLINTEGER *StrLen_or_Ind)
321 return( SQLBindParameter( StatementHandle, ParameterNumber,
322 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
323 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
326 SQLRETURN SQLBindParam(
327 SQLHSTMT StatementHandle,
328 SQLUSMALLINT ParameterNumber,
329 SQLSMALLINT ValueType,
330 SQLSMALLINT ParameterType,
331 SQLUINTEGER LengthPrecision,
332 SQLSMALLINT ParameterScale,
333 SQLPOINTER ParameterValue,
334 SQLINTEGER *StrLen_or_Ind)
336 return( SQLBindParameter( StatementHandle, ParameterNumber,
337 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
338 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
341 SQLRETURN SQLBindParameter(
342 SQLHSTMT StatementHandle,
343 SQLUSMALLINT ParameterNumber,
344 SQLSMALLINT InputOutputType,
345 SQLSMALLINT ValueType,
346 SQLSMALLINT ParameterType,
347 SQLUINTEGER LengthPrecision,
348 SQLSMALLINT ParameterScale,
349 SQLPOINTER ParameterValue,
350 SQLINTEGER BufferLength,
351 SQLINTEGER *StrLen_or_Ind)
353 // Is Stmt valid ?
354 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
355 return( SQL_INVALID_HANDLE );
357 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindParameter( ParameterNumber,
358 InputOutputType, ValueType,
359 ParameterType, LengthPrecision,
360 ParameterScale, ParameterValue,
361 BufferLength, StrLen_or_Ind ) );
364 SQLRETURN CSqlOdbcStmt::SQLBindParameter(
365 SQLUSMALLINT parameterNumber,
366 SQLSMALLINT inputOutputType,
367 SQLSMALLINT valueType,
368 SQLSMALLINT parameterType,
369 SQLUINTEGER lengthPrecision,
370 SQLSMALLINT parameterScale,
371 SQLPOINTER parameterValue,
372 SQLINTEGER bufferLength,
373 SQLINTEGER *ind)
375 CSqlOdbcDesc *bindDesc = 0;
376 CSqlOdbcDesc *inputDesc =0;
377 SQLRETURN found;
379 // Start with NO_ERR
380 err_.set( NO_ERR );
382 // Can we proceed ?
383 if( chkStateForSQLBindParameter() != SQL_SUCCESS )
384 return( SQL_ERROR );
386 // Invalid Buffer Length.
387 switch( valueType )
389 // switch is in order to support more types.
390 case SQL_C_CHAR:
391 if( bufferLength < 0 && bufferLength != SQL_NTS )
393 err_.set( ERROR_BUFLEN );
394 return( SQL_ERROR );
396 break;
397 case SQL_C_BINARY:
398 if( bufferLength < 0 && bufferLength != SQL_NTS )
400 err_.set( ERROR_BUFLEN );
401 return( SQL_ERROR );
403 break;
406 // Validate parameters
407 switch( inputOutputType )
409 case SQL_PARAM_INPUT:
410 case SQL_PARAM_OUTPUT:
411 case SQL_PARAM_INPUT_OUTPUT: break;
412 default: err_.set( ERROR_INV_PARAMTYPE );
413 return( SQL_ERROR );
415 if( isValidCType( valueType ) != SQL_SUCCESS ||
416 isValidSQLType( parameterType ) != SQL_SUCCESS )
418 err_.set( ERROR_INVBUFTYPE );
419 return( SQL_ERROR );
421 if( parameterNumber < 1 )
423 err_.set( ERROR_COLNUM );
424 return( SQL_ERROR );
427 // Get the Descriptor if already exists
428 found = apd_.getDescWithColNum( parameterNumber , &bindDesc );
429 if( found != SQL_SUCCESS )
431 bindDesc = new CSqlOdbcDesc();
432 apd_.insert( apd_.end(), bindDesc );
433 // Initialize Descriptor.
434 bindDesc->col_ = parameterNumber;
435 bindDesc->paramType_ = inputOutputType;
436 bindDesc->cType_ = valueType;
437 bindDesc->sqlType_ = parameterType;
438 bindDesc->dataPtr_ = parameterValue;
439 bindDesc->length_ = (SQLUINTEGER) bufferLength;
440 bindDesc->precision_ =(short) lengthPrecision;
441 bindDesc->scale_ = parameterScale;
442 bindDesc->indPtr_ = (SQLPOINTER) ind;
444 found = ipd_.getDescWithColNum (parameterNumber, &inputDesc);
445 if( found != SQL_SUCCESS )
447 inputDesc = new CSqlOdbcDesc();
448 ipd_.insert(ipd_.end(),inputDesc);
449 //Initialize inputDescriptor
450 DataType destType=getCSqlType(valueType);
451 inputDesc->col_ = parameterNumber;
452 inputDesc->paramType_ = inputOutputType;
453 inputDesc->cType_ = valueType;
454 inputDesc->sqlType_ = parameterType;
455 inputDesc->dataPtr_= NULL;
456 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
457 inputDesc->length_ = (SQLUINTEGER) bufferLength;
458 inputDesc->precision_ = (short)lengthPrecision;
459 inputDesc->scale_ = parameterScale;
460 inputDesc->indPtr_ = (SQLPOINTER) ind;
462 //isParamBound_ = false;
463 return( SQL_SUCCESS );
466 SQLRETURN SQLPrepare(
467 SQLHSTMT StatementHandle, // IN
468 SQLCHAR *StatementText, // IN
469 SQLINTEGER TextLength) // IN
471 // Is Stmt valid ?
472 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
473 return( SQL_INVALID_HANDLE );
475 // Prepare
476 return( ((CSqlOdbcStmt*) StatementHandle)->SQLPrepare( StatementText, TextLength ) );
479 SQLRETURN CSqlOdbcStmt::SQLPrepare(
480 SQLCHAR *statementText, // IN
481 SQLINTEGER textLength) // IN
483 // Start with NO_ERR
484 err_.set( NO_ERR );
486 // Can we proceed ?
487 if( chkStateForSQLPrepare() != SQL_SUCCESS )
488 return( SQL_ERROR );
490 // Invalid Buffer Length.
491 if( textLength < 0 && textLength != SQL_NTS )
493 err_.set( ERROR_BUFLEN );
494 return( SQL_ERROR );
497 // If Stmt is already prepared.
498 if( state_ >= S2 ) {
499 resetStmt();
502 if (parentDbc_->mode_ ==1)
503 fsqlStmt_ = SqlFactory::createStatement(CSql);
504 else if (parentDbc_->mode_ ==2)
505 fsqlStmt_ = SqlFactory::createStatement(CSqlGateway);
506 else if (parentDbc_->mode_ ==3)
507 fsqlStmt_ = SqlFactory::createStatement(CSqlAdapter);
508 fsqlStmt_->setConnection( parentDbc_->fsqlConn_ );
510 // Prepare
511 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
512 DbRetVal rv=OK;
513 if( (rv=fsqlStmt_->prepare( (char*) statementText ))!= OK) // CSQL
515 state_ = S1;
516 err_.set(ERROR_GENERAL);
517 /*switch(rv)
519 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
520 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
521 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
522 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
523 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
524 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
525 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
526 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
527 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
528 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
529 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
530 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
531 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
532 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
533 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
534 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
535 default:
537 return( SQL_ERROR );
539 if( fsqlStmt_->isSelect() != true ) // CSQL
540 state_ = S2; // With cursor
541 else
542 state_ = S3; // Without cursor
544 //parentDbc_->state_ = C6;
545 isPrepared_ = true;
546 return( SQL_SUCCESS );
549 SQLRETURN SQLExecute(SQLHSTMT StatementHandle) // IN
551 // Is Stmt valid ?
552 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
553 return( SQL_INVALID_HANDLE );
555 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecute() );
558 SQLRETURN CSqlOdbcStmt::SQLExecute() // TODO
560 // Start with NO_ERR
561 err_.set( NO_ERR );
563 // Can we proceed ?
564 if( chkStateForSQLExecute() != SQL_SUCCESS )
565 return( SQL_ERROR );
567 if( fsqlStmt_->noOfParamFields() > 0 )
570 // Iterate through all apd_;
571 CSqlOdbcDesc *appParamDesc;
572 CSqlOdbcDescList::iterator apdIter;
573 apdIter = apd_.begin();
574 CSqlOdbcDesc *csqlParamDesc;
575 CSqlOdbcDescList::iterator ipdIter;
576 ipdIter = ipd_.begin();
578 //Get the source and the destination type
579 DataType sourceType = typeUnknown,destType = typeUnknown;
580 int paramNum=1,sourceLength=-1,destLength=-1;
581 bool nullFlag=false;
583 while( (apdIter != apd_.end()) || (ipdIter != ipd_.end()) )
585 appParamDesc=*apdIter;
586 csqlParamDesc=*ipdIter;
587 if((paramNum) <= fsqlStmt_->noOfParamFields())
589 FieldInfo *finfo = new FieldInfo();
590 if( fsqlStmt_->getParamFldInfo(paramNum, finfo ) != OK ) return( SQL_ERROR );
591 sourceType=getCSqlType(appParamDesc->cType_);
592 destType=finfo->type;
593 sourceLength=(int)appParamDesc->length_;
594 destLength=finfo->length;
595 delete finfo;
596 if(sourceType != typeUnknown && destType != typeUnknown)
598 //Check if NULL is inserted
599 if((appParamDesc->indPtr_ != NULL ) && (*(SQLINTEGER *)appParamDesc->indPtr_) == SQL_NULL_DATA)
601 nullFlag=true;
602 //finfo->isNull = true; CSQL TODO - need to understand how to set null
604 else
606 //Only if both types are not the same, then we need to copy it onto intermediate buffer
607 //Else no need
608 if( (sourceType == typeString || sourceType == typeBinary) && (sourceLength <= 0))
610 if((appParamDesc->indPtr_!= NULL) && *(SQLINTEGER *)appParamDesc->indPtr_ > 0)
611 sourceLength=(int)(*(SQLINTEGER *)appParamDesc->indPtr_);
612 else if (appParamDesc->precision_ > 0)
613 sourceLength=appParamDesc->precision_;
614 else
616 err_.set( ERROR_BUFLEN );
617 return SQL_ERROR;
620 if(destType == typeString) //|| destType == typeVarString)
622 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
623 destLength=sourceLength;
625 if(sourceType == destType)
626 //|| (sourceType == typeString && destType == typeVarString)
627 //|| (sourceType == typeBinary && destType == typeVarBinary))
629 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength,destType); // CSQL TODO
630 } else
632 getInputBuffer(&csqlParamDesc->dataPtr_ ,sourceType,sourceLength);
633 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength, sourceType);
634 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
638 else
640 err_.set(ERROR_GENERAL);
641 return SQL_ERROR;
644 paramNum++;
645 apdIter++;
646 ipdIter++;
651 // Get the result
652 int rowsAffected=0;
653 DbRetVal rv = fsqlStmt_->execute( rowsAffected );
654 if( rowsAffected < 0 )
656 if( isPrepared_ ) state_ = S2; else resetStmt();
657 err_.set( ERROR_GENERAL );
658 /*switch(rv)
660 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
661 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
662 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
663 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
664 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
665 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
666 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
667 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
668 default:
669 err_.set( ERROR_GENERAL );break;
670 } */
671 return( SQL_ERROR );
674 // Set Stmt State
675 if( fsqlStmt_->isSelect() == true )
677 rowsAffected_ = -1;
678 state_ = S5;
680 else
682 rowsAffected_ = rowsAffected;
683 state_ = S4;
686 // Set Dbc State to Transaction Mode.
687 parentDbc_->state_ = C6;
689 // AutoCommit Mode
690 if( parentDbc_->autoCommit_ == SQL_AUTOCOMMIT_ON )
691 parentDbc_->SQLEndTran( SQL_COMMIT );
693 return( SQL_SUCCESS );
696 SQLRETURN SQLExecDirect(
697 SQLHSTMT StatementHandle,
698 SQLCHAR *StatementText,
699 SQLINTEGER TextLength)
701 // Is Stmt valid ?
702 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
703 return( SQL_INVALID_HANDLE );
705 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecDirect( StatementText, TextLength ) );
708 SQLRETURN CSqlOdbcStmt::SQLExecDirect(
709 SQLCHAR *statementText,
710 SQLINTEGER textLength)
712 SQLRETURN ret;
714 // Can we proceed ?
715 if( chkStateForSQLExecDirect() != SQL_SUCCESS )
716 return( SQL_ERROR );
718 // SQLExecDirect = SQLPrepare + SQLExecute.
719 if( SQLPrepare( statementText, textLength ) != SQL_SUCCESS )
720 return( SQL_ERROR );
722 ret = SQLExecute();
723 isPrepared_ = false; // Set Stmt as non-prepared stmt.
725 if( ret != SQL_SUCCESS )
726 return( SQL_ERROR );
728 return( SQL_SUCCESS );
731 SQLRETURN SQLSetStmtOption(
732 SQLHSTMT StatementHandle,
733 SQLUSMALLINT Option,
734 SQLUINTEGER Value)
736 return (SQLSetStmtAttr(StatementHandle, Option, (SQLPOINTER) Value, 0));
739 SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
740 SQLINTEGER Attribute, SQLPOINTER Value,
741 SQLINTEGER StringLength)
743 return (((CSqlOdbcStmt*)StatementHandle)->SQLSetStmtAttr(Attribute, Value,StringLength));
746 SQLRETURN CSqlOdbcStmt::SQLSetStmtAttr(
747 SQLINTEGER Attribute,
748 SQLPOINTER Value,
749 SQLINTEGER stringLength)
751 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
752 //HACK
753 /*switch(Attribute)
755 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
756 //Default is SQL_FETCH_SINGLE_TUPLE.
757 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
758 //is sent from server to client in a single packet whatever be
759 //the packet size. If a tuple size is 50 and network packet size
760 //is 500, the remaining 450 bytes can also be used to send more
761 //in a single packet so that in the next SQLFetch call one network
762 //packet transfer overhead is reduced.
763 case SQL_FETCH_MODE:
764 if(state_ <= S5)
765 //state_ > S5 means Fetch has already started on this statement.
766 fetchMode_ = (SQLINTEGER)Value;
767 else
768 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
769 break;
770 default:
771 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
773 return (SQL_SUCCESS);
776 SQLRETURN SQLFetch(SQLHSTMT StatementHandle)
778 // Is Stmt valid ?
779 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
780 return( SQL_INVALID_HANDLE );
782 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFetch() );
785 SQLRETURN CSqlOdbcStmt::SQLFetch()
787 // Start with NO_ERR
788 err_.set( NO_ERR );
790 // Can we proceed ?
791 if( chkStateForSQLFetch() != SQL_SUCCESS )
792 return( SQL_ERROR );
794 void *tuple;
795 tuple = fsqlStmt_->next();
797 if( ! tuple ) // IF Row not found.
799 rowsAffected_ = 0;
800 state_ = S6;
801 return( SQL_NO_DATA_FOUND );
803 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
805 rowsAffected_ = -1;
806 err_.set( ERROR_GENERAL );
807 return( SQL_ERROR );
809 else // IF Row found.
811 rowsAffected_ = 1;
813 // Iterate through all ard_;
814 CSqlOdbcDesc *appColDesc;
815 CSqlOdbcDescList::iterator ardIter;
816 ardIter = ard_.begin();
817 //Get the input parameter data
818 CSqlOdbcDesc *csqlColDesc;
819 CSqlOdbcDescList::iterator irdIter;
820 irdIter = ird_.begin();
822 DataType sourceType = typeUnknown,destType = typeUnknown;
823 int colNum=-1,sourceLength=-1,destLength=-1;
824 SQLINTEGER ind;
825 void* sourceData = NULL;
826 //FieldInfo *info = new FieldInfo();
827 while( (ardIter != ard_.end()) || (irdIter != ird_.end()) )
829 appColDesc = *ardIter;
830 csqlColDesc = *irdIter;
832 colNum = appColDesc->col_ - 1;
833 // fsqlStmt_->getProjFldInfo(colNum+1, info);
834 sourceType = (DataType)csqlColDesc->cType_;
835 destType = getCSqlType(appColDesc->cType_);
836 sourceLength = (int)csqlColDesc->length_;
837 destLength = (int)appColDesc->length_;
839 if( sourceType != typeUnknown && destType != typeUnknown )
841 sourceData = fsqlStmt_->getFieldValuePtr( colNum );
842 if(fsqlStmt_->isFldNull(appColDesc->col_) || sourceData == NULL )
844 if (appColDesc->indPtr_ != NULL)
845 *((SQLINTEGER *)(appColDesc->indPtr_))=SQL_NULL_DATA;
847 else
849 /*if( sourceType == csqlSqlTvarBinary)
850 sourceLength=resultSet_->getDataLength(colNum); */
851 if (sourceType == typeString ) // CSQL TODO - handle varchar also
853 sourceLength=(int)(strlen((char *) sourceData ));
854 if(appColDesc->indPtr_ != NULL)
855 *((SQLINTEGER *)(appColDesc->indPtr_))=copyToOdbc(appColDesc->dataPtr_,destLength,
856 sourceData,sourceLength, sourceType);
857 else
858 copyToOdbc(appColDesc->dataPtr_,destLength,sourceData,
859 sourceLength, sourceType);
861 else
863 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
864 if(appColDesc->indPtr_ != NULL){
865 *((SQLINTEGER *)(appColDesc->indPtr_))=
866 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
868 else
869 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
872 // CSQL TODO - handle varstring, binary, varbinary
873 if( sourceType == typeString && sourceLength > destLength )
874 err_.set( ERROR_DATATRUNC );
877 ardIter++;
878 irdIter++;
880 state_ = S6;
882 if(err_.csqlErrCode == ERROR_DATATRUNC)
883 return (SQL_SUCCESS_WITH_INFO);
885 return( SQL_SUCCESS );
888 SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle)
890 // Is Stmt valid ?
891 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
892 return( SQL_INVALID_HANDLE );
894 return( ((CSqlOdbcStmt*) StatementHandle)->SQLCloseCursor() );
897 SQLRETURN CSqlOdbcStmt::SQLCloseCursor()
899 // Start with NO_ERR
900 err_.set( NO_ERR );
902 // Can we proceed ?
903 if( chkStateForSQLCloseCursor() != SQL_SUCCESS )
904 return( SQL_ERROR );
906 // Close the cursor
907 fsqlStmt_->close();
908 state_ = S3;
909 return( SQL_SUCCESS );
912 SQLRETURN SQLSetCursorName(
913 SQLHSTMT StatementHandle,
914 SQLCHAR *CursorName,
915 SQLSMALLINT NameLength)
917 // Is Stmt valid ?
918 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
919 return( SQL_INVALID_HANDLE );
921 return( ((CSqlOdbcStmt*) StatementHandle)->SQLSetCursorName( CursorName, NameLength ) );
924 SQLRETURN CSqlOdbcStmt::SQLSetCursorName(
925 SQLCHAR *cursorName,
926 SQLSMALLINT nameLength)
928 // Start with NO_ERR
929 err_.set( NO_ERR );
931 // Can we proceed ?
932 if( chkStateForSQLSetCursorName() != SQL_SUCCESS )
933 return( SQL_ERROR );
935 // Invalid Stmt Length.
936 if( nameLength < 0 && nameLength != SQL_NTS )
938 err_.set( ERROR_INVARGVAL );
939 return( SQL_ERROR );
942 // Validate Parameters
943 if( cursorName == 0 || cursorName[0] == '\0' || strlen( (char*) cursorName ) > SQL_MAX_CURSOR_NAME_LEN ||
944 nameLength > SQL_MAX_CURSOR_NAME_LEN )
946 err_.set( ERROR_CURNAME );
947 return( SQL_ERROR );
950 // Check for duplicate Name
951 std::vector<CSqlOdbcStmt*>::iterator iter;
952 iter = parentDbc_->stmtList_.begin();
953 while( iter != parentDbc_->stmtList_.end() )
955 if( *iter != this )
957 if( strcmp( (char*) cursorName, (char*) (*iter)->cursorName_ ) == 0 )
959 err_.set( ERROR_DUP_CURNAME );
960 return( SQL_ERROR );
963 iter++;
966 // Copy name
967 strcpy( (char*) cursorName_, (char*) cursorName );
969 return( SQL_SUCCESS );
972 SQLRETURN SQLGetCursorName(
973 SQLHSTMT StatementHandle,
974 SQLCHAR *CursorName,
975 SQLSMALLINT BufferLength,
976 SQLSMALLINT *NameLength)
978 // Is Stmt valid ?
979 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
980 return( SQL_INVALID_HANDLE );
982 return( ((CSqlOdbcStmt*) StatementHandle)->SQLGetCursorName( CursorName, BufferLength, NameLength ) );
984 SQLRETURN CSqlOdbcStmt::SQLGetCursorName(
985 SQLCHAR *cursorName,
986 SQLSMALLINT bufferLength,
987 SQLSMALLINT *nameLength)
989 // Can we proceed ?
990 if( chkStateForSQLGetCursorName() != SQL_SUCCESS )
991 return( SQL_ERROR );
993 if( cursorName_[0] == '\0' )
995 err_.set( ERROR_NOCURNAME );
996 return( SQL_ERROR );
999 // Copy
1000 *nameLength = (short)strlen( (char*) cursorName_ );
1001 if( *nameLength > bufferLength ) *nameLength = bufferLength;
1002 strncpy( (char*) cursorName, (char*) cursorName_, *nameLength );
1003 cursorName[ *nameLength ] = '\0';
1005 // Did truncate ?
1006 if( bufferLength < strlen( (char*) cursorName_ ) )
1008 err_.set( ERROR_DATATRUNC );
1009 return( SQL_SUCCESS_WITH_INFO );
1012 return( SQL_SUCCESS );
1015 SQLRETURN SQLNumResultCols(
1016 SQLHSTMT StatementHandle, // IN
1017 SQLSMALLINT *ColumnCount) // OUT
1019 // Is Stmt valid ?
1020 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1021 return( SQL_INVALID_HANDLE );
1023 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumResultCols( ColumnCount ) );
1026 SQLRETURN CSqlOdbcStmt::SQLNumResultCols(
1027 SQLSMALLINT *columnCount) // OUT
1029 // Start with NO_ERR
1030 err_.set( NO_ERR );
1032 // Can we proceed ?
1033 if( chkStateForSQLNumResultCols() != SQL_SUCCESS )
1034 return( SQL_ERROR );
1036 // If DML
1037 if( fsqlStmt_->isSelect() == false )
1039 *columnCount=0;
1040 return (SQL_SUCCESS);
1043 // If Select
1044 SQLSMALLINT count = fsqlStmt_->noOfProjFields();
1045 if( count < 1 ) // Assume atleast one column is projected
1046 return( SQL_ERROR );
1048 // Fill Column Count
1049 *columnCount = count;
1051 return( SQL_SUCCESS );
1054 SQLRETURN SQL_API SQLRowCount(
1055 SQLHSTMT StatementHandle, // IN
1056 SQLINTEGER *RowCount) // OUT
1058 // Is Stmt valid ?
1059 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1060 return( SQL_INVALID_HANDLE );
1062 return( ((CSqlOdbcStmt*) StatementHandle)->SQLRowCount( RowCount ) );
1065 SQLRETURN CSqlOdbcStmt::SQLRowCount(
1066 SQLINTEGER *rowCount) // OUT
1067 { // TODO
1068 // Start with NO_ERR
1069 err_.set( NO_ERR );
1071 // Can we proceed ?
1072 if( chkStateForSQLRowCount() != SQL_SUCCESS )
1073 return( SQL_ERROR );
1075 if(rowCount == NULL)
1076 return SQL_SUCCESS;
1078 if( state_ == S4 ) // For INSERT/DELETE/UPDATE
1079 *rowCount = (SQLINTEGER) rowsAffected_;
1080 else if( state_ == S5 ) // For SELECT before SQLFetch()
1082 *rowCount = (SQLINTEGER) 0;
1083 // CSQL TODO - Think if you really want to do this!!!
1085 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1086 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1087 if( resultSet_->next() != csqlSqlErrNoTuple )
1088 *rowCount = (SQLINTEGER) 1;
1090 resultSet_->close();
1091 resultSet_->open(); */
1093 else if( state_ == S6 ) // For SELECT after SQLFetch();
1094 *rowCount = (SQLINTEGER) rowsAffected_;
1096 return( SQL_SUCCESS );
1099 SQLRETURN SQLDescribeCol(
1100 SQLHSTMT StatementHandle,
1101 SQLUSMALLINT ColumnNumber,
1102 SQLCHAR *ColumnName,
1103 SQLSMALLINT BufferLength,
1104 SQLSMALLINT *NameLength,
1105 SQLSMALLINT *DataType,
1106 SQLUINTEGER *ColumnSize,
1107 SQLSMALLINT *DecimalDigits,
1108 SQLSMALLINT *Nullable)
1110 // Is Stmt valid ?
1111 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1112 return( SQL_INVALID_HANDLE );
1114 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeCol( ColumnNumber, ColumnName, BufferLength,
1115 NameLength, DataType, ColumnSize, DecimalDigits, Nullable) );
1118 SQLRETURN CSqlOdbcStmt::SQLDescribeCol(
1119 SQLUSMALLINT columnNumber,
1120 SQLCHAR *columnName,
1121 SQLSMALLINT bufferLength,
1122 SQLSMALLINT *nameLength,
1123 SQLSMALLINT *dataType,
1124 SQLUINTEGER *columnSize,
1125 SQLSMALLINT *decimalDigits,
1126 SQLSMALLINT *nullable)
1128 int nameLen;
1129 int type;
1130 int colSize;
1131 int deciDigits;
1132 int isNullable;
1134 // Start with NO_ERR
1135 err_.set( NO_ERR );
1137 // Can we proceed ?
1138 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1139 return( SQL_ERROR );
1141 if( columnNumber < 1 )
1143 err_.set( ERROR_COLNUM );
1144 return( SQL_ERROR );
1147 // If DML
1148 if( fsqlStmt_->isSelect() == false )
1149 return( SQL_ERROR );
1151 // If SELECT
1152 if(columnNumber > fsqlStmt_->noOfProjFields())
1154 err_.set( ERROR_COLNUM );
1155 return( SQL_ERROR );
1157 if(columnName == NULL) {
1158 err_.set( ERROR_COLNUM );
1159 return( SQL_ERROR );
1161 FieldInfo *info = new FieldInfo();
1162 fsqlStmt_->getProjFldInfo(columnNumber+1, info);
1163 strncpy( (char*)columnName, (char*)info->fldName, bufferLength );
1164 if(nameLength != NULL)
1165 *nameLength=(short)strlen((const char*)info->fldName); // HARDCODED - TO DO, need support for n/w layer & sql layer
1166 if(dataType != NULL)
1167 *dataType = (SQLSMALLINT) getSQLType(info->type); // Need to convert from SQL<->ODBC - TO DO
1168 if(columnSize != NULL)
1170 *columnSize = (SQLUINTEGER) info->length;
1171 SQLSMALLINT sqlType=getSQLType(info->type);
1172 if(sqlType == SQL_CHAR )
1173 *columnSize = *columnSize -1;
1176 /*if(decimalDigits != NULL) // CSQL TODO
1177 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1178 if(nullable != NULL)
1179 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1180 if(strlen((char*)info->fldName) > bufferLength)
1182 err_.set( ERROR_DATATRUNC );
1183 return( SQL_SUCCESS_WITH_INFO );
1185 else
1186 return( SQL_SUCCESS );
1189 SQLRETURN SQLColAttributes(
1190 SQLHSTMT StatementHandle,
1191 SQLUSMALLINT ColumnNumber,
1192 SQLUSMALLINT FieldIdentifier,
1193 SQLPOINTER CharacterAttributePtr,
1194 SQLSMALLINT BufferLength,
1195 SQLSMALLINT *StringLengthPtr,
1196 SQLINTEGER *NumericAttributePtr)
1198 // Is Stmt valid ?
1199 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1200 return( SQL_INVALID_HANDLE );
1202 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1203 CharacterAttributePtr, BufferLength, StringLengthPtr, (SQLPOINTER)NumericAttributePtr) );
1206 SQLRETURN SQLColAttribute(
1207 SQLHSTMT StatementHandle,
1208 SQLUSMALLINT ColumnNumber,
1209 SQLUSMALLINT FieldIdentifier,
1210 SQLPOINTER CharacterAttributePtr,
1211 SQLSMALLINT BufferLength,
1212 SQLSMALLINT * StringLengthPtr,
1213 SQLPOINTER NumericAttributePtr)
1215 // Is Stmt valid ?
1216 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1217 return( SQL_INVALID_HANDLE );
1219 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1220 CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr) );
1223 SQLRETURN CSqlOdbcStmt::SQLColAttribute(
1224 SQLUSMALLINT columnNumber,
1225 SQLUSMALLINT fieldIdentifier,
1226 SQLPOINTER characterAttributePtr,
1227 SQLSMALLINT bufferLength,
1228 SQLSMALLINT * stringLengthPtr,
1229 SQLPOINTER numericAttributePtr)
1231 int nameLen;
1232 int type;
1233 int colSize;
1234 int deciDigits;
1235 int isNullable;
1237 // Start with NO_ERR
1238 err_.set( NO_ERR );
1240 // Can we proceed ?
1241 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1242 return( SQL_ERROR );
1244 if( columnNumber < 1 )
1246 err_.set( ERROR_COLNUM );
1247 return( SQL_ERROR );
1249 // If DML
1250 if( fsqlStmt_->isSelect() == false )
1251 return( SQL_ERROR );
1253 FieldInfo *info = new FieldInfo();
1254 fsqlStmt_->getProjFldInfo(columnNumber+1, info);
1256 // If SELECT
1257 if(columnNumber > fsqlStmt_->noOfProjFields())
1259 err_.set( ERROR_COLNUM );
1260 return( SQL_ERROR );
1262 switch(fieldIdentifier)
1264 case SQL_DESC_NAME:
1265 case SQL_COLUMN_NAME:
1266 if(characterAttributePtr != NULL)
1268 strncpy( (char*)characterAttributePtr, (char*)info->fldName, bufferLength);
1269 if(stringLengthPtr != NULL)
1270 *stringLengthPtr=(short)strlen((char*)info->fldName);
1272 break;
1273 case SQL_DESC_COUNT:
1274 case SQL_COLUMN_COUNT:
1275 if(numericAttributePtr != NULL)
1276 *(SQLINTEGER*)numericAttributePtr=fsqlStmt_->noOfProjFields();
1277 break;
1278 case SQL_DESC_TYPE:
1279 case SQL_COLUMN_TYPE:
1280 if(numericAttributePtr != NULL)
1281 *(SQLINTEGER *)numericAttributePtr=getSQLType(info->type);
1282 break;
1283 case SQL_DESC_LENGTH:
1284 case SQL_COLUMN_LENGTH:
1285 if(numericAttributePtr != NULL)
1287 SQLSMALLINT sqlType=getSQLType(info->type);
1288 *(SQLINTEGER *)numericAttributePtr=(SQLUINTEGER) info->length;
1289 if(sqlType == SQL_CHAR)
1290 *(SQLINTEGER *)numericAttributePtr=*(SQLINTEGER *)numericAttributePtr -1;
1292 break;
1293 case SQL_DESC_PRECISION:
1294 case SQL_COLUMN_PRECISION:
1295 /*if(numericAttributePtr != NULL) // CSQL TODO
1296 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1297 break;
1298 case SQL_DESC_SCALE:
1299 case SQL_COLUMN_SCALE:
1300 /*if(numericAttributePtr != NULL) // CSQL TODO
1301 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1302 break;
1303 case SQL_DESC_NULLABLE:
1304 case SQL_COLUMN_NULLABLE:
1305 /*if(numericAttributePtr != NULL) // CSQL TODO
1306 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1307 break;
1308 case SQL_DESC_UNSIGNED:
1309 if(numericAttributePtr != NULL)
1311 SQLSMALLINT sqlType=getSQLType(info->type);
1312 if((sqlType != SQL_TIME) && (sqlType != SQL_DATE) && (sqlType != SQL_TIMESTAMP)
1313 && (sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR) && (sqlType != SQL_BINARY)
1314 && (sqlType != SQL_VARBINARY) && (sqlType != SQL_BIT))
1315 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1316 else
1317 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1319 break;
1320 case SQL_DESC_FIXED_PREC_SCALE:
1321 if(numericAttributePtr != NULL)
1322 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1323 break;
1324 case SQL_DESC_TYPE_NAME:
1325 if(characterAttributePtr != NULL)
1327 SQLSMALLINT sqlType=getSQLType(info->type);
1328 strncpy((char*)characterAttributePtr,(char *)(getSQLTypeName(sqlType)),bufferLength);
1329 if(stringLengthPtr != NULL)
1330 *stringLengthPtr=(int)strlen((char *)getSQLTypeName(sqlType));
1332 break;
1333 case SQL_DESC_UPDATABLE:
1334 if(numericAttributePtr != NULL)
1335 *(SQLINTEGER*)numericAttributePtr=SQL_ATTR_READWRITE_UNKNOWN;
1336 break;
1337 case SQL_DESC_AUTO_UNIQUE_VALUE:
1338 if(numericAttributePtr != NULL)
1339 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1340 break;
1341 case SQL_DESC_CASE_SENSITIVE:
1342 if(numericAttributePtr != NULL)
1344 SQLSMALLINT sqlType=getSQLType(info->type);
1345 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1346 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1347 else
1348 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1350 break;
1351 case SQL_DESC_SEARCHABLE:
1352 if(numericAttributePtr != NULL)
1354 SQLSMALLINT sqlType=getSQLType(info->type);
1355 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1356 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_BASIC;
1357 else
1358 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_SEARCHABLE;
1360 break;
1361 default:
1362 break;
1364 if(stringLengthPtr != NULL)
1366 if(*stringLengthPtr > bufferLength)
1368 err_.set( ERROR_DATATRUNC );
1369 return( SQL_SUCCESS_WITH_INFO );
1372 return( SQL_SUCCESS );
1375 SQLRETURN SQLNumParams(
1376 SQLHSTMT StatementHandle,
1377 SQLSMALLINT * ParameterCountPtr)
1379 // Is Stmt valid ?
1380 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1381 return( SQL_INVALID_HANDLE );
1383 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumParams(ParameterCountPtr) );
1386 SQLRETURN CSqlOdbcStmt::SQLNumParams(
1387 SQLSMALLINT * ParameterCount)
1389 // Start with NO_ERR
1390 err_.set( NO_ERR );
1392 // Can we proceed ?
1393 if( chkStateForSQLNumParams() != SQL_SUCCESS )
1394 return( SQL_ERROR );
1395 if(ParameterCount == NULL)
1396 return (SQL_ERROR);
1397 *ParameterCount=fsqlStmt_->noOfParamFields();
1399 return SQL_SUCCESS;
1402 SQLRETURN SQLDescribeParam(
1403 SQLHSTMT StatementHandle,
1404 SQLUSMALLINT ParameterNumber,
1405 SQLSMALLINT * DataTypePtr,
1406 SQLUINTEGER * ParameterSizePtr,
1407 SQLSMALLINT * DecimalDigitsPtr,
1408 SQLSMALLINT * NullablePtr)
1410 // Is Stmt valid ?
1411 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1412 return( SQL_INVALID_HANDLE );
1414 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeParam(ParameterNumber,DataTypePtr,
1415 ParameterSizePtr,DecimalDigitsPtr,NullablePtr ) );
1417 SQLRETURN CSqlOdbcStmt::SQLDescribeParam(
1418 SQLUSMALLINT paramNumber,
1419 SQLSMALLINT * dataType,
1420 SQLUINTEGER * paramSize,
1421 SQLSMALLINT * decimalDigits,
1422 SQLSMALLINT * isNullable)
1425 // Start with NO_ERR
1426 err_.set( NO_ERR );
1428 // Can we proceed ?
1429 if( chkStateForSQLDescribeParam() != SQL_SUCCESS )
1430 return( SQL_ERROR );
1432 if( paramNumber < 1 )
1434 err_.set( ERROR_PARAMNUM);
1435 return( SQL_ERROR );
1438 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1439 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1440 if(paramNumber > fsqlStmt_->noOfParamFields())
1442 err_.set( ERROR_PARAMNUM );
1443 return( SQL_ERROR );
1446 FieldInfo *finfo = new FieldInfo();
1447 if( fsqlStmt_->getParamFldInfo( paramNumber-1, finfo ) != OK ) return( SQL_ERROR );
1448 if(dataType != NULL)
1449 *dataType = (SQLSMALLINT) getSQLType(finfo->type);
1450 if(paramSize != NULL)
1452 *paramSize = (SQLUINTEGER) finfo->length;
1453 SQLSMALLINT sqlType=getSQLType(finfo->type);
1454 if(sqlType == SQL_CHAR )
1455 *paramSize= *paramSize -1;
1457 /*if(decimalDigits != NULL) // CSQL TODO
1458 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1459 if(isNullable != NULL)
1460 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1461 return( SQL_SUCCESS );
1464 // Resets the Stmt to initial state. As if newly allocated.
1465 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1467 SQLFreeStmt( SQL_CLOSE );
1468 SQLFreeStmt( SQL_UNBIND );
1469 SQLFreeStmt( SQL_RESET_PARAMS );
1470 if (fsqlStmt_) { fsqlStmt_->free(); delete fsqlStmt_; fsqlStmt_ = NULL; }
1471 isPrepared_ = false;
1472 state_ = S1;