plugged the memory leaks
[csql.git] / src / odbc / odbcStmt.cxx
blob794326ad0332a1590a42f13ebbd12e4c5e9e1d48
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 if( inputDbc->state_ <= C4 )
64 inputDbc->state_ = C5;
65 ((CSqlOdbcStmt*) *outputHandle)->parentDbc_ = inputDbc;
66 //CSqlOdbcError::printDbg("proxy:stmt:setConnection");
67 //((CSqlOdbcStmt*) *outputHandle)->fsqlStmt_->setConnection( inputDbc->fsqlConn_ );
69 return( SQL_SUCCESS );
72 SQLRETURN CSqlOdbcStmt::SQLFreeHandle(
73 SQLHANDLE inputHandle) // IN
75 CSqlOdbcStmt *inputStmt = (CSqlOdbcStmt*) inputHandle;
77 // Is Stmt valid ?
78 if( isValidHandle( inputStmt, SQL_HANDLE_STMT ) != SQL_SUCCESS )
79 return( SQL_INVALID_HANDLE );
81 // Can we proceed ?
82 if( inputStmt->chkStateForSQLFreeHandle() != SQL_SUCCESS )
83 return( SQL_ERROR );
85 // Free resultset
86 inputStmt->resetStmt();
88 // Remove Stmt from Parent Dbc.
89 std::vector<CSqlOdbcStmt*>::iterator iter;
90 iter = inputStmt->parentDbc_->stmtList_.begin();
91 while( iter != inputStmt->parentDbc_->stmtList_.end() )
93 if( *iter == inputStmt )
95 inputStmt->parentDbc_->stmtList_.erase( iter );
96 break;
98 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.
106 return( SQL_SUCCESS );
109 SQLRETURN SQLFreeStmt(
110 SQLHSTMT StatementHandle, // IN
111 SQLUSMALLINT Option) // IN
113 // Is Stmt valid ?
114 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
115 return( SQL_INVALID_HANDLE );
117 // Free Handle
118 if( Option == SQL_DROP )
119 return( CSqlOdbcStmt::SQLFreeHandle( StatementHandle ) );
121 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFreeStmt( Option ) );
124 SQLRETURN CSqlOdbcStmt::SQLFreeStmt(
125 SQLUSMALLINT option)
127 // Start with NO_ERR
128 err_.set( NO_ERR );
130 // Can we proceed
131 if( chkStateForSQLFreeStmt() != SQL_SUCCESS )
132 return( SQL_ERROR );
133 if (!fsqlStmt_) return (SQL_SUCCESS);
134 switch( option )
136 case SQL_CLOSE: // // Free resultset
137 // if( fsqlStmt_->isSelect() == true ) // CSQL
138 // {
139 // //CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
140 // CSqlResultSet *resultSet_ = fsqlStmt_->getResultSet(); // CSQL
141 // if( resultSet_ && resultSet_->isOpen() == true )
142 // {
143 // resultSet_->close();
144 // }
145 // }
147 // cursor states
148 if( isPrepared_ )
150 if( fsqlStmt_->isSelect() == true ) // CSQL
151 state_ = S3; // With Cursor
152 else
153 state_ = S2; // Without Cursor
155 else
157 ard_.freeAllDesc();
158 apd_.freeAllDesc();
159 ipd_.freeAllDesc();
160 ird_.freeAllDesc();
161 fsqlStmt_->free(); // CSQL
162 state_ = S1;
165 break;
167 case SQL_UNBIND: ard_.freeAllDesc();
168 ird_.freeAllDesc();
169 break;
171 case SQL_RESET_PARAMS: apd_.freeAllDesc();
172 ipd_.freeAllDesc();
173 //isParamBound_ = false;
174 break;
176 default: err_.set( ERROR_OPTRANGE );
177 return( SQL_ERROR );
179 return( SQL_SUCCESS );
182 SQLRETURN SQLBindCol(
183 SQLHSTMT StatementHandle,
184 SQLUSMALLINT ColumnNumber,
185 SQLSMALLINT TargetType,
186 SQLPOINTER TargetValue,
187 SQLINTEGER BufferLength,
188 SQLINTEGER *StrLen_or_Ind)
190 // Is Stmt valid ?
191 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
192 return( SQL_INVALID_HANDLE );
194 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindCol( ColumnNumber,
195 TargetType, TargetValue, BufferLength, StrLen_or_Ind ) );
198 SQLRETURN CSqlOdbcStmt::SQLBindCol(
199 SQLUSMALLINT columnNumber,
200 SQLSMALLINT targetType,
201 SQLPOINTER targetValue,
202 SQLINTEGER bufferLength,
203 SQLINTEGER *ind)
205 CSqlOdbcDesc *bindDesc = 0;
206 CSqlOdbcDesc *inputDesc = 0;
207 SQLRETURN found = SQL_ERROR;
209 // Start with NO_ERR
210 err_.set( NO_ERR );
212 // Can we proceed ?
213 if( chkStateForSQLBindCol() != SQL_SUCCESS )
214 return( SQL_ERROR );
216 // Invalid Buffer Length.
217 switch( targetType )
219 // switch is in order to support more types.
220 case SQL_C_CHAR:
221 if( bufferLength < 0 && bufferLength != SQL_NTS )
223 err_.set( ERROR_BUFLEN );
224 return( SQL_ERROR );
226 break;
227 case SQL_C_BINARY:
228 if( bufferLength < 0 && bufferLength != SQL_NTS )
230 err_.set( ERROR_BUFLEN );
231 return( SQL_ERROR );
233 break;
236 // Invalid Column Number
237 if( columnNumber < 1 )
239 err_.set( ERROR_COLNUM );
240 return( SQL_ERROR );
243 // Get the Descriptor if already exists
244 found = ard_.getDescWithColNum( columnNumber , &bindDesc );
246 // UNBIND
247 if( targetValue == 0 )
249 if( found != SQL_SUCCESS )
251 err_.set( ERROR_COLNUM );
252 return( SQL_ERROR );
254 ard_.delDesc( bindDesc ); // UNBIND
256 return( SQL_SUCCESS );
259 // Validate target Type, Value and Column no.
260 if( targetValue == 0 || isValidCType( targetType ) != SQL_SUCCESS )
262 err_.set( ERROR_INVBUFTYPE );
263 return( SQL_ERROR );
266 // Add new descriptor
267 if( found != SQL_SUCCESS )
269 bindDesc = new CSqlOdbcDesc();
270 ard_.insert( ard_.begin(), bindDesc );
273 // Initialize Descriptor.
274 bindDesc->col_ = columnNumber;
275 bindDesc->cType_ = targetType;
276 bindDesc->dataPtr_ = targetValue;
277 bindDesc->length_ = (SQLUINTEGER) bufferLength;
278 bindDesc->indPtr_ = (SQLPOINTER) ind;
280 found = ird_.getDescWithColNum( columnNumber , &inputDesc );
282 // Add new descriptor
283 if( found != SQL_SUCCESS )
285 inputDesc = new CSqlOdbcDesc();
286 ird_.insert(ird_.begin(),inputDesc);
289 //Get Field Information from CSQL
290 FieldInfo *info = new FieldInfo();
291 fsqlStmt_->getProjFldInfo(columnNumber, info);
292 // Initialize input Descriptor.
293 //DataType sourceType = getCSqlType( targetType );
294 inputDesc->col_ = columnNumber;
295 inputDesc->cType_ = info->type;
296 getInputBuffer(&inputDesc->dataPtr_ ,info->type,(SQLUINTEGER) bufferLength);
297 inputDesc->length_ = info->length;
298 inputDesc->indPtr_ = (SQLPOINTER) ind;
299 delete info;
300 return( SQL_SUCCESS );
303 SQLRETURN SQLSetParam(
304 SQLHSTMT StatementHandle,
305 SQLUSMALLINT ParameterNumber,
306 SQLSMALLINT ValueType,
307 SQLSMALLINT ParameterType,
308 SQLUINTEGER LengthPrecision,
309 SQLSMALLINT ParameterScale,
310 SQLPOINTER ParameterValue,
311 SQLINTEGER *StrLen_or_Ind)
313 return( SQLBindParameter( StatementHandle, ParameterNumber,
314 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
315 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
318 SQLRETURN SQLBindParam(
319 SQLHSTMT StatementHandle,
320 SQLUSMALLINT ParameterNumber,
321 SQLSMALLINT ValueType,
322 SQLSMALLINT ParameterType,
323 SQLUINTEGER LengthPrecision,
324 SQLSMALLINT ParameterScale,
325 SQLPOINTER ParameterValue,
326 SQLINTEGER *StrLen_or_Ind)
328 return( SQLBindParameter( StatementHandle, ParameterNumber,
329 SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType, LengthPrecision,
330 ParameterScale, ParameterValue, 0, StrLen_or_Ind) );
333 SQLRETURN SQLBindParameter(
334 SQLHSTMT StatementHandle,
335 SQLUSMALLINT ParameterNumber,
336 SQLSMALLINT InputOutputType,
337 SQLSMALLINT ValueType,
338 SQLSMALLINT ParameterType,
339 SQLUINTEGER LengthPrecision,
340 SQLSMALLINT ParameterScale,
341 SQLPOINTER ParameterValue,
342 SQLINTEGER BufferLength,
343 SQLINTEGER *StrLen_or_Ind)
345 // Is Stmt valid ?
346 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
347 return( SQL_INVALID_HANDLE );
349 return( ((CSqlOdbcStmt*) StatementHandle)->SQLBindParameter( ParameterNumber,
350 InputOutputType, ValueType,
351 ParameterType, LengthPrecision,
352 ParameterScale, ParameterValue,
353 BufferLength, StrLen_or_Ind ) );
356 SQLRETURN CSqlOdbcStmt::SQLBindParameter(
357 SQLUSMALLINT parameterNumber,
358 SQLSMALLINT inputOutputType,
359 SQLSMALLINT valueType,
360 SQLSMALLINT parameterType,
361 SQLUINTEGER lengthPrecision,
362 SQLSMALLINT parameterScale,
363 SQLPOINTER parameterValue,
364 SQLINTEGER bufferLength,
365 SQLINTEGER *ind)
367 CSqlOdbcDesc *bindDesc = 0;
368 CSqlOdbcDesc *inputDesc =0;
369 SQLRETURN found;
371 // Start with NO_ERR
372 err_.set( NO_ERR );
374 // Can we proceed ?
375 if( chkStateForSQLBindParameter() != SQL_SUCCESS )
376 return( SQL_ERROR );
378 // Invalid Buffer Length.
379 switch( valueType )
381 // switch is in order to support more types.
382 case SQL_C_CHAR:
383 if( bufferLength < 0 && bufferLength != SQL_NTS )
385 err_.set( ERROR_BUFLEN );
386 return( SQL_ERROR );
388 break;
389 case SQL_C_BINARY:
390 if( bufferLength < 0 && bufferLength != SQL_NTS )
392 err_.set( ERROR_BUFLEN );
393 return( SQL_ERROR );
395 break;
398 // Validate parameters
399 switch( inputOutputType )
401 case SQL_PARAM_INPUT:
402 case SQL_PARAM_OUTPUT:
403 case SQL_PARAM_INPUT_OUTPUT: break;
404 default: err_.set( ERROR_INV_PARAMTYPE );
405 return( SQL_ERROR );
407 if( isValidCType( valueType ) != SQL_SUCCESS ||
408 isValidSQLType( parameterType ) != SQL_SUCCESS )
410 err_.set( ERROR_INVBUFTYPE );
411 return( SQL_ERROR );
413 if( parameterNumber < 1 )
415 err_.set( ERROR_COLNUM );
416 return( SQL_ERROR );
419 // Get the Descriptor if already exists
420 found = apd_.getDescWithColNum( parameterNumber , &bindDesc );
421 if( found != SQL_SUCCESS )
423 bindDesc = new CSqlOdbcDesc();
424 apd_.insert( apd_.end(), bindDesc );
425 // Initialize Descriptor.
426 bindDesc->col_ = parameterNumber;
427 bindDesc->paramType_ = inputOutputType;
428 bindDesc->cType_ = valueType;
429 bindDesc->sqlType_ = parameterType;
430 bindDesc->dataPtr_ = parameterValue;
431 bindDesc->length_ = (SQLUINTEGER) bufferLength;
432 bindDesc->precision_ =(short) lengthPrecision;
433 bindDesc->scale_ = parameterScale;
434 bindDesc->indPtr_ = (SQLPOINTER) ind;
436 found = ipd_.getDescWithColNum (parameterNumber, &inputDesc);
437 if( found != SQL_SUCCESS )
439 inputDesc = new CSqlOdbcDesc();
440 ipd_.insert(ipd_.end(),inputDesc);
441 //Initialize inputDescriptor
442 DataType destType=getCSqlType(valueType);
443 inputDesc->col_ = parameterNumber;
444 inputDesc->paramType_ = inputOutputType;
445 inputDesc->cType_ = valueType;
446 inputDesc->sqlType_ = parameterType;
447 inputDesc->dataPtr_= NULL;
448 //getInputBuffer(&inputDesc->dataPtr_,destType,(SQLUINTEGER)bufferLength);
449 inputDesc->length_ = (SQLUINTEGER) bufferLength;
450 inputDesc->precision_ = (short)lengthPrecision;
451 inputDesc->scale_ = parameterScale;
452 inputDesc->indPtr_ = (SQLPOINTER) ind;
454 //isParamBound_ = false;
455 return( SQL_SUCCESS );
458 SQLRETURN SQLPrepare(
459 SQLHSTMT StatementHandle, // IN
460 SQLCHAR *StatementText, // IN
461 SQLINTEGER TextLength) // IN
463 // Is Stmt valid ?
464 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
465 return( SQL_INVALID_HANDLE );
467 // Prepare
468 return( ((CSqlOdbcStmt*) StatementHandle)->SQLPrepare( StatementText, TextLength ) );
471 SQLRETURN CSqlOdbcStmt::SQLPrepare(
472 SQLCHAR *statementText, // IN
473 SQLINTEGER textLength) // IN
475 // Start with NO_ERR
476 err_.set( NO_ERR );
478 // Can we proceed ?
479 if( chkStateForSQLPrepare() != SQL_SUCCESS )
480 return( SQL_ERROR );
482 // Invalid Buffer Length.
483 if( textLength < 0 && textLength != SQL_NTS )
485 err_.set( ERROR_BUFLEN );
486 return( SQL_ERROR );
489 // If Stmt is already prepared.
490 if( state_ >= S2 ) {
491 resetStmt();
494 if (parentDbc_->mode_ ==1)
495 fsqlStmt_ = SqlFactory::createStatement(CSql);
496 else if (parentDbc_->mode_ ==2)
497 fsqlStmt_ = SqlFactory::createStatement(CSqlGateway);
498 else if (parentDbc_->mode_ ==3)
499 fsqlStmt_ = SqlFactory::createStatement(CSqlAdapter);
500 fsqlStmt_->setConnection( parentDbc_->fsqlConn_ );
502 // Prepare
503 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
504 DbRetVal rv=OK;
505 if( (rv=fsqlStmt_->prepare( (char*) statementText ))!= OK) // CSQL
507 state_ = S1;
508 err_.set(ERROR_GENERAL);
509 /*switch(rv)
511 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
512 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
513 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
514 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
515 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
516 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
517 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
518 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
519 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
520 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
521 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
522 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
523 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
524 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
525 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
526 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
527 default:
529 return( SQL_ERROR );
531 if( fsqlStmt_->isSelect() != true ) // CSQL
532 state_ = S2; // With cursor
533 else
534 state_ = S3; // Without cursor
536 //parentDbc_->state_ = C6;
537 isPrepared_ = true;
538 return( SQL_SUCCESS );
541 SQLRETURN SQLExecute(SQLHSTMT StatementHandle) // IN
543 // Is Stmt valid ?
544 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
545 return( SQL_INVALID_HANDLE );
547 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecute() );
550 SQLRETURN CSqlOdbcStmt::SQLExecute() // TODO
552 // Start with NO_ERR
553 err_.set( NO_ERR );
555 // Can we proceed ?
556 if( chkStateForSQLExecute() != SQL_SUCCESS )
557 return( SQL_ERROR );
559 if( fsqlStmt_->noOfParamFields() > 0 )
562 // Iterate through all apd_;
563 CSqlOdbcDesc *appParamDesc;
564 CSqlOdbcDescList::iterator apdIter;
565 apdIter = apd_.begin();
566 CSqlOdbcDesc *csqlParamDesc;
567 CSqlOdbcDescList::iterator ipdIter;
568 ipdIter = ipd_.begin();
570 //Get the source and the destination type
571 DataType sourceType = typeUnknown,destType = typeUnknown;
572 int paramNum=1,sourceLength=-1,destLength=-1;
573 bool nullFlag=false;
575 while( (apdIter != apd_.end()) || (ipdIter != ipd_.end()) )
577 appParamDesc=*apdIter;
578 csqlParamDesc=*ipdIter;
579 if((paramNum) <= fsqlStmt_->noOfParamFields())
581 FieldInfo *finfo = new FieldInfo();
582 if( fsqlStmt_->getParamFldInfo(paramNum, finfo ) != OK ) return( SQL_ERROR );
583 sourceType=getCSqlType(appParamDesc->cType_);
584 destType=finfo->type;
585 sourceLength=(int)appParamDesc->length_;
586 destLength=finfo->length;
587 delete finfo;
588 if(sourceType != typeUnknown && destType != typeUnknown)
590 //Check if NULL is inserted
591 if((appParamDesc->indPtr_ != NULL ) && (*(SQLINTEGER *)appParamDesc->indPtr_) == SQL_NULL_DATA)
593 nullFlag=true;
594 //finfo->isNull = true; CSQL TODO - need to understand how to set null
596 else
598 //Only if both types are not the same, then we need to copy it onto intermediate buffer
599 //Else no need
600 if( (sourceType == typeString || sourceType == typeBinary) && (sourceLength <= 0))
602 if((appParamDesc->indPtr_!= NULL) && *(SQLINTEGER *)appParamDesc->indPtr_ > 0)
603 sourceLength=(int)(*(SQLINTEGER *)appParamDesc->indPtr_);
604 else if (appParamDesc->precision_ > 0)
605 sourceLength=appParamDesc->precision_;
606 else
608 err_.set( ERROR_BUFLEN );
609 return SQL_ERROR;
612 if(destType == typeString) //|| destType == typeVarString)
614 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
615 destLength=sourceLength;
617 if(sourceType == destType)
618 //|| (sourceType == typeString && destType == typeVarString)
619 //|| (sourceType == typeBinary && destType == typeVarBinary))
621 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength,destType); // CSQL TODO
622 } else
624 getInputBuffer(&csqlParamDesc->dataPtr_ ,sourceType,sourceLength);
625 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength, sourceType);
626 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
630 else
632 err_.set(ERROR_GENERAL);
633 return SQL_ERROR;
636 paramNum++;
637 apdIter++;
638 ipdIter++;
643 // Get the result
644 int rowsAffected=0;
645 DbRetVal rv = fsqlStmt_->execute( rowsAffected );
646 if( rowsAffected < 0 )
648 if( isPrepared_ ) state_ = S2; else resetStmt();
649 err_.set( ERROR_GENERAL );
650 /*switch(rv)
652 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
653 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
654 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
655 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
656 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
657 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
658 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
659 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
660 default:
661 err_.set( ERROR_GENERAL );break;
662 } */
663 return( SQL_ERROR );
666 // Set Stmt State
667 if( fsqlStmt_->isSelect() == true )
669 rowsAffected_ = -1;
670 state_ = S5;
672 else
674 rowsAffected_ = rowsAffected;
675 state_ = S4;
678 // Set Dbc State to Transaction Mode.
679 parentDbc_->state_ = C6;
681 // AutoCommit Mode
682 if( parentDbc_->autoCommit_ == SQL_AUTOCOMMIT_ON )
683 parentDbc_->SQLEndTran( SQL_COMMIT );
685 return( SQL_SUCCESS );
688 SQLRETURN SQLExecDirect(
689 SQLHSTMT StatementHandle,
690 SQLCHAR *StatementText,
691 SQLINTEGER TextLength)
693 // Is Stmt valid ?
694 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
695 return( SQL_INVALID_HANDLE );
697 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecDirect( StatementText, TextLength ) );
700 SQLRETURN CSqlOdbcStmt::SQLExecDirect(
701 SQLCHAR *statementText,
702 SQLINTEGER textLength)
704 SQLRETURN ret;
706 // Can we proceed ?
707 if( chkStateForSQLExecDirect() != SQL_SUCCESS )
708 return( SQL_ERROR );
710 // SQLExecDirect = SQLPrepare + SQLExecute.
711 if( SQLPrepare( statementText, textLength ) != SQL_SUCCESS )
712 return( SQL_ERROR );
714 ret = SQLExecute();
715 isPrepared_ = false; // Set Stmt as non-prepared stmt.
717 if( ret != SQL_SUCCESS )
718 return( SQL_ERROR );
720 return( SQL_SUCCESS );
723 SQLRETURN SQLSetStmtOption(
724 SQLHSTMT StatementHandle,
725 SQLUSMALLINT Option,
726 SQLUINTEGER Value)
728 return (SQLSetStmtAttr(StatementHandle, Option, (SQLPOINTER) Value, 0));
731 SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
732 SQLINTEGER Attribute, SQLPOINTER Value,
733 SQLINTEGER StringLength)
735 return (((CSqlOdbcStmt*)StatementHandle)->SQLSetStmtAttr(Attribute, Value,StringLength));
738 SQLRETURN CSqlOdbcStmt::SQLSetStmtAttr(
739 SQLINTEGER Attribute,
740 SQLPOINTER Value,
741 SQLINTEGER stringLength)
743 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
744 //HACK
745 /*switch(Attribute)
747 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
748 //Default is SQL_FETCH_SINGLE_TUPLE.
749 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
750 //is sent from server to client in a single packet whatever be
751 //the packet size. If a tuple size is 50 and network packet size
752 //is 500, the remaining 450 bytes can also be used to send more
753 //in a single packet so that in the next SQLFetch call one network
754 //packet transfer overhead is reduced.
755 case SQL_FETCH_MODE:
756 if(state_ <= S5)
757 //state_ > S5 means Fetch has already started on this statement.
758 fetchMode_ = (SQLINTEGER)Value;
759 else
760 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
761 break;
762 default:
763 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
765 return (SQL_SUCCESS);
768 SQLRETURN SQLFetch(SQLHSTMT StatementHandle)
770 // Is Stmt valid ?
771 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
772 return( SQL_INVALID_HANDLE );
774 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFetch() );
777 SQLRETURN CSqlOdbcStmt::SQLFetch()
779 // Start with NO_ERR
780 err_.set( NO_ERR );
782 // Can we proceed ?
783 if( chkStateForSQLFetch() != SQL_SUCCESS )
784 return( SQL_ERROR );
786 void *tuple;
787 tuple = fsqlStmt_->next();
789 if( ! tuple ) // IF Row not found.
791 rowsAffected_ = 0;
792 state_ = S6;
793 return( SQL_NO_DATA_FOUND );
795 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
797 rowsAffected_ = -1;
798 err_.set( ERROR_GENERAL );
799 return( SQL_ERROR );
801 else // IF Row found.
803 rowsAffected_ = 1;
805 // Iterate through all ard_;
806 CSqlOdbcDesc *appColDesc;
807 CSqlOdbcDescList::iterator ardIter;
808 ardIter = ard_.begin();
809 //Get the input parameter data
810 CSqlOdbcDesc *csqlColDesc;
811 CSqlOdbcDescList::iterator irdIter;
812 irdIter = ird_.begin();
814 DataType sourceType = typeUnknown,destType = typeUnknown;
815 int colNum=-1,sourceLength=-1,destLength=-1;
816 SQLINTEGER ind;
817 void* sourceData = NULL;
818 //FieldInfo *info = new FieldInfo();
819 while( (ardIter != ard_.end()) || (irdIter != ird_.end()) )
821 appColDesc = *ardIter;
822 csqlColDesc = *irdIter;
824 colNum = appColDesc->col_ - 1;
825 // fsqlStmt_->getProjFldInfo(colNum+1, info);
826 sourceType = (DataType)csqlColDesc->cType_;
827 destType = getCSqlType(appColDesc->cType_);
828 sourceLength = (int)csqlColDesc->length_;
829 destLength = (int)appColDesc->length_;
831 if( sourceType != typeUnknown && destType != typeUnknown )
833 sourceData = fsqlStmt_->getFieldValuePtr( colNum );
834 if(fsqlStmt_->isFldNull(appColDesc->col_) || sourceData == NULL )
836 if (appColDesc->indPtr_ != NULL)
837 *((SQLINTEGER *)(appColDesc->indPtr_))=SQL_NULL_DATA;
839 else
841 /*if( sourceType == csqlSqlTvarBinary)
842 sourceLength=resultSet_->getDataLength(colNum); */
843 if (sourceType == typeString ) // CSQL TODO - handle varchar also
845 sourceLength=(int)(strlen((char *) sourceData ));
846 if(appColDesc->indPtr_ != NULL)
847 *((SQLINTEGER *)(appColDesc->indPtr_))=copyToOdbc(appColDesc->dataPtr_,destLength,
848 sourceData,sourceLength, sourceType);
849 else
850 copyToOdbc(appColDesc->dataPtr_,destLength,sourceData,
851 sourceLength, sourceType);
853 else
855 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
856 if(appColDesc->indPtr_ != NULL){
857 *((SQLINTEGER *)(appColDesc->indPtr_))=
858 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
860 else
861 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
864 // CSQL TODO - handle varstring, binary, varbinary
865 if( sourceType == typeString && sourceLength > destLength )
866 err_.set( ERROR_DATATRUNC );
869 ardIter++;
870 irdIter++;
872 state_ = S6;
874 if(err_.csqlErrCode == ERROR_DATATRUNC)
875 return (SQL_SUCCESS_WITH_INFO);
877 return( SQL_SUCCESS );
880 SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle)
882 // Is Stmt valid ?
883 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
884 return( SQL_INVALID_HANDLE );
886 return( ((CSqlOdbcStmt*) StatementHandle)->SQLCloseCursor() );
889 SQLRETURN CSqlOdbcStmt::SQLCloseCursor()
891 // Start with NO_ERR
892 err_.set( NO_ERR );
894 // Can we proceed ?
895 if( chkStateForSQLCloseCursor() != SQL_SUCCESS )
896 return( SQL_ERROR );
898 // Close the cursor
899 fsqlStmt_->close();
900 state_ = S3;
901 return( SQL_SUCCESS );
904 SQLRETURN SQLSetCursorName(
905 SQLHSTMT StatementHandle,
906 SQLCHAR *CursorName,
907 SQLSMALLINT NameLength)
909 // Is Stmt valid ?
910 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
911 return( SQL_INVALID_HANDLE );
913 return( ((CSqlOdbcStmt*) StatementHandle)->SQLSetCursorName( CursorName, NameLength ) );
916 SQLRETURN CSqlOdbcStmt::SQLSetCursorName(
917 SQLCHAR *cursorName,
918 SQLSMALLINT nameLength)
920 // Start with NO_ERR
921 err_.set( NO_ERR );
923 // Can we proceed ?
924 if( chkStateForSQLSetCursorName() != SQL_SUCCESS )
925 return( SQL_ERROR );
927 // Invalid Stmt Length.
928 if( nameLength < 0 && nameLength != SQL_NTS )
930 err_.set( ERROR_INVARGVAL );
931 return( SQL_ERROR );
934 // Validate Parameters
935 if( cursorName == 0 || cursorName[0] == '\0' || strlen( (char*) cursorName ) > SQL_MAX_CURSOR_NAME_LEN ||
936 nameLength > SQL_MAX_CURSOR_NAME_LEN )
938 err_.set( ERROR_CURNAME );
939 return( SQL_ERROR );
942 // Check for duplicate Name
943 std::vector<CSqlOdbcStmt*>::iterator iter;
944 iter = parentDbc_->stmtList_.begin();
945 while( iter != parentDbc_->stmtList_.end() )
947 if( *iter != this )
949 if( strcmp( (char*) cursorName, (char*) (*iter)->cursorName_ ) == 0 )
951 err_.set( ERROR_DUP_CURNAME );
952 return( SQL_ERROR );
955 iter++;
958 // Copy name
959 strcpy( (char*) cursorName_, (char*) cursorName );
961 return( SQL_SUCCESS );
964 SQLRETURN SQLGetCursorName(
965 SQLHSTMT StatementHandle,
966 SQLCHAR *CursorName,
967 SQLSMALLINT BufferLength,
968 SQLSMALLINT *NameLength)
970 // Is Stmt valid ?
971 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
972 return( SQL_INVALID_HANDLE );
974 return( ((CSqlOdbcStmt*) StatementHandle)->SQLGetCursorName( CursorName, BufferLength, NameLength ) );
976 SQLRETURN CSqlOdbcStmt::SQLGetCursorName(
977 SQLCHAR *cursorName,
978 SQLSMALLINT bufferLength,
979 SQLSMALLINT *nameLength)
981 // Can we proceed ?
982 if( chkStateForSQLGetCursorName() != SQL_SUCCESS )
983 return( SQL_ERROR );
985 if( cursorName_[0] == '\0' )
987 err_.set( ERROR_NOCURNAME );
988 return( SQL_ERROR );
991 // Copy
992 *nameLength = (short)strlen( (char*) cursorName_ );
993 if( *nameLength > bufferLength ) *nameLength = bufferLength;
994 strncpy( (char*) cursorName, (char*) cursorName_, *nameLength );
995 cursorName[ *nameLength ] = '\0';
997 // Did truncate ?
998 if( bufferLength < strlen( (char*) cursorName_ ) )
1000 err_.set( ERROR_DATATRUNC );
1001 return( SQL_SUCCESS_WITH_INFO );
1004 return( SQL_SUCCESS );
1007 SQLRETURN SQLNumResultCols(
1008 SQLHSTMT StatementHandle, // IN
1009 SQLSMALLINT *ColumnCount) // OUT
1011 // Is Stmt valid ?
1012 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1013 return( SQL_INVALID_HANDLE );
1015 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumResultCols( ColumnCount ) );
1018 SQLRETURN CSqlOdbcStmt::SQLNumResultCols(
1019 SQLSMALLINT *columnCount) // OUT
1021 // Start with NO_ERR
1022 err_.set( NO_ERR );
1024 // Can we proceed ?
1025 if( chkStateForSQLNumResultCols() != SQL_SUCCESS )
1026 return( SQL_ERROR );
1028 // If DML
1029 if( fsqlStmt_->isSelect() == false )
1031 *columnCount=0;
1032 return (SQL_SUCCESS);
1035 // If Select
1036 SQLSMALLINT count = fsqlStmt_->noOfProjFields();
1037 if( count < 1 ) // Assume atleast one column is projected
1038 return( SQL_ERROR );
1040 // Fill Column Count
1041 *columnCount = count;
1043 return( SQL_SUCCESS );
1046 SQLRETURN SQL_API SQLRowCount(
1047 SQLHSTMT StatementHandle, // IN
1048 SQLINTEGER *RowCount) // OUT
1050 // Is Stmt valid ?
1051 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1052 return( SQL_INVALID_HANDLE );
1054 return( ((CSqlOdbcStmt*) StatementHandle)->SQLRowCount( RowCount ) );
1057 SQLRETURN CSqlOdbcStmt::SQLRowCount(
1058 SQLINTEGER *rowCount) // OUT
1059 { // TODO
1060 // Start with NO_ERR
1061 err_.set( NO_ERR );
1063 // Can we proceed ?
1064 if( chkStateForSQLRowCount() != SQL_SUCCESS )
1065 return( SQL_ERROR );
1067 if(rowCount == NULL)
1068 return SQL_SUCCESS;
1070 if( state_ == S4 ) // For INSERT/DELETE/UPDATE
1071 *rowCount = (SQLINTEGER) rowsAffected_;
1072 else if( state_ == S5 ) // For SELECT before SQLFetch()
1074 *rowCount = (SQLINTEGER) 0;
1075 // CSQL TODO - Think if you really want to do this!!!
1077 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1078 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1079 if( resultSet_->next() != csqlSqlErrNoTuple )
1080 *rowCount = (SQLINTEGER) 1;
1082 resultSet_->close();
1083 resultSet_->open(); */
1085 else if( state_ == S6 ) // For SELECT after SQLFetch();
1086 *rowCount = (SQLINTEGER) rowsAffected_;
1088 return( SQL_SUCCESS );
1091 SQLRETURN SQLDescribeCol(
1092 SQLHSTMT StatementHandle,
1093 SQLUSMALLINT ColumnNumber,
1094 SQLCHAR *ColumnName,
1095 SQLSMALLINT BufferLength,
1096 SQLSMALLINT *NameLength,
1097 SQLSMALLINT *DataType,
1098 SQLUINTEGER *ColumnSize,
1099 SQLSMALLINT *DecimalDigits,
1100 SQLSMALLINT *Nullable)
1102 // Is Stmt valid ?
1103 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1104 return( SQL_INVALID_HANDLE );
1106 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeCol( ColumnNumber, ColumnName, BufferLength,
1107 NameLength, DataType, ColumnSize, DecimalDigits, Nullable) );
1110 SQLRETURN CSqlOdbcStmt::SQLDescribeCol(
1111 SQLUSMALLINT columnNumber,
1112 SQLCHAR *columnName,
1113 SQLSMALLINT bufferLength,
1114 SQLSMALLINT *nameLength,
1115 SQLSMALLINT *dataType,
1116 SQLUINTEGER *columnSize,
1117 SQLSMALLINT *decimalDigits,
1118 SQLSMALLINT *nullable)
1120 int nameLen;
1121 int type;
1122 int colSize;
1123 int deciDigits;
1124 int isNullable;
1126 // Start with NO_ERR
1127 err_.set( NO_ERR );
1129 // Can we proceed ?
1130 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1131 return( SQL_ERROR );
1133 if( columnNumber < 1 )
1135 err_.set( ERROR_COLNUM );
1136 return( SQL_ERROR );
1139 // If DML
1140 if( fsqlStmt_->isSelect() == false )
1141 return( SQL_ERROR );
1143 // If SELECT
1144 if(columnNumber > fsqlStmt_->noOfProjFields())
1146 err_.set( ERROR_COLNUM );
1147 return( SQL_ERROR );
1149 if(columnName == NULL) {
1150 err_.set( ERROR_COLNUM );
1151 return( SQL_ERROR );
1153 FieldInfo *info = new FieldInfo();
1154 fsqlStmt_->getProjFldInfo(columnNumber+1, info);
1155 strncpy( (char*)columnName, (char*)info->fldName, bufferLength );
1156 if(nameLength != NULL)
1157 *nameLength=(short)strlen((const char*)info->fldName); // HARDCODED - TO DO, need support for n/w layer & sql layer
1158 if(dataType != NULL)
1159 *dataType = (SQLSMALLINT) getSQLType(info->type); // Need to convert from SQL<->ODBC - TO DO
1160 if(columnSize != NULL)
1162 *columnSize = (SQLUINTEGER) info->length;
1163 SQLSMALLINT sqlType=getSQLType(info->type);
1164 if(sqlType == SQL_CHAR )
1165 *columnSize = *columnSize -1;
1168 /*if(decimalDigits != NULL) // CSQL TODO
1169 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1170 if(nullable != NULL)
1171 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1172 if(strlen((char*)info->fldName) > bufferLength)
1174 err_.set( ERROR_DATATRUNC );
1175 return( SQL_SUCCESS_WITH_INFO );
1177 else
1178 return( SQL_SUCCESS );
1181 SQLRETURN SQLColAttributes(
1182 SQLHSTMT StatementHandle,
1183 SQLUSMALLINT ColumnNumber,
1184 SQLUSMALLINT FieldIdentifier,
1185 SQLPOINTER CharacterAttributePtr,
1186 SQLSMALLINT BufferLength,
1187 SQLSMALLINT *StringLengthPtr,
1188 SQLINTEGER *NumericAttributePtr)
1190 // Is Stmt valid ?
1191 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1192 return( SQL_INVALID_HANDLE );
1194 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1195 CharacterAttributePtr, BufferLength, StringLengthPtr, (SQLPOINTER)NumericAttributePtr) );
1198 SQLRETURN SQLColAttribute(
1199 SQLHSTMT StatementHandle,
1200 SQLUSMALLINT ColumnNumber,
1201 SQLUSMALLINT FieldIdentifier,
1202 SQLPOINTER CharacterAttributePtr,
1203 SQLSMALLINT BufferLength,
1204 SQLSMALLINT * StringLengthPtr,
1205 SQLPOINTER NumericAttributePtr)
1207 // Is Stmt valid ?
1208 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1209 return( SQL_INVALID_HANDLE );
1211 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1212 CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr) );
1215 SQLRETURN CSqlOdbcStmt::SQLColAttribute(
1216 SQLUSMALLINT columnNumber,
1217 SQLUSMALLINT fieldIdentifier,
1218 SQLPOINTER characterAttributePtr,
1219 SQLSMALLINT bufferLength,
1220 SQLSMALLINT * stringLengthPtr,
1221 SQLPOINTER numericAttributePtr)
1223 int nameLen;
1224 int type;
1225 int colSize;
1226 int deciDigits;
1227 int isNullable;
1229 // Start with NO_ERR
1230 err_.set( NO_ERR );
1232 // Can we proceed ?
1233 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1234 return( SQL_ERROR );
1236 if( columnNumber < 1 )
1238 err_.set( ERROR_COLNUM );
1239 return( SQL_ERROR );
1241 // If DML
1242 if( fsqlStmt_->isSelect() == false )
1243 return( SQL_ERROR );
1245 FieldInfo *info = new FieldInfo();
1246 fsqlStmt_->getProjFldInfo(columnNumber+1, info);
1248 // If SELECT
1249 if(columnNumber > fsqlStmt_->noOfProjFields())
1251 err_.set( ERROR_COLNUM );
1252 return( SQL_ERROR );
1254 switch(fieldIdentifier)
1256 case SQL_DESC_NAME:
1257 case SQL_COLUMN_NAME:
1258 if(characterAttributePtr != NULL)
1260 strncpy( (char*)characterAttributePtr, (char*)info->fldName, bufferLength);
1261 if(stringLengthPtr != NULL)
1262 *stringLengthPtr=(short)strlen((char*)info->fldName);
1264 break;
1265 case SQL_DESC_COUNT:
1266 case SQL_COLUMN_COUNT:
1267 if(numericAttributePtr != NULL)
1268 *(SQLINTEGER*)numericAttributePtr=fsqlStmt_->noOfProjFields();
1269 break;
1270 case SQL_DESC_TYPE:
1271 case SQL_COLUMN_TYPE:
1272 if(numericAttributePtr != NULL)
1273 *(SQLINTEGER *)numericAttributePtr=getSQLType(info->type);
1274 break;
1275 case SQL_DESC_LENGTH:
1276 case SQL_COLUMN_LENGTH:
1277 if(numericAttributePtr != NULL)
1279 SQLSMALLINT sqlType=getSQLType(info->type);
1280 *(SQLINTEGER *)numericAttributePtr=(SQLUINTEGER) info->length;
1281 if(sqlType == SQL_CHAR)
1282 *(SQLINTEGER *)numericAttributePtr=*(SQLINTEGER *)numericAttributePtr -1;
1284 break;
1285 case SQL_DESC_PRECISION:
1286 case SQL_COLUMN_PRECISION:
1287 /*if(numericAttributePtr != NULL) // CSQL TODO
1288 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1289 break;
1290 case SQL_DESC_SCALE:
1291 case SQL_COLUMN_SCALE:
1292 /*if(numericAttributePtr != NULL) // CSQL TODO
1293 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1294 break;
1295 case SQL_DESC_NULLABLE:
1296 case SQL_COLUMN_NULLABLE:
1297 /*if(numericAttributePtr != NULL) // CSQL TODO
1298 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1299 break;
1300 case SQL_DESC_UNSIGNED:
1301 if(numericAttributePtr != NULL)
1303 SQLSMALLINT sqlType=getSQLType(info->type);
1304 if((sqlType != SQL_TIME) && (sqlType != SQL_DATE) && (sqlType != SQL_TIMESTAMP)
1305 && (sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR) && (sqlType != SQL_BINARY)
1306 && (sqlType != SQL_VARBINARY) && (sqlType != SQL_BIT))
1307 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1308 else
1309 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1311 break;
1312 case SQL_DESC_FIXED_PREC_SCALE:
1313 if(numericAttributePtr != NULL)
1314 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1315 break;
1316 case SQL_DESC_TYPE_NAME:
1317 if(characterAttributePtr != NULL)
1319 SQLSMALLINT sqlType=getSQLType(info->type);
1320 strncpy((char*)characterAttributePtr,(char *)(getSQLTypeName(sqlType)),bufferLength);
1321 if(stringLengthPtr != NULL)
1322 *stringLengthPtr=(int)strlen((char *)getSQLTypeName(sqlType));
1324 break;
1325 case SQL_DESC_UPDATABLE:
1326 if(numericAttributePtr != NULL)
1327 *(SQLINTEGER*)numericAttributePtr=SQL_ATTR_READWRITE_UNKNOWN;
1328 break;
1329 case SQL_DESC_AUTO_UNIQUE_VALUE:
1330 if(numericAttributePtr != NULL)
1331 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1332 break;
1333 case SQL_DESC_CASE_SENSITIVE:
1334 if(numericAttributePtr != NULL)
1336 SQLSMALLINT sqlType=getSQLType(info->type);
1337 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1338 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1339 else
1340 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1342 break;
1343 case SQL_DESC_SEARCHABLE:
1344 if(numericAttributePtr != NULL)
1346 SQLSMALLINT sqlType=getSQLType(info->type);
1347 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1348 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_BASIC;
1349 else
1350 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_SEARCHABLE;
1352 break;
1353 default:
1354 break;
1356 if(stringLengthPtr != NULL)
1358 if(*stringLengthPtr > bufferLength)
1360 err_.set( ERROR_DATATRUNC );
1361 return( SQL_SUCCESS_WITH_INFO );
1364 return( SQL_SUCCESS );
1367 SQLRETURN SQLNumParams(
1368 SQLHSTMT StatementHandle,
1369 SQLSMALLINT * ParameterCountPtr)
1371 // Is Stmt valid ?
1372 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1373 return( SQL_INVALID_HANDLE );
1375 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumParams(ParameterCountPtr) );
1378 SQLRETURN CSqlOdbcStmt::SQLNumParams(
1379 SQLSMALLINT * ParameterCount)
1381 // Start with NO_ERR
1382 err_.set( NO_ERR );
1384 // Can we proceed ?
1385 if( chkStateForSQLNumParams() != SQL_SUCCESS )
1386 return( SQL_ERROR );
1387 if(ParameterCount == NULL)
1388 return (SQL_ERROR);
1389 *ParameterCount=fsqlStmt_->noOfParamFields();
1391 return SQL_SUCCESS;
1394 SQLRETURN SQLDescribeParam(
1395 SQLHSTMT StatementHandle,
1396 SQLUSMALLINT ParameterNumber,
1397 SQLSMALLINT * DataTypePtr,
1398 SQLUINTEGER * ParameterSizePtr,
1399 SQLSMALLINT * DecimalDigitsPtr,
1400 SQLSMALLINT * NullablePtr)
1402 // Is Stmt valid ?
1403 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1404 return( SQL_INVALID_HANDLE );
1406 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeParam(ParameterNumber,DataTypePtr,
1407 ParameterSizePtr,DecimalDigitsPtr,NullablePtr ) );
1409 SQLRETURN CSqlOdbcStmt::SQLDescribeParam(
1410 SQLUSMALLINT paramNumber,
1411 SQLSMALLINT * dataType,
1412 SQLUINTEGER * paramSize,
1413 SQLSMALLINT * decimalDigits,
1414 SQLSMALLINT * isNullable)
1417 // Start with NO_ERR
1418 err_.set( NO_ERR );
1420 // Can we proceed ?
1421 if( chkStateForSQLDescribeParam() != SQL_SUCCESS )
1422 return( SQL_ERROR );
1424 if( paramNumber < 1 )
1426 err_.set( ERROR_PARAMNUM);
1427 return( SQL_ERROR );
1430 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1431 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1432 if(paramNumber > fsqlStmt_->noOfParamFields())
1434 err_.set( ERROR_PARAMNUM );
1435 return( SQL_ERROR );
1438 FieldInfo *finfo = new FieldInfo();
1439 if( fsqlStmt_->getParamFldInfo( paramNumber-1, finfo ) != OK ) return( SQL_ERROR );
1440 if(dataType != NULL)
1441 *dataType = (SQLSMALLINT) getSQLType(finfo->type);
1442 if(paramSize != NULL)
1444 *paramSize = (SQLUINTEGER) finfo->length;
1445 SQLSMALLINT sqlType=getSQLType(finfo->type);
1446 if(sqlType == SQL_CHAR )
1447 *paramSize= *paramSize -1;
1449 /*if(decimalDigits != NULL) // CSQL TODO
1450 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1451 if(isNullable != NULL)
1452 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1453 return( SQL_SUCCESS );
1456 // Resets the Stmt to initial state. As if newly allocated.
1457 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1459 SQLFreeStmt( SQL_CLOSE );
1460 SQLFreeStmt( SQL_UNBIND );
1461 SQLFreeStmt( SQL_RESET_PARAMS );
1462 if (fsqlStmt_) { fsqlStmt_->free(); delete fsqlStmt_; fsqlStmt_ = NULL; }
1463 isPrepared_ = false;
1464 state_ = S1;