network support for odbc
[csql.git] / src / odbc / odbcStmt.cxx
blobada256e079922554c22dbcae162c29d489145e5e
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(CSqlAdapter);
506 else if (parentDbc_->mode_ ==3)
507 fsqlStmt_ = SqlFactory::createStatement(CSqlGateway);
508 else if (parentDbc_->mode_ ==4)
509 fsqlStmt_ = SqlFactory::createStatement(CSqlNetwork);
510 else if (parentDbc_->mode_ ==5)
511 fsqlStmt_ = SqlFactory::createStatement(CSqlNetworkAdapter);
512 else if (parentDbc_->mode_ ==6)
513 fsqlStmt_ = SqlFactory::createStatement(CSqlNetworkGateway);
514 fsqlStmt_->setConnection( parentDbc_->fsqlConn_ );
516 // Prepare
517 //CSqlOdbcError::printDbg("proxy:stmt:prepare");
518 DbRetVal rv=OK;
519 if( (rv=fsqlStmt_->prepare( (char*) statementText ))!= OK) // CSQL
521 state_ = S1;
522 err_.set(ERROR_GENERAL);
523 /*switch(rv)
525 case csqlSqlErrSchNotFound: err_.set( ERROR_SCHNOTFOUND); break;
526 case csqlSqlErrTblNotFound: err_.set( ERROR_TBLNOTFOUND); break;
527 case csqlSqlErrFldNotFound: err_.set( ERROR_NO_COLEXISTS); break;
528 case csqlSqlErrIndexNotFound: err_.set( ERROR_NO_IDXEXISTS); break;
529 case csqlSqlErrViewNotFound: err_.set( ERROR_TBLNOTFOUND); break;
530 case csqlSqlErrTblExists: err_.set( ERROR_TBLEXISTS); break;
531 case csqlSqlErrFldExists: err_.set( ERROR_COLEXISTS); break;
532 case csqlSqlErrIndexExists: err_.set( ERROR_IDXEXISTS); break;
533 case csqlSqlErrViewExists: err_.set( ERROR_TBLEXISTS); break;
534 case csqlSqlErrTooManyVals:err_.set(ERROR_MANY_VALS);break;
535 case csqlSqlErrTooFewVals:err_.set(ERROR_FEW_VALS);break;
536 case csqlSqlErrSqlSyntaxError:err_.set(ERROR_SQL_SYNTAX);break;
537 case csqlSqlErrIncompatibleType:err_.set(ERROR_TYPE_INCMP);break;
538 case csqlSqlErrInvalidFormat:err_.set(ERROR_DATA_FORMAT);break;
539 case csqlSqlErrDuplicateFld:err_.set(ERROR_DUP_COL);break;
540 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
541 default:
543 return( SQL_ERROR );
545 if( fsqlStmt_->isSelect() != true ) // CSQL
546 state_ = S2; // With cursor
547 else
548 state_ = S3; // Without cursor
550 //parentDbc_->state_ = C6;
551 isPrepared_ = true;
552 return( SQL_SUCCESS );
555 SQLRETURN SQLExecute(SQLHSTMT StatementHandle) // IN
557 // Is Stmt valid ?
558 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
559 return( SQL_INVALID_HANDLE );
561 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecute() );
564 SQLRETURN CSqlOdbcStmt::SQLExecute() // TODO
566 // Start with NO_ERR
567 err_.set( NO_ERR );
569 // Can we proceed ?
570 if( chkStateForSQLExecute() != SQL_SUCCESS )
571 return( SQL_ERROR );
573 if( fsqlStmt_->noOfParamFields() > 0 )
576 // Iterate through all apd_;
577 CSqlOdbcDesc *appParamDesc;
578 CSqlOdbcDescList::iterator apdIter;
579 apdIter = apd_.begin();
580 CSqlOdbcDesc *csqlParamDesc;
581 CSqlOdbcDescList::iterator ipdIter;
582 ipdIter = ipd_.begin();
584 //Get the source and the destination type
585 DataType sourceType = typeUnknown,destType = typeUnknown;
586 int paramNum=1,sourceLength=-1,destLength=-1;
587 bool nullFlag=false;
589 while( (apdIter != apd_.end()) || (ipdIter != ipd_.end()) )
591 appParamDesc=*apdIter;
592 csqlParamDesc=*ipdIter;
593 if((paramNum) <= fsqlStmt_->noOfParamFields())
595 FieldInfo *finfo = new FieldInfo();
596 if( fsqlStmt_->getParamFldInfo(paramNum, finfo ) != OK ) return( SQL_ERROR );
597 sourceType=getCSqlType(appParamDesc->cType_);
598 destType=finfo->type;
599 sourceLength=(int)appParamDesc->length_;
600 destLength=finfo->length;
601 delete finfo;
602 if(sourceType != typeUnknown && destType != typeUnknown)
604 //Check if NULL is inserted
605 if((appParamDesc->indPtr_ != NULL ) && (*(SQLINTEGER *)appParamDesc->indPtr_) == SQL_NULL_DATA)
607 nullFlag=true;
608 //finfo->isNull = true; CSQL TODO - need to understand how to set null
610 else
612 //Only if both types are not the same, then we need to copy it onto intermediate buffer
613 //Else no need
614 if( (sourceType == typeString || sourceType == typeBinary) && (sourceLength <= 0))
616 if((appParamDesc->indPtr_!= NULL) && *(SQLINTEGER *)appParamDesc->indPtr_ > 0)
617 sourceLength=(int)(*(SQLINTEGER *)appParamDesc->indPtr_);
618 else if (appParamDesc->precision_ > 0)
619 sourceLength=appParamDesc->precision_;
620 else
622 err_.set( ERROR_BUFLEN );
623 return SQL_ERROR;
626 if(destType == typeString) //|| destType == typeVarString)
628 //fsqlStmt_->allocParam(paramNum,sourceLength); // CSQL TODO
629 destLength=sourceLength;
631 if(sourceType == destType)
632 //|| (sourceType == typeString && destType == typeVarString)
633 //|| (sourceType == typeBinary && destType == typeVarBinary))
635 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength,destType); // CSQL TODO
636 } else
638 getInputBuffer(&csqlParamDesc->dataPtr_ ,sourceType,sourceLength);
639 copyFromOdbc(fsqlStmt_, paramNum, destLength, appParamDesc->dataPtr_, sourceLength, sourceType);
640 //convert(sourceType,csqlParamDesc->dataPtr_,destType, fsqlStmt_->getParamPtr( paramNum),sourceLength,destLength); // CSQL TODO
644 else
646 err_.set(ERROR_GENERAL);
647 return SQL_ERROR;
650 paramNum++;
651 apdIter++;
652 ipdIter++;
657 // Get the result
658 int rowsAffected=0;
659 DbRetVal rv = fsqlStmt_->execute( rowsAffected );
660 if( rowsAffected < 0 )
662 if( isPrepared_ ) state_ = S2; else resetStmt();
663 err_.set( ERROR_GENERAL );
664 /*switch(rv)
666 case csqlSqlErrOverflow:err_.set(ERROR_OVERFLOW);break;
667 case csqlSqlErrUnderflow:err_.set(ERROR_UNDERFLOW);break;
668 case csqlSqlErrTooManyTpl:err_.set(ERROR_MANY_TUP);break;
669 case csqlSqlErrProjCnt:err_.set(ERROR_NUM_PROJ);break;
670 case csqlSqlErrStorageAttr:err_.set(ERROR_STORAGE_ATTR);break;
671 case csqlSqlErrFldCntMismatch:err_.set(ERROR_FLDCNT_MISMATCH);break;
672 case csqlSqlErrSqlInternal:err_.set(ERROR_SQL_INT);break;
673 case csqlSqlErrNoMatchKeyFound:err_.set(ERROR_MATCHKEY_NOTFOUND);break;
674 default:
675 err_.set( ERROR_GENERAL );break;
676 } */
677 return( SQL_ERROR );
680 // Set Stmt State
681 if( fsqlStmt_->isSelect() == true )
683 rowsAffected_ = -1;
684 state_ = S5;
686 else
688 rowsAffected_ = rowsAffected;
689 state_ = S4;
692 // Set Dbc State to Transaction Mode.
693 parentDbc_->state_ = C6;
695 // AutoCommit Mode
696 if( parentDbc_->autoCommit_ == SQL_AUTOCOMMIT_ON )
697 parentDbc_->SQLEndTran( SQL_COMMIT );
699 return( SQL_SUCCESS );
702 SQLRETURN SQLExecDirect(
703 SQLHSTMT StatementHandle,
704 SQLCHAR *StatementText,
705 SQLINTEGER TextLength)
707 // Is Stmt valid ?
708 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
709 return( SQL_INVALID_HANDLE );
711 return( ((CSqlOdbcStmt*) StatementHandle)->SQLExecDirect( StatementText, TextLength ) );
714 SQLRETURN CSqlOdbcStmt::SQLExecDirect(
715 SQLCHAR *statementText,
716 SQLINTEGER textLength)
718 SQLRETURN ret;
720 // Can we proceed ?
721 if( chkStateForSQLExecDirect() != SQL_SUCCESS )
722 return( SQL_ERROR );
724 // SQLExecDirect = SQLPrepare + SQLExecute.
725 if( SQLPrepare( statementText, textLength ) != SQL_SUCCESS )
726 return( SQL_ERROR );
728 ret = SQLExecute();
729 isPrepared_ = false; // Set Stmt as non-prepared stmt.
731 if( ret != SQL_SUCCESS )
732 return( SQL_ERROR );
734 return( SQL_SUCCESS );
737 SQLRETURN SQLSetStmtOption(
738 SQLHSTMT StatementHandle,
739 SQLUSMALLINT Option,
740 SQLUINTEGER Value)
742 return (SQLSetStmtAttr(StatementHandle, Option, (SQLPOINTER) Value, 0));
745 SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
746 SQLINTEGER Attribute, SQLPOINTER Value,
747 SQLINTEGER StringLength)
749 return (((CSqlOdbcStmt*)StatementHandle)->SQLSetStmtAttr(Attribute, Value,StringLength));
752 SQLRETURN CSqlOdbcStmt::SQLSetStmtAttr(
753 SQLINTEGER Attribute,
754 SQLPOINTER Value,
755 SQLINTEGER stringLength)
757 CSqlOdbcError::printDbg("proxy:stmt:SQLSetStmtAttr");
758 //HACK
759 /*switch(Attribute)
761 //Values: SQL_FETCH_SINGLE_TUPLE or SQL_FETCH_MULTIPLE_TUPLES
762 //Default is SQL_FETCH_SINGLE_TUPLE.
763 //In SQL_FETCH_SINGLE_TUPLE mode, only a single tuple
764 //is sent from server to client in a single packet whatever be
765 //the packet size. If a tuple size is 50 and network packet size
766 //is 500, the remaining 450 bytes can also be used to send more
767 //in a single packet so that in the next SQLFetch call one network
768 //packet transfer overhead is reduced.
769 case SQL_FETCH_MODE:
770 if(state_ <= S5)
771 //state_ > S5 means Fetch has already started on this statement.
772 fetchMode_ = (SQLINTEGER)Value;
773 else
774 printf("ODBC:Error in setting fetch mode, can't set after fetch is started.\n");
775 break;
776 default:
777 printf("ODBC: Error, Stmt Option %d is not supported.\n", Attribute);
779 return (SQL_SUCCESS);
782 SQLRETURN SQLFetch(SQLHSTMT StatementHandle)
784 // Is Stmt valid ?
785 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
786 return( SQL_INVALID_HANDLE );
788 return( ((CSqlOdbcStmt*) StatementHandle)->SQLFetch() );
791 SQLRETURN CSqlOdbcStmt::SQLFetch()
793 // Start with NO_ERR
794 err_.set( NO_ERR );
796 // Can we proceed ?
797 if( chkStateForSQLFetch() != SQL_SUCCESS )
798 return( SQL_ERROR );
800 void *tuple;
801 tuple = fsqlStmt_->next();
803 if( ! tuple ) // IF Row not found.
805 rowsAffected_ = 0;
806 state_ = S6;
807 return( SQL_NO_DATA_FOUND );
809 /*else if( rowsAffected != SQL_SUCCESS ) // IF Error
811 rowsAffected_ = -1;
812 err_.set( ERROR_GENERAL );
813 return( SQL_ERROR );
815 else // IF Row found.
817 rowsAffected_ = 1;
819 // Iterate through all ard_;
820 CSqlOdbcDesc *appColDesc;
821 CSqlOdbcDescList::iterator ardIter;
822 ardIter = ard_.begin();
823 //Get the input parameter data
824 CSqlOdbcDesc *csqlColDesc;
825 CSqlOdbcDescList::iterator irdIter;
826 irdIter = ird_.begin();
828 DataType sourceType = typeUnknown,destType = typeUnknown;
829 int colNum=-1,sourceLength=-1,destLength=-1;
830 SQLINTEGER ind;
831 void* sourceData = NULL;
832 //FieldInfo *info = new FieldInfo();
833 while( (ardIter != ard_.end()) || (irdIter != ird_.end()) )
835 appColDesc = *ardIter;
836 csqlColDesc = *irdIter;
838 colNum = appColDesc->col_ - 1;
839 // fsqlStmt_->getProjFldInfo(colNum+1, info);
840 sourceType = (DataType)csqlColDesc->cType_;
841 destType = getCSqlType(appColDesc->cType_);
842 sourceLength = (int)csqlColDesc->length_;
843 destLength = (int)appColDesc->length_;
845 if( sourceType != typeUnknown && destType != typeUnknown )
847 sourceData = fsqlStmt_->getFieldValuePtr( colNum );
848 if(fsqlStmt_->isFldNull(appColDesc->col_) || sourceData == NULL )
850 if (appColDesc->indPtr_ != NULL)
851 *((SQLINTEGER *)(appColDesc->indPtr_))=SQL_NULL_DATA;
853 else
855 /*if( sourceType == csqlSqlTvarBinary)
856 sourceLength=resultSet_->getDataLength(colNum); */
857 if (sourceType == typeString ) // CSQL TODO - handle varchar also
859 sourceLength=(int)(strlen((char *) sourceData ));
860 if(appColDesc->indPtr_ != NULL)
861 *((SQLINTEGER *)(appColDesc->indPtr_))=copyToOdbc(appColDesc->dataPtr_,destLength,
862 sourceData,sourceLength, sourceType);
863 else
864 copyToOdbc(appColDesc->dataPtr_,destLength,sourceData,
865 sourceLength, sourceType);
867 else
869 //convert(sourceType,sourceData,destType, csqlColDesc->dataPtr_,sourceLength,destLength);
870 if(appColDesc->indPtr_ != NULL){
871 *((SQLINTEGER *)(appColDesc->indPtr_))=
872 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
874 else
875 copyToOdbc(appColDesc->dataPtr_,destLength, sourceData, sourceLength, sourceType);
878 // CSQL TODO - handle varstring, binary, varbinary
879 if( sourceType == typeString && sourceLength > destLength )
880 err_.set( ERROR_DATATRUNC );
883 ardIter++;
884 irdIter++;
886 state_ = S6;
888 if(err_.csqlErrCode == ERROR_DATATRUNC)
889 return (SQL_SUCCESS_WITH_INFO);
891 return( SQL_SUCCESS );
894 SQLRETURN SQLCloseCursor(SQLHSTMT StatementHandle)
896 // Is Stmt valid ?
897 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
898 return( SQL_INVALID_HANDLE );
900 return( ((CSqlOdbcStmt*) StatementHandle)->SQLCloseCursor() );
903 SQLRETURN CSqlOdbcStmt::SQLCloseCursor()
905 // Start with NO_ERR
906 err_.set( NO_ERR );
908 // Can we proceed ?
909 if( chkStateForSQLCloseCursor() != SQL_SUCCESS )
910 return( SQL_ERROR );
912 // Close the cursor
913 fsqlStmt_->close();
914 state_ = S3;
915 return( SQL_SUCCESS );
918 SQLRETURN SQLSetCursorName(
919 SQLHSTMT StatementHandle,
920 SQLCHAR *CursorName,
921 SQLSMALLINT NameLength)
923 // Is Stmt valid ?
924 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
925 return( SQL_INVALID_HANDLE );
927 return( ((CSqlOdbcStmt*) StatementHandle)->SQLSetCursorName( CursorName, NameLength ) );
930 SQLRETURN CSqlOdbcStmt::SQLSetCursorName(
931 SQLCHAR *cursorName,
932 SQLSMALLINT nameLength)
934 // Start with NO_ERR
935 err_.set( NO_ERR );
937 // Can we proceed ?
938 if( chkStateForSQLSetCursorName() != SQL_SUCCESS )
939 return( SQL_ERROR );
941 // Invalid Stmt Length.
942 if( nameLength < 0 && nameLength != SQL_NTS )
944 err_.set( ERROR_INVARGVAL );
945 return( SQL_ERROR );
948 // Validate Parameters
949 if( cursorName == 0 || cursorName[0] == '\0' || strlen( (char*) cursorName ) > SQL_MAX_CURSOR_NAME_LEN ||
950 nameLength > SQL_MAX_CURSOR_NAME_LEN )
952 err_.set( ERROR_CURNAME );
953 return( SQL_ERROR );
956 // Check for duplicate Name
957 std::vector<CSqlOdbcStmt*>::iterator iter;
958 iter = parentDbc_->stmtList_.begin();
959 while( iter != parentDbc_->stmtList_.end() )
961 if( *iter != this )
963 if( strcmp( (char*) cursorName, (char*) (*iter)->cursorName_ ) == 0 )
965 err_.set( ERROR_DUP_CURNAME );
966 return( SQL_ERROR );
969 iter++;
972 // Copy name
973 strcpy( (char*) cursorName_, (char*) cursorName );
975 return( SQL_SUCCESS );
978 SQLRETURN SQLGetCursorName(
979 SQLHSTMT StatementHandle,
980 SQLCHAR *CursorName,
981 SQLSMALLINT BufferLength,
982 SQLSMALLINT *NameLength)
984 // Is Stmt valid ?
985 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
986 return( SQL_INVALID_HANDLE );
988 return( ((CSqlOdbcStmt*) StatementHandle)->SQLGetCursorName( CursorName, BufferLength, NameLength ) );
990 SQLRETURN CSqlOdbcStmt::SQLGetCursorName(
991 SQLCHAR *cursorName,
992 SQLSMALLINT bufferLength,
993 SQLSMALLINT *nameLength)
995 // Can we proceed ?
996 if( chkStateForSQLGetCursorName() != SQL_SUCCESS )
997 return( SQL_ERROR );
999 if( cursorName_[0] == '\0' )
1001 err_.set( ERROR_NOCURNAME );
1002 return( SQL_ERROR );
1005 // Copy
1006 *nameLength = (short)strlen( (char*) cursorName_ );
1007 if( *nameLength > bufferLength ) *nameLength = bufferLength;
1008 strncpy( (char*) cursorName, (char*) cursorName_, *nameLength );
1009 cursorName[ *nameLength ] = '\0';
1011 // Did truncate ?
1012 if( bufferLength < strlen( (char*) cursorName_ ) )
1014 err_.set( ERROR_DATATRUNC );
1015 return( SQL_SUCCESS_WITH_INFO );
1018 return( SQL_SUCCESS );
1021 SQLRETURN SQLNumResultCols(
1022 SQLHSTMT StatementHandle, // IN
1023 SQLSMALLINT *ColumnCount) // OUT
1025 // Is Stmt valid ?
1026 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1027 return( SQL_INVALID_HANDLE );
1029 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumResultCols( ColumnCount ) );
1032 SQLRETURN CSqlOdbcStmt::SQLNumResultCols(
1033 SQLSMALLINT *columnCount) // OUT
1035 // Start with NO_ERR
1036 err_.set( NO_ERR );
1038 // Can we proceed ?
1039 if( chkStateForSQLNumResultCols() != SQL_SUCCESS )
1040 return( SQL_ERROR );
1042 // If DML
1043 if( fsqlStmt_->isSelect() == false )
1045 *columnCount=0;
1046 return (SQL_SUCCESS);
1049 // If Select
1050 SQLSMALLINT count = fsqlStmt_->noOfProjFields();
1051 if( count < 1 ) // Assume atleast one column is projected
1052 return( SQL_ERROR );
1054 // Fill Column Count
1055 *columnCount = count;
1057 return( SQL_SUCCESS );
1060 SQLRETURN SQL_API SQLRowCount(
1061 SQLHSTMT StatementHandle, // IN
1062 SQLINTEGER *RowCount) // OUT
1064 // Is Stmt valid ?
1065 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1066 return( SQL_INVALID_HANDLE );
1068 return( ((CSqlOdbcStmt*) StatementHandle)->SQLRowCount( RowCount ) );
1071 SQLRETURN CSqlOdbcStmt::SQLRowCount(
1072 SQLINTEGER *rowCount) // OUT
1073 { // TODO
1074 // Start with NO_ERR
1075 err_.set( NO_ERR );
1077 // Can we proceed ?
1078 if( chkStateForSQLRowCount() != SQL_SUCCESS )
1079 return( SQL_ERROR );
1081 if(rowCount == NULL)
1082 return SQL_SUCCESS;
1084 if( state_ == S4 ) // For INSERT/DELETE/UPDATE
1085 *rowCount = (SQLINTEGER) rowsAffected_;
1086 else if( state_ == S5 ) // For SELECT before SQLFetch()
1088 *rowCount = (SQLINTEGER) 0;
1089 // CSQL TODO - Think if you really want to do this!!!
1091 /*CSqlOdbcError::printDbg("proxy:stmt:getResultSet");
1092 CSqlResultSet *resultSet_ = fsqlStmt_.getResultSet();
1093 if( resultSet_->next() != csqlSqlErrNoTuple )
1094 *rowCount = (SQLINTEGER) 1;
1096 resultSet_->close();
1097 resultSet_->open(); */
1099 else if( state_ == S6 ) // For SELECT after SQLFetch();
1100 *rowCount = (SQLINTEGER) rowsAffected_;
1102 return( SQL_SUCCESS );
1105 SQLRETURN SQLDescribeCol(
1106 SQLHSTMT StatementHandle,
1107 SQLUSMALLINT ColumnNumber,
1108 SQLCHAR *ColumnName,
1109 SQLSMALLINT BufferLength,
1110 SQLSMALLINT *NameLength,
1111 SQLSMALLINT *DataType,
1112 SQLUINTEGER *ColumnSize,
1113 SQLSMALLINT *DecimalDigits,
1114 SQLSMALLINT *Nullable)
1116 // Is Stmt valid ?
1117 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1118 return( SQL_INVALID_HANDLE );
1120 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeCol( ColumnNumber, ColumnName, BufferLength,
1121 NameLength, DataType, ColumnSize, DecimalDigits, Nullable) );
1124 SQLRETURN CSqlOdbcStmt::SQLDescribeCol(
1125 SQLUSMALLINT columnNumber,
1126 SQLCHAR *columnName,
1127 SQLSMALLINT bufferLength,
1128 SQLSMALLINT *nameLength,
1129 SQLSMALLINT *dataType,
1130 SQLUINTEGER *columnSize,
1131 SQLSMALLINT *decimalDigits,
1132 SQLSMALLINT *nullable)
1134 int nameLen;
1135 int type;
1136 int colSize;
1137 int deciDigits;
1138 int isNullable;
1140 // Start with NO_ERR
1141 err_.set( NO_ERR );
1143 // Can we proceed ?
1144 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1145 return( SQL_ERROR );
1147 if( columnNumber < 1 )
1149 err_.set( ERROR_COLNUM );
1150 return( SQL_ERROR );
1153 // If DML
1154 if( fsqlStmt_->isSelect() == false )
1155 return( SQL_ERROR );
1157 // If SELECT
1158 if(columnNumber > fsqlStmt_->noOfProjFields())
1160 err_.set( ERROR_COLNUM );
1161 return( SQL_ERROR );
1163 if(columnName == NULL) {
1164 err_.set( ERROR_COLNUM );
1165 return( SQL_ERROR );
1167 FieldInfo *info = new FieldInfo();
1168 fsqlStmt_->getProjFldInfo(columnNumber+1, info);
1169 strncpy( (char*)columnName, (char*)info->fldName, bufferLength );
1170 if(nameLength != NULL)
1171 *nameLength=(short)strlen((const char*)info->fldName); // HARDCODED - TO DO, need support for n/w layer & sql layer
1172 if(dataType != NULL)
1173 *dataType = (SQLSMALLINT) getSQLType(info->type); // Need to convert from SQL<->ODBC - TO DO
1174 if(columnSize != NULL)
1176 *columnSize = (SQLUINTEGER) info->length;
1177 SQLSMALLINT sqlType=getSQLType(info->type);
1178 if(sqlType == SQL_CHAR )
1179 *columnSize = *columnSize -1;
1182 /*if(decimalDigits != NULL) // CSQL TODO
1183 *decimalDigits = (SQLSMALLINT) fsqlStmt_->getPrecision( columnNumber-1 );
1184 if(nullable != NULL)
1185 *nullable = rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N; */
1186 if(strlen((char*)info->fldName) > bufferLength)
1188 err_.set( ERROR_DATATRUNC );
1189 return( SQL_SUCCESS_WITH_INFO );
1191 else
1192 return( SQL_SUCCESS );
1195 SQLRETURN SQLColAttributes(
1196 SQLHSTMT StatementHandle,
1197 SQLUSMALLINT ColumnNumber,
1198 SQLUSMALLINT FieldIdentifier,
1199 SQLPOINTER CharacterAttributePtr,
1200 SQLSMALLINT BufferLength,
1201 SQLSMALLINT *StringLengthPtr,
1202 SQLINTEGER *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, (SQLPOINTER)NumericAttributePtr) );
1212 SQLRETURN SQLColAttribute(
1213 SQLHSTMT StatementHandle,
1214 SQLUSMALLINT ColumnNumber,
1215 SQLUSMALLINT FieldIdentifier,
1216 SQLPOINTER CharacterAttributePtr,
1217 SQLSMALLINT BufferLength,
1218 SQLSMALLINT * StringLengthPtr,
1219 SQLPOINTER NumericAttributePtr)
1221 // Is Stmt valid ?
1222 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1223 return( SQL_INVALID_HANDLE );
1225 return( ((CSqlOdbcStmt*) StatementHandle)->SQLColAttribute(ColumnNumber ,FieldIdentifier ,
1226 CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr) );
1229 SQLRETURN CSqlOdbcStmt::SQLColAttribute(
1230 SQLUSMALLINT columnNumber,
1231 SQLUSMALLINT fieldIdentifier,
1232 SQLPOINTER characterAttributePtr,
1233 SQLSMALLINT bufferLength,
1234 SQLSMALLINT * stringLengthPtr,
1235 SQLPOINTER numericAttributePtr)
1237 int nameLen;
1238 int type;
1239 int colSize;
1240 int deciDigits;
1241 int isNullable;
1243 // Start with NO_ERR
1244 err_.set( NO_ERR );
1246 // Can we proceed ?
1247 if( chkStateForSQLDescribeCol() != SQL_SUCCESS )
1248 return( SQL_ERROR );
1250 if( columnNumber < 1 )
1252 err_.set( ERROR_COLNUM );
1253 return( SQL_ERROR );
1255 // If DML
1256 if( fsqlStmt_->isSelect() == false )
1257 return( SQL_ERROR );
1259 FieldInfo *info = new FieldInfo();
1260 fsqlStmt_->getProjFldInfo(columnNumber+1, info);
1262 // If SELECT
1263 if(columnNumber > fsqlStmt_->noOfProjFields())
1265 err_.set( ERROR_COLNUM );
1266 return( SQL_ERROR );
1268 switch(fieldIdentifier)
1270 case SQL_DESC_NAME:
1271 case SQL_COLUMN_NAME:
1272 if(characterAttributePtr != NULL)
1274 strncpy( (char*)characterAttributePtr, (char*)info->fldName, bufferLength);
1275 if(stringLengthPtr != NULL)
1276 *stringLengthPtr=(short)strlen((char*)info->fldName);
1278 break;
1279 case SQL_DESC_COUNT:
1280 case SQL_COLUMN_COUNT:
1281 if(numericAttributePtr != NULL)
1282 *(SQLINTEGER*)numericAttributePtr=fsqlStmt_->noOfProjFields();
1283 break;
1284 case SQL_DESC_TYPE:
1285 case SQL_COLUMN_TYPE:
1286 if(numericAttributePtr != NULL)
1287 *(SQLINTEGER *)numericAttributePtr=getSQLType(info->type);
1288 break;
1289 case SQL_DESC_LENGTH:
1290 case SQL_COLUMN_LENGTH:
1291 if(numericAttributePtr != NULL)
1293 SQLSMALLINT sqlType=getSQLType(info->type);
1294 *(SQLINTEGER *)numericAttributePtr=(SQLUINTEGER) info->length;
1295 if(sqlType == SQL_CHAR)
1296 *(SQLINTEGER *)numericAttributePtr=*(SQLINTEGER *)numericAttributePtr -1;
1298 break;
1299 case SQL_DESC_PRECISION:
1300 case SQL_COLUMN_PRECISION:
1301 /*if(numericAttributePtr != NULL) // CSQL TODO
1302 *(SQLINTEGER *)numericAttributePtr=(SQLSMALLINT) rsMetaData->getPrecision( columnNumber-1 ); */
1303 break;
1304 case SQL_DESC_SCALE:
1305 case SQL_COLUMN_SCALE:
1306 /*if(numericAttributePtr != NULL) // CSQL TODO
1307 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->getScale( columnNumber-1 );*/
1308 break;
1309 case SQL_DESC_NULLABLE:
1310 case SQL_COLUMN_NULLABLE:
1311 /*if(numericAttributePtr != NULL) // CSQL TODO
1312 *(SQLINTEGER*)numericAttributePtr=(SQLSMALLINT) rsMetaData->isNullable( columnNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1313 break;
1314 case SQL_DESC_UNSIGNED:
1315 if(numericAttributePtr != NULL)
1317 SQLSMALLINT sqlType=getSQLType(info->type);
1318 if((sqlType != SQL_TIME) && (sqlType != SQL_DATE) && (sqlType != SQL_TIMESTAMP)
1319 && (sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR) && (sqlType != SQL_BINARY)
1320 && (sqlType != SQL_VARBINARY) && (sqlType != SQL_BIT))
1321 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1322 else
1323 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1325 break;
1326 case SQL_DESC_FIXED_PREC_SCALE:
1327 if(numericAttributePtr != NULL)
1328 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1329 break;
1330 case SQL_DESC_TYPE_NAME:
1331 if(characterAttributePtr != NULL)
1333 SQLSMALLINT sqlType=getSQLType(info->type);
1334 strncpy((char*)characterAttributePtr,(char *)(getSQLTypeName(sqlType)),bufferLength);
1335 if(stringLengthPtr != NULL)
1336 *stringLengthPtr=(int)strlen((char *)getSQLTypeName(sqlType));
1338 break;
1339 case SQL_DESC_UPDATABLE:
1340 if(numericAttributePtr != NULL)
1341 *(SQLINTEGER*)numericAttributePtr=SQL_ATTR_READWRITE_UNKNOWN;
1342 break;
1343 case SQL_DESC_AUTO_UNIQUE_VALUE:
1344 if(numericAttributePtr != NULL)
1345 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1346 break;
1347 case SQL_DESC_CASE_SENSITIVE:
1348 if(numericAttributePtr != NULL)
1350 SQLSMALLINT sqlType=getSQLType(info->type);
1351 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1352 *(SQLINTEGER*)numericAttributePtr=SQL_FALSE;
1353 else
1354 *(SQLINTEGER*)numericAttributePtr=SQL_TRUE;
1356 break;
1357 case SQL_DESC_SEARCHABLE:
1358 if(numericAttributePtr != NULL)
1360 SQLSMALLINT sqlType=getSQLType(info->type);
1361 if((sqlType != SQL_CHAR) && (sqlType != SQL_VARCHAR))
1362 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_BASIC;
1363 else
1364 *(SQLINTEGER*)numericAttributePtr=SQL_PRED_SEARCHABLE;
1366 break;
1367 default:
1368 break;
1370 if(stringLengthPtr != NULL)
1372 if(*stringLengthPtr > bufferLength)
1374 err_.set( ERROR_DATATRUNC );
1375 return( SQL_SUCCESS_WITH_INFO );
1378 return( SQL_SUCCESS );
1381 SQLRETURN SQLNumParams(
1382 SQLHSTMT StatementHandle,
1383 SQLSMALLINT * ParameterCountPtr)
1385 // Is Stmt valid ?
1386 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1387 return( SQL_INVALID_HANDLE );
1389 return( ((CSqlOdbcStmt*) StatementHandle)->SQLNumParams(ParameterCountPtr) );
1392 SQLRETURN CSqlOdbcStmt::SQLNumParams(
1393 SQLSMALLINT * ParameterCount)
1395 // Start with NO_ERR
1396 err_.set( NO_ERR );
1398 // Can we proceed ?
1399 if( chkStateForSQLNumParams() != SQL_SUCCESS )
1400 return( SQL_ERROR );
1401 if(ParameterCount == NULL)
1402 return (SQL_ERROR);
1403 *ParameterCount=fsqlStmt_->noOfParamFields();
1405 return SQL_SUCCESS;
1408 SQLRETURN SQLDescribeParam(
1409 SQLHSTMT StatementHandle,
1410 SQLUSMALLINT ParameterNumber,
1411 SQLSMALLINT * DataTypePtr,
1412 SQLUINTEGER * ParameterSizePtr,
1413 SQLSMALLINT * DecimalDigitsPtr,
1414 SQLSMALLINT * NullablePtr)
1416 // Is Stmt valid ?
1417 if( isValidHandle( (CSqlOdbcStmt*) StatementHandle, SQL_HANDLE_STMT ) != SQL_SUCCESS )
1418 return( SQL_INVALID_HANDLE );
1420 return( ((CSqlOdbcStmt*) StatementHandle)->SQLDescribeParam(ParameterNumber,DataTypePtr,
1421 ParameterSizePtr,DecimalDigitsPtr,NullablePtr ) );
1423 SQLRETURN CSqlOdbcStmt::SQLDescribeParam(
1424 SQLUSMALLINT paramNumber,
1425 SQLSMALLINT * dataType,
1426 SQLUINTEGER * paramSize,
1427 SQLSMALLINT * decimalDigits,
1428 SQLSMALLINT * isNullable)
1431 // Start with NO_ERR
1432 err_.set( NO_ERR );
1434 // Can we proceed ?
1435 if( chkStateForSQLDescribeParam() != SQL_SUCCESS )
1436 return( SQL_ERROR );
1438 if( paramNumber < 1 )
1440 err_.set( ERROR_PARAMNUM);
1441 return( SQL_ERROR );
1444 //CSqlOdbcError::printDbg("proxy:stmt:getMetaData");
1445 //CSqlParamMetaData *paramMetaData = fsqlStmt_->getParamMetaData();
1446 if(paramNumber > fsqlStmt_->noOfParamFields())
1448 err_.set( ERROR_PARAMNUM );
1449 return( SQL_ERROR );
1452 FieldInfo *finfo = new FieldInfo();
1453 if( fsqlStmt_->getParamFldInfo( paramNumber-1, finfo ) != OK ) return( SQL_ERROR );
1454 if(dataType != NULL)
1455 *dataType = (SQLSMALLINT) getSQLType(finfo->type);
1456 if(paramSize != NULL)
1458 *paramSize = (SQLUINTEGER) finfo->length;
1459 SQLSMALLINT sqlType=getSQLType(finfo->type);
1460 if(sqlType == SQL_CHAR )
1461 *paramSize= *paramSize -1;
1463 /*if(decimalDigits != NULL) // CSQL TODO
1464 *decimalDigits = (SQLSMALLINT) paramMetaData->getPrecision( paramNumber-1 );
1465 if(isNullable != NULL)
1466 *isNullable = paramMetaData->isNullable( paramNumber-1 )?SQL_NULLABLE_N:SQL_NO_NULLS_N;*/
1467 return( SQL_SUCCESS );
1470 // Resets the Stmt to initial state. As if newly allocated.
1471 void CSqlOdbcStmt::resetStmt( void ) // TO DO
1473 SQLFreeStmt( SQL_CLOSE );
1474 SQLFreeStmt( SQL_UNBIND );
1475 SQLFreeStmt( SQL_RESET_PARAMS );
1476 if (fsqlStmt_) { fsqlStmt_->free(); delete fsqlStmt_; fsqlStmt_ = NULL; }
1477 isPrepared_ = false;
1478 state_ = S1;