solaris changes
[csql.git] / src / adapter / SqlOdbcStatement.cxx
blobb5bc7cc7d40125ef8288de354fbbd0f6fe3a241d
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include <SqlOdbcStatement.h>
21 //Important Note: MySQL Bug
22 //Bug #1382 SQLDescribeParam returns the same type information for any type
23 //as varchar of length 255. To avoid this, this class converts every data type
24 //to varchar by using appropriate conversion functions.
26 DbRetVal SqlOdbcStatement::executeDirect(char *stmtstr)
28 DbRetVal rv = OK;
29 int retValue = 0;
30 SqlOdbcConnection *conn = (SqlOdbcConnection*)con;
31 retValue=SQLAllocHandle (SQL_HANDLE_STMT, conn->dbHdl, &hstmt);
32 if (retValue) return ErrBadCall;
33 SQLCHAR* sstr= (SQLCHAR*)stmtstr;
34 retValue=(*SqlOdbcConnection::ODBCFuncPtrs.SQLExecDirectPtr) (hstmt, sstr, SQL_NTS);
35 if (retValue) return ErrBadCall;
36 logFinest(Conf::logger, "executeDirect %s", stmtstr);
37 return rv;
40 DbRetVal SqlOdbcStatement::prepare(char *stmtstr)
42 DbRetVal rv = OK;
43 if (innerStmt) rv = ErrBadCall;
44 if (rv != OK) return rv;
45 int retValue =0;
46 isPrepared = false;
47 isProcedureCallStmt = false;
48 SqlOdbcConnection *conn = (SqlOdbcConnection*)con;
49 //retValue=SQLAllocHandle (SQL_HANDLE_STMT, conn->dbHdl, &hstmt);
50 retValue=(*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_STMT, conn->dbHdl, &hstmt);
51 if (retValue) return ErrBadCall;
52 SQLCHAR* sstr= (SQLCHAR*)stmtstr;
53 //retValue = SQLPrepare (hstmt, sstr, SQL_NTS);
54 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLPreparePtr) (hstmt, sstr, SQL_NTS);
55 if (retValue) {
56 // setErrorState(hstmt);
57 printError(ErrSysInternal, "Unable to prepare statement");
58 return ErrSysInternal;
60 isSelStmt=chechStmtType(stmtstr);
61 isPrepared = true;
62 if(strstr(stmtstr,"call ")!=NULL || strstr(stmtstr,"CALL ")!=NULL)
64 logFinest(Conf::logger, "Procedure call statement =true");
65 isProcedureCallStmt=true;
67 short totalFields=0;
68 tdbname = conn->getTrDbName();
69 rv = resolveForBindField(hstmt);
70 if(rv!=OK) return rv;
71 UWORD icol;
72 SWORD colNameMax;
73 SWORD scale;
74 SWORD nullable;
75 BindSqlField *bindField;
76 //retValue = SQLNumParams (hstmt, &totalFields);
77 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLNumParamsPtr) (hstmt, &totalFields);
78 if (retValue) return ErrBadCall;
79 icol = 1; colNameMax = IDENTIFIER_LENGTH;
80 SWORD cType=0;
81 SQLULEN cLength=0;
82 scale=0;
83 logFinest(Conf::logger, "NumParams %d", totalFields);
84 if(totalFields != 0)
86 paramlen =(SQLINTEGER *) malloc((totalFields+1)*sizeof(SQLINTEGER));
87 for(int i=0;i<=totalFields;i++) { paramlen[i] = SQL_NTS; }
90 while (icol <= totalFields)
92 //retValue = SQLDescribeParam(hstmt, icol, &cType, &cLength,
93 //Note: MySQL Bug
94 //Bug #1382 SQLDescribeParam returns the same type information
96 bindField = new BindSqlField();
97 bindField->type = typeString;
98 bindField->length = 512;
99 bindField->value = AllDataType::alloc(bindField->type, bindField->length);
100 bindField->targetvalue = NULL;
101 int fieldsize =0;
102 switch(bindField->type)
104 case typeString:
105 fieldsize = bindField->length;
106 bindField->targetvalue = malloc(fieldsize);
107 break;
108 case typeDate:
109 fieldsize = sizeof(DATE_STRUCT);
110 bindField->targetvalue = malloc(sizeof(DATE_STRUCT));
111 break;
112 case typeTime:
113 fieldsize = sizeof(TIME_STRUCT);
114 bindField->targetvalue = malloc(sizeof(TIME_STRUCT));
115 break;
116 case typeTimeStamp:
117 fieldsize = sizeof(TIMESTAMP_STRUCT);
118 bindField->targetvalue = malloc(sizeof(TIMESTAMP_STRUCT));
119 break;
120 default:
121 bindField->targetvalue = AllDataType::alloc(bindField->type, cLength);
122 break;
125 //retValue = SQLBindParameter(hstmt, icol, SQL_PARAM_INPUT,
126 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLBindParameterPtr)(hstmt, icol, SQL_PARAM_INPUT,
127 AllDataType::convertToSQL_C_Type(bindField->type,tdbname),
128 AllDataType::convertToSQLType(bindField->type), fieldsize, scale, bindField->targetvalue,
129 fieldsize, &paramlen[icol]);
130 if (retValue) return ErrBadCall;
131 paramList.append(bindField);
132 icol++;
134 //TODO::deallocate memory and remove elements from list in case of any
135 //failure in any of the above ODBC functions
136 logFinest(Conf::logger, "Statement prepared %s", stmtstr);
137 return OK;
140 bool SqlOdbcStatement::isSelect()
142 //TODO
143 return isSelStmt;
146 DbRetVal SqlOdbcStatement::execute(int &rowsAffected)
148 DbRetVal rv = OK;
149 if (!isPrepared) return ErrNotPrepared;
150 int retValue=0;
151 ListIterator iter = paramList.getIterator();
152 BindSqlField *bindField = NULL;
153 int col = 0;
154 while (iter.hasElement())
156 bindField = (BindSqlField*)iter.nextElement();
157 if(paramlen[++col] == SQL_NULL_DATA){
158 ::free(bindField->targetvalue);
159 bindField->targetvalue = NULL;
160 continue;
162 switch(bindField->type)
164 case typeDate: {
165 Date *dtCSQL = (Date*) bindField->value;
166 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bindField->targetvalue;
167 dtTarget->year= dtCSQL->year();
168 dtTarget->month= dtCSQL->month();
169 dtTarget->day = dtCSQL->dayOfMonth();
170 break;
172 case typeTime: {
173 Time *dtCSQL = (Time*) bindField->value;
174 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bindField->targetvalue;
175 dtTarget->hour = dtCSQL->hours();
176 dtTarget->minute = dtCSQL->minutes();
177 dtTarget->second = dtCSQL->seconds();
178 break;
180 case typeTimeStamp: {
181 TimeStamp *dtCSQL = (TimeStamp*) bindField->value;
182 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bindField->targetvalue;
183 dtTarget->year= dtCSQL->year();
184 dtTarget->month= dtCSQL->month();
185 dtTarget->day = dtCSQL->dayOfMonth();
186 dtTarget->hour = dtCSQL->hours();
187 dtTarget->minute = dtCSQL->minutes();
188 dtTarget->second = dtCSQL->seconds();
189 break;
191 default: {
192 AllDataType::cachecopyVal(bindField->targetvalue, bindField->value,
193 bindField->type, bindField->length);
194 break;
198 //int retValue = SQLExecute (hstmt);
199 if(isProcedureCallStmt)
201 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLExecutePtr) (hstmt);
202 if ((retValue != SQL_SUCCESS) && (retValue != SQL_SUCCESS_WITH_INFO )) {
203 return ErrBadCall;
205 rv = resolveForBindField(hstmt);
206 if(rv!=OK) return rv;
207 logFinest(Conf::logger, "Procedure executed");
208 }else{
209 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLExecutePtr) (hstmt);
210 if ((retValue != SQL_SUCCESS) && (retValue != SQL_SUCCESS_WITH_INFO )) {
211 // setErrorState(hstmt);
212 return ErrBadCall;
214 logFinest(Conf::logger, "Statement executed");
216 //retValue=SQLRowCount(hstmt,(SQLINTEGER*)&rowsAffected);
217 retValue= (*SqlOdbcConnection::ODBCFuncPtrs.SQLRowCountPtr)(hstmt,(SQLINTEGER*)&rowsAffected);
218 if(isSelStmt) rowsAffected = 0;
219 return rv;
222 DbRetVal SqlOdbcStatement::bindParam(int pos, void* value)
224 DbRetVal rv = OK;
225 printError(ErrWarning, "Deprecated. Use setParamXXX instead\n");
226 return rv;
229 DbRetVal SqlOdbcStatement::bindField(int pos, void* value)
231 if (!isPrepared) return OK;
232 BindSqlProjectField *bindField = (BindSqlProjectField*)bindList.get(pos);
233 if (NULL == bindField)
235 printError(ErrBadArg, "Could not get the projection list. Should be called only for SELECT statement");
236 return ErrBadArg;
238 bindField->value = value;
239 return OK;
242 //void SqlOdbcStatement::setNullInfo(Table *table)
243 void SqlOdbcStatement::setNullInfo(AbsSqlStatement *stmt)
245 int fldpos=0;
246 while(fldpos < totalFld)
248 if(len[++fldpos] == SQL_NULL_DATA)
250 stmt->setNull(fldpos);
255 void* SqlOdbcStatement::fetch()
257 if (!isPrepared) return NULL;
258 //int retValue = SQLFetch (hstmt);
259 int retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLFetchPtr) (hstmt);
260 if (retValue) return NULL;
261 ListIterator iter = bindList.getIterator();
262 BindSqlProjectField *bindField = NULL;
263 void *ptrToFirstField = NULL;
264 int icol=0;
265 while (iter.hasElement())
267 bindField = (BindSqlProjectField*)iter.nextElement();
268 if (ptrToFirstField == NULL) ptrToFirstField=bindField->value;
269 if(len[++icol] == SQL_NULL_DATA)
271 if(bindField->value) AllDataType::memoryset(bindField->value,bindField->type);
272 continue;
274 if( isSelStmt && NULL == bindField->value )
276 if (ptrToFirstField == NULL) ptrToFirstField=bindField->targetvalue;
277 continue;
279 switch(bindField->type)
281 case typeDate: {
282 Date *dtCSQL = (Date*) bindField->value;
283 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bindField->targetvalue;
284 dtCSQL->set(dtTarget->year,dtTarget->month,dtTarget->day);
285 break;
287 case typeTime: {
288 Time *dtCSQL = (Time*) bindField->value;
289 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bindField->targetvalue;
290 dtCSQL->set(dtTarget->hour,dtTarget->minute,dtTarget->second);
291 break;
293 case typeTimeStamp: {
294 TimeStamp *dtCSQL = (TimeStamp*) bindField->value;
295 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bindField->targetvalue;
296 dtCSQL->setDate(dtTarget->year,dtTarget->month,dtTarget->day);
297 dtCSQL->setTime(dtTarget->hour,dtTarget->minute,
298 dtTarget->second, 0);//dtTarget->fraction);
299 break;
301 default: {
302 AllDataType::cachecopyVal(bindField->value, bindField->targetvalue,
303 bindField->type, bindField->length,tdbname);
304 break;
308 return ptrToFirstField;
311 void* SqlOdbcStatement::fetch(DbRetVal &rv)
313 if (!isPrepared) return NULL;
314 //int retValue = SQLFetch (hstmt);
315 int retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLFetchPtr) (hstmt);
316 if (retValue) { rv = OK; return NULL; }
317 ListIterator iter = bindList.getIterator();
318 BindSqlProjectField *bindField = NULL;
319 void *ptrToFirstField = NULL;
320 int icol=0;
321 while (iter.hasElement())
323 bindField = (BindSqlProjectField*)iter.nextElement();
324 if (ptrToFirstField == NULL) ptrToFirstField=bindField->value;
325 if(len[++icol] == SQL_NULL_DATA)
327 if(bindField->value) AllDataType::memoryset(bindField->value,bindField->type);
328 continue;
330 if( isSelStmt && NULL == bindField->value )
332 if (ptrToFirstField == NULL) ptrToFirstField=bindField->targetvalue;
333 continue;
335 switch(bindField->type)
337 case typeDate: {
338 Date *dtCSQL = (Date*) bindField->value;
339 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bindField->targetvalue;
340 dtCSQL->set(dtTarget->year,dtTarget->month,dtTarget->day);
341 break;
343 case typeTime: {
344 Time *dtCSQL = (Time*) bindField->value;
345 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bindField->targetvalue;
346 dtCSQL->set(dtTarget->hour,dtTarget->minute,dtTarget->second);
347 break;
349 case typeTimeStamp: {
350 TimeStamp *dtCSQL = (TimeStamp*) bindField->value;
351 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bindField->targetvalue;
352 dtCSQL->setDate(dtTarget->year,dtTarget->month,dtTarget->day);
353 dtCSQL->setTime(dtTarget->hour,dtTarget->minute,
354 dtTarget->second, 0);// dtTarget->fraction);
355 break;
357 default: {
358 AllDataType::cachecopyVal(bindField->value, bindField->targetvalue, bindField->type, bindField->length, tdbname);
359 break;
363 return ptrToFirstField;
366 void* SqlOdbcStatement::fetchAndPrint(bool SQL)
368 if (!isPrepared) return NULL;
369 //int retValue = SQLFetch (hstmt);
370 int retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLFetchPtr) (hstmt);
371 if (retValue) return NULL;
372 ListIterator iter = bindList.getIterator();
373 BindSqlProjectField *bindField = NULL;
374 void *ptrToFirstField = NULL;
375 int icol=1;
376 while (iter.hasElement())
379 bindField = (BindSqlProjectField*)iter.nextElement();
380 if (ptrToFirstField == NULL) ptrToFirstField=bindField->targetvalue;
381 if(len[icol++] == SQL_NULL_DATA)
383 printf("NULL");
384 continue;
386 switch(bindField->type)
388 case typeDate: {
389 Date dtCSQL;
390 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bindField->targetvalue;
391 dtCSQL.set(dtTarget->year,dtTarget->month,dtTarget->day);
392 AllDataType::printVal(&dtCSQL, bindField->type, bindField->length);
393 break;
395 case typeTime: {
396 Time dtCSQL;
397 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bindField->targetvalue;
398 dtCSQL.set(dtTarget->hour,dtTarget->minute,dtTarget->second);
399 AllDataType::printVal(&dtCSQL, bindField->type, bindField->length);
400 break;
402 case typeTimeStamp: {
403 TimeStamp dtCSQL;
404 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bindField->targetvalue;
405 dtCSQL.setDate(dtTarget->year,dtTarget->month,dtTarget->day);
406 dtCSQL.setTime(dtTarget->hour,dtTarget->minute,
407 dtTarget->second, 0);//dtTarget->fraction);
408 AllDataType::printVal(&dtCSQL, bindField->type, bindField->length);
409 break;
411 default: {
412 AllDataType::printVal(bindField->targetvalue,
413 bindField->type, bindField->length,tdbname);
414 break;
417 printf("\t");
419 return ptrToFirstField;
422 void* SqlOdbcStatement::next()
424 return fetch();
427 DbRetVal SqlOdbcStatement::close()
429 if (!isPrepared) return OK;
430 (*SqlOdbcConnection::ODBCFuncPtrs.SQLCloseCursorPtr)(hstmt);
431 logFinest(Conf::logger, "CloseCursor");
432 return OK;
434 bool SqlOdbcStatement::chechStmtType(char *buf)
436 char c;
437 while(1)
439 c=*buf;
440 if(c !=' ') break;
441 buf++;
443 if (strncasecmp (buf, "SELECT", 6) == 0) { return true;}
444 return false;
446 void* SqlOdbcStatement::getFieldValuePtr( int pos )
449 ListIterator biter = bindList.getIterator();
450 BindSqlProjectField *elem = NULL;
451 int count =0;
452 while (biter.hasElement())
454 elem = (BindSqlProjectField*) biter.nextElement();
455 if (count == pos)
457 if(elem->value == NULL)
459 switch(elem->type)
461 case typeDate: {
462 Date *dtCSQL=(Date *) elem->jdbcBindValue;
463 DATE_STRUCT *dtTarget = (DATE_STRUCT*) elem->targetvalue;
464 dtCSQL->set(dtTarget->year,dtTarget->month,dtTarget->day);
465 return dtCSQL;
467 case typeTime: {
468 Time *dtCSQL = (Time *) elem->jdbcBindValue;
469 TIME_STRUCT *dtTarget = (TIME_STRUCT*) elem->targetvalue;
470 dtCSQL->set(dtTarget->hour,dtTarget->minute,dtTarget->second);
471 return dtCSQL;
473 case typeTimeStamp: {
474 TimeStamp *dtCSQL= (TimeStamp *) elem->jdbcBindValue;
475 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) elem->targetvalue;
476 dtCSQL->setDate(dtTarget->year,dtTarget->month,dtTarget->day);
477 dtCSQL->setTime(dtTarget->hour,dtTarget->minute,dtTarget->second, 0);//dtTarget->fraction);
478 return dtCSQL;
482 return elem->targetvalue;
484 count++;
486 return NULL;
489 void SqlOdbcStatement::getProjFieldType(int *data)
491 ListIterator biter = bindList.getIterator();
492 BindSqlProjectField *elem = NULL;
493 int i = 1;
494 while (biter.hasElement())
496 elem = (BindSqlProjectField*) biter.nextElement();
497 if((tdbname == postgres) && typeLongLong == elem->type)
498 data[i++] = typeString;
499 else
500 data[i++] = elem->type;
504 void* SqlOdbcStatement::getFieldValuePtr( char *name )
506 ListIterator biter = bindList.getIterator();
507 BindSqlProjectField *elem = NULL;
508 int count =0;
509 while (biter.hasElement())
511 elem = (BindSqlProjectField*) biter.nextElement();
512 if ( strcpy(elem->fName,name) == 0 )
514 return elem->targetvalue;
517 return NULL;
520 int SqlOdbcStatement::noOfProjFields()
522 if (!isPrepared) return 0;
523 return bindList.size();
526 int SqlOdbcStatement::noOfParamFields()
528 if (!isPrepared) return 0;
529 return paramList.size();
532 DbRetVal SqlOdbcStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
534 ListIterator biter = bindList.getIterator();
535 BindSqlProjectField *elem = NULL;
536 int count =0;
537 while (biter.hasElement())
539 elem = (BindSqlProjectField*) biter.nextElement();
540 if (count == projpos-1)
542 strcpy(fInfo->fldName, elem->fName);
543 fInfo->length = elem->length;
544 fInfo->type =elem->type;
545 return OK;
547 count++;
549 return ErrNotFound;
552 DbRetVal SqlOdbcStatement::getParamFldInfo (int parampos, FieldInfo *&fInfo)
554 ListIterator biter = paramList.getIterator();
555 BindSqlField *elem = NULL;
556 int count =0;
557 while (biter.hasElement())
559 elem = (BindSqlField*) biter.nextElement();
560 if (count == parampos-1)
562 fInfo->length = elem->length;
563 fInfo->type =elem->type;
564 return OK;
566 count++;
568 return ErrNotFound;
571 DbRetVal SqlOdbcStatement::free()
573 if(!isPrepared) return OK;
574 ListIterator biter = bindList.getIterator();
575 BindSqlProjectField *elem = NULL;
576 while (biter.hasElement())
578 elem = (BindSqlProjectField*) biter.nextElement();
579 if(elem->targetvalue)
580 ::free(elem->targetvalue);
581 if(elem->jdbcBindValue)
582 ::free(elem->jdbcBindValue);
583 delete elem;
585 bindList.reset();
586 ListIterator piter = paramList.getIterator();
587 BindSqlField *bindField = NULL;
588 while (piter.hasElement())
590 bindField = (BindSqlField*) piter.nextElement();
591 ::free(bindField->value);
592 ::free(bindField->targetvalue);
593 delete bindField;
595 paramList.reset();
596 if(len){ ::free(len); len = NULL;}
597 if(paramlen) {::free(paramlen); paramlen = NULL;}
598 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_STMT, hstmt);
599 isPrepared = false;
600 isProcedureCallStmt = false;
601 logFinest(Conf::logger, "Statement Freed");
602 return OK;
604 void SqlOdbcStatement::setShortParam(int paramPos, short value)
606 if (!isPrepared) return ;
607 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
608 AllDataType::convertToString(bindField->value, &value, typeShort, 0,tdbname);
609 return;
611 void SqlOdbcStatement::setIntParam(int paramPos, int value)
613 if (!isPrepared) return ;
614 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
615 //Note: MySQL Bug
616 //Bug #1382 SQLDescribeParam returns the same type information, varchar
617 AllDataType::convertToString(bindField->value, &value, typeInt,0,tdbname);
618 return;
621 void SqlOdbcStatement::setLongParam(int paramPos, long value)
623 if (!isPrepared) return ;
624 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
625 //Note: MySQL Bug
626 //Bug #1382 SQLDescribeParam returns the same type information, varchar
627 AllDataType::convertToString(bindField->value, &value, typeLong,0,tdbname);
628 return;
631 void SqlOdbcStatement::setLongLongParam(int paramPos, long long value)
633 if (!isPrepared) return ;
634 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
635 AllDataType::convertToString(bindField->value, &value, typeLongLong,0,tdbname);
636 return;
638 void SqlOdbcStatement::setByteIntParam(int paramPos, ByteInt value)
640 if (!isPrepared) return ;
641 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
642 AllDataType::convertToString(bindField->value, &value, typeByteInt,0,tdbname);
643 return;
645 void SqlOdbcStatement::setFloatParam(int paramPos, float value)
647 if (!isPrepared) return ;
648 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
649 AllDataType::convertToString(bindField->value, &value, typeFloat,0, tdbname);
650 return;
652 void SqlOdbcStatement::setDoubleParam(int paramPos, double value)
654 if (!isPrepared) return ;
655 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
656 AllDataType::convertToString(bindField->value, &value, typeDouble,0,tdbname);
657 return;
659 void SqlOdbcStatement::setStringParam(int paramPos, char *value)
661 if (!isPrepared) return ;
662 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
663 if (bindField->type != typeString) return;
664 char *dest = (char*)bindField->value;
665 strncpy(dest, value, bindField->length);
666 dest[ bindField->length - 1] ='\0';
667 return;
669 void SqlOdbcStatement::setDateParam(int paramPos, Date value)
671 if (!isPrepared) return ;
672 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
673 AllDataType::convertToString(bindField->value, &value, typeDate,0,tdbname);
674 return;
676 void SqlOdbcStatement::setTimeParam(int paramPos, Time value)
678 if (!isPrepared) return ;
679 BindSqlField *bindField = (BindSqlField*)paramList.get(paramPos);
680 AllDataType::convertToString(bindField->value, &value, typeTime,0,tdbname);
681 return;
683 void SqlOdbcStatement::setTimeStampParam(int paramPos, TimeStamp value)
685 if (!isPrepared) return ;
686 BindSqlField *bindField = (BindSqlField*) paramList.get(paramPos);
687 AllDataType::convertToString(bindField->value, &value, typeTimeStamp,0, tdbname);
688 return;
690 void SqlOdbcStatement::setBinaryParam(int paramPos, void *value, int length)
692 if (!isPrepared) return;
693 BindSqlField *bindField = (BindSqlField*) paramList.get(paramPos);
694 AllDataType::convertToString(bindField->value, value, typeBinary, bindField->length,tdbname);
695 return;
698 void SqlOdbcStatement::getPrimaryKeyFieldName(char *tablename, char *pkfieldname)
700 if (pkfieldname == NULL) return;
701 SQLCHAR outstr[1024];
702 SQLSMALLINT outstrlen;
703 int retValue =0;
704 SQLHENV henv;
705 SQLHDBC hdbc;
706 SQLHSTMT hstmt;
707 SqlOdbcConnection *conn = (SqlOdbcConnection*)con;
708 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
709 if (retValue) {
710 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
712 (*SqlOdbcConnection::ODBCFuncPtrs.SQLSetEnvAttrPtr)(henv, SQL_ATTR_ODBC_VERSION,(void *) SQL_OV_ODBC3, 0);
713 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_DBC, henv, &hdbc);
714 if (retValue) {
715 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
717 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLDriverConnectPtr)(hdbc, NULL, (SQLCHAR*)conn->dsn, SQL_NTS, outstr, sizeof(outstr), &outstrlen,SQL_DRIVER_NOPROMPT);
718 if (SQL_SUCCEEDED(retValue)) {
719 printDebug(DM_Gateway, "Connected to target database using dsn = %s\n", conn->dsn);
720 } else {
721 printError(ErrSysInit, "Failed to connect to target database\n");
723 retValue=(*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_STMT, hdbc, &hstmt);
724 if (retValue) {
725 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
727 char columnname[IDENTIFIER_LENGTH];
728 retValue=(*SqlOdbcConnection::ODBCFuncPtrs.SQLPrimaryKeysPtr)(hstmt, NULL, SQL_NTS, NULL, SQL_NTS, (SQLCHAR*) tablename, SQL_NTS);
729 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLBindColPtr)(hstmt, 4, SQL_C_CHAR,columnname, 129,NULL);
730 bool isPkExists=false;
731 if((*SqlOdbcConnection::ODBCFuncPtrs.SQLFetchPtr)( hstmt ) == SQL_SUCCESS)
733 Util::str_tolower(columnname);
734 strcpy(pkfieldname, columnname);
735 isPkExists = true;
737 tdbname = conn->getTrDbName();
738 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_STMT, hstmt);
739 (*SqlOdbcConnection::ODBCFuncPtrs.SQLDisconnectPtr)(hdbc);
740 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_DBC, hdbc);
741 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_ENV, henv);
742 return;
745 bool SqlOdbcStatement::isFldNull(int pos)
747 if( len[pos] == SQL_NULL_DATA )
748 return true;
749 else
750 return false;
752 bool SqlOdbcStatement::isFldNull(char *name)
754 ListIterator iter = bindList.getIterator();
755 BindSqlProjectField *bindField = NULL;
756 int pos=1;
757 while (iter.hasElement())
759 bindField = (BindSqlProjectField*)iter.nextElement();
760 if(strcmp(name,bindField->fName)==0)
762 break;
764 pos++;
766 if( len[pos] == SQL_NULL_DATA )
767 return true;
768 else
769 return false;
772 void SqlOdbcStatement::setNull(int pos)
774 paramlen[pos] = SQL_NULL_DATA ;
777 bool SqlOdbcStatement::isTableExists( char *name)
780 SQLCHAR outstr[1024];
781 SQLSMALLINT outstrlen;
782 int retValue =0;
783 SQLHENV henv;
784 SQLHDBC hdbc;
785 SQLHSTMT hstmt;
786 SqlOdbcConnection *conn = (SqlOdbcConnection*)con;
787 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
788 if (retValue) {
789 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
792 (*SqlOdbcConnection::ODBCFuncPtrs.SQLSetEnvAttrPtr)(henv, SQL_ATTR_ODBC_VERSION,(void *) SQL_OV_ODBC3, 0);
793 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_DBC, henv, &hdbc);
794 if (retValue) {
795 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
797 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLDriverConnectPtr)(hdbc, NULL, (SQLCHAR*)conn->dsn, SQL_NTS, outstr, sizeof(outstr), &outstrlen,SQL_DRIVER_NOPROMPT);
798 if (SQL_SUCCEEDED(retValue)) {
799 printDebug(DM_Gateway, "Connected to target database using dsn = %s\n", conn->dsn);
800 } else {
801 printError(ErrSysInit, "Failed to connect to target database\n");
804 retValue=(*SqlOdbcConnection::ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_STMT, hdbc, &hstmt);
805 if (retValue) {
806 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
808 char tablename[IDENTIFIER_LENGTH];
809 //retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLTablesPtr)(hstmt, (SQLCHAR*)"test", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"TABLE", SQL_NTS );
810 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLTablesPtr)(hstmt, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS );
811 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLBindColPtr)(hstmt,3,SQL_C_CHAR,tablename,sizeof(tablename),NULL);
812 while(SQL_SUCCEEDED(retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLFetchPtr)(hstmt)))
814 if(strcmp(tablename,name)==0){
815 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_STMT, hstmt);
816 (*SqlOdbcConnection::ODBCFuncPtrs.SQLDisconnectPtr)(hdbc);
817 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_DBC, hdbc);
818 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_ENV, henv);
819 return true;
823 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_STMT, hstmt);
824 (*SqlOdbcConnection::ODBCFuncPtrs.SQLDisconnectPtr)(hdbc);
825 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_DBC, hdbc);
826 (*SqlOdbcConnection::ODBCFuncPtrs.SQLFreeHandlePtr)(SQL_HANDLE_ENV, henv);
827 return false;
829 void SqlOdbcStatement::setErrorState(SQLHSTMT hStmt)
831 SQLINTEGER i = 0;
832 SQLINTEGER native;
833 SQLCHAR state[ 7 ];
834 SQLCHAR text[256];
835 SQLSMALLINT len;
836 SQLRETURN ret;
837 ret = (*SqlOdbcConnection::ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_STMT, hStmt, ++i,
838 state, &native, text, sizeof(text), &len );
840 if (SQL_SUCCEEDED(ret)){
841 printf("%s:%ld:%ld:%s\n", state, i, native, text);
842 strcpy(errState,(char*)state);
846 DbRetVal SqlOdbcStatement::resolveForBindField(SQLHSTMT hstmt)
848 short totalFields=0;
849 int retValue = 0;
850 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLNumResultColsPtr) (hstmt, &totalFields);
851 if (retValue){ return ErrBadCall; }
852 BindSqlProjectField *bindProjField = NULL;
853 UWORD icol;
854 UCHAR colName[IDENTIFIER_LENGTH];
855 SWORD colNameMax;
856 SWORD nameLength;
857 SWORD colType;
858 SQLULEN colLength;
859 SWORD scale;
860 SWORD nullable;
861 icol = 1; colNameMax = IDENTIFIER_LENGTH;
862 if(totalFields != 0)
864 if(isProcedureCallStmt) isSelStmt = true;
865 len = (SQLINTEGER *)malloc((totalFields+1)*sizeof(SQLINTEGER));
866 for(int i=0;i<=totalFields;i++) { len[i] = SQL_NTS ;}
868 while (icol <= totalFields)
870 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLDescribeColPtr)(hstmt, icol, colName, colNameMax,
871 &nameLength, &colType, &colLength,
872 &scale, &nullable);
873 if (retValue) return ErrBadCall;
874 bindProjField = new BindSqlProjectField();
875 strcpy(bindProjField->fName, (char*)colName);
876 bindProjField->type = AllDataType::convertFromSQLType(colType,colLength,scale,tdbname);
877 bindProjField->length = AllDataType::size(bindProjField->type, colLength+1);
878 bindProjField->value = NULL;
879 bindProjField->targetvalue = NULL;
880 int fieldsize =0;
881 if(tdbname==postgres && -5 == colType) {
882 bindProjField->targetvalue = AllDataType::alloc(typeString, 128);
883 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLBindColPtr)(hstmt, icol,
884 AllDataType::convertToSQLType(typeString),
885 bindProjField->targetvalue, 128, &len[icol]);
886 }else{
887 switch(bindProjField->type)
889 case typeString:
890 fieldsize = colLength+1;
891 bindProjField->targetvalue = malloc(fieldsize);
892 break;
893 case typeDate:
894 fieldsize = sizeof(DATE_STRUCT);
895 bindProjField->targetvalue = malloc(sizeof(DATE_STRUCT));
896 bindProjField->jdbcBindValue = AllDataType::alloc(typeDate);
897 break;
898 case typeTime:
899 fieldsize = sizeof(TIME_STRUCT);
900 bindProjField->targetvalue = malloc(sizeof(TIME_STRUCT));
901 bindProjField->jdbcBindValue = AllDataType::alloc(typeTime);
902 break;
903 case typeTimeStamp:
904 fieldsize = sizeof(TIMESTAMP_STRUCT);
905 bindProjField->targetvalue = malloc(sizeof(TIMESTAMP_STRUCT));
906 bindProjField->jdbcBindValue = AllDataType::alloc(typeTimeStamp);
907 break;
908 default:
909 bindProjField->targetvalue = AllDataType::alloc(bindProjField->type, bindProjField->length);
911 retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLBindColPtr)(hstmt, icol,
912 AllDataType::convertToSQL_C_Type(bindProjField->type,tdbname),
913 bindProjField->targetvalue, fieldsize, &len[icol]);
915 if (retValue) return ErrBadCall;
916 bindList.append(bindProjField);
917 icol++;
919 totalFld = totalFields;
920 return OK;