1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
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. *
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. *
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
)
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
;
39 DbRetVal
SqlOdbcStatement::prepare(char *stmtstr
)
42 if (innerStmt
) rv
= ErrBadCall
;
43 if (rv
!= OK
) return rv
;
46 isProcedureCallStmt
= false;
47 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
48 //retValue=SQLAllocHandle (SQL_HANDLE_STMT, conn->dbHdl, &hstmt);
49 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, conn
->dbHdl
, &hstmt
);
50 if (retValue
) return ErrBadCall
;
51 SQLCHAR
* sstr
= (SQLCHAR
*)stmtstr
;
52 //retValue = SQLPrepare (hstmt, sstr, SQL_NTS);
53 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLPreparePtr
) (hstmt
, sstr
, SQL_NTS
);
55 // setErrorState(hstmt);
58 isSelStmt
=chechStmtType(stmtstr
);
60 if(strstr(stmtstr
,"call ")!=NULL
|| strstr(stmtstr
,"CALL ")!=NULL
)
62 isProcedureCallStmt
=true;
65 tdbname
= conn
->getTrDbName();
66 rv
= resolveForBindField(hstmt
);
72 BindSqlField
*bindField
;
73 //retValue = SQLNumParams (hstmt, &totalFields);
74 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLNumParamsPtr
) (hstmt
, &totalFields
);
75 if (retValue
) return ErrBadCall
;
76 icol
= 1; colNameMax
= IDENTIFIER_LENGTH
;
82 paramlen
=(SQLINTEGER
*) malloc((totalFields
+1)*sizeof(SQLINTEGER
));
83 for(int i
=0;i
<=totalFields
;i
++) { paramlen
[i
] = SQL_NTS
; }
86 while (icol
<= totalFields
)
88 //retValue = SQLDescribeParam(hstmt, icol, &cType, &cLength,
90 //Bug #1382 SQLDescribeParam returns the same type information
92 bindField
= new BindSqlField();
93 bindField
->type
= typeString
;
94 bindField
->length
= 512;
95 bindField
->value
= AllDataType::alloc(bindField
->type
, bindField
->length
);
96 bindField
->targetvalue
= NULL
;
98 switch(bindField
->type
)
101 fieldsize
= bindField
->length
;
102 bindField
->targetvalue
= malloc(fieldsize
);
105 fieldsize
= sizeof(DATE_STRUCT
);
106 bindField
->targetvalue
= malloc(sizeof(DATE_STRUCT
));
109 fieldsize
= sizeof(TIME_STRUCT
);
110 bindField
->targetvalue
= malloc(sizeof(TIME_STRUCT
));
113 fieldsize
= sizeof(TIMESTAMP_STRUCT
);
114 bindField
->targetvalue
= malloc(sizeof(TIMESTAMP_STRUCT
));
117 bindField
->targetvalue
= AllDataType::alloc(bindField
->type
, cLength
);
121 //retValue = SQLBindParameter(hstmt, icol, SQL_PARAM_INPUT,
122 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindParameterPtr
)(hstmt
, icol
, SQL_PARAM_INPUT
,
123 AllDataType::convertToSQL_C_Type(bindField
->type
,tdbname
),
124 AllDataType::convertToSQLType(bindField
->type
), fieldsize
, scale
, bindField
->targetvalue
,
125 fieldsize
, ¶mlen
[icol
]);
126 if (retValue
) return ErrBadCall
;
127 paramList
.append(bindField
);
130 //TODO::deallocate memory and remove elements from list in case of any
131 //failure in any of the above ODBC functions
135 bool SqlOdbcStatement::isSelect()
141 DbRetVal
SqlOdbcStatement::execute(int &rowsAffected
)
144 if (!isPrepared
) return ErrNotPrepared
;
146 ListIterator iter
= paramList
.getIterator();
147 BindSqlField
*bindField
= NULL
;
149 while (iter
.hasElement())
151 bindField
= (BindSqlField
*)iter
.nextElement();
152 if(paramlen
[++col
] == SQL_NULL_DATA
){
153 ::free(bindField
->targetvalue
);
154 bindField
->targetvalue
= NULL
;
157 switch(bindField
->type
)
160 Date
*dtCSQL
= (Date
*) bindField
->value
;
161 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
162 dtTarget
->year
= dtCSQL
->year();
163 dtTarget
->month
= dtCSQL
->month();
164 dtTarget
->day
= dtCSQL
->dayOfMonth();
168 Time
*dtCSQL
= (Time
*) bindField
->value
;
169 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
170 dtTarget
->hour
= dtCSQL
->hours();
171 dtTarget
->minute
= dtCSQL
->minutes();
172 dtTarget
->second
= dtCSQL
->seconds();
175 case typeTimeStamp
: {
176 TimeStamp
*dtCSQL
= (TimeStamp
*) bindField
->value
;
177 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) bindField
->targetvalue
;
178 dtTarget
->year
= dtCSQL
->year();
179 dtTarget
->month
= dtCSQL
->month();
180 dtTarget
->day
= dtCSQL
->dayOfMonth();
181 dtTarget
->hour
= dtCSQL
->hours();
182 dtTarget
->minute
= dtCSQL
->minutes();
183 dtTarget
->second
= dtCSQL
->seconds();
187 AllDataType::cachecopyVal(bindField
->targetvalue
, bindField
->value
,
188 bindField
->type
, bindField
->length
);
193 //int retValue = SQLExecute (hstmt);
194 if(isProcedureCallStmt
)
196 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLExecutePtr
) (hstmt
);
197 if ((retValue
!= SQL_SUCCESS
) && (retValue
!= SQL_SUCCESS_WITH_INFO
)) {
200 rv
= resolveForBindField(hstmt
);
201 if(rv
!=OK
) return rv
;
203 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLExecutePtr
) (hstmt
);
204 if ((retValue
!= SQL_SUCCESS
) && (retValue
!= SQL_SUCCESS_WITH_INFO
)) {
205 // setErrorState(hstmt);
209 //retValue=SQLRowCount(hstmt,(SQLINTEGER*)&rowsAffected);
210 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLRowCountPtr
)(hstmt
,(SQLINTEGER
*)&rowsAffected
);
211 if(isSelStmt
) rowsAffected
= 0;
215 DbRetVal
SqlOdbcStatement::bindParam(int pos
, void* value
)
218 printError(ErrWarning
, "Deprecated. Use setParamXXX instead\n");
222 DbRetVal
SqlOdbcStatement::bindField(int pos
, void* value
)
224 if (!isPrepared
) return OK
;
225 BindSqlProjectField
*bindField
= (BindSqlProjectField
*)bindList
.get(pos
);
226 if (NULL
== bindField
)
228 printError(ErrBadArg
, "Could not get the projection list. Should be called only for SELECT statement");
231 bindField
->value
= value
;
235 //void SqlOdbcStatement::setNullInfo(Table *table)
236 void SqlOdbcStatement::setNullInfo(AbsSqlStatement
*stmt
)
239 while(fldpos
< totalFld
)
241 if(len
[++fldpos
] == SQL_NULL_DATA
)
243 stmt
->setNull(fldpos
);
248 void* SqlOdbcStatement::fetch()
250 if (!isPrepared
) return NULL
;
251 //int retValue = SQLFetch (hstmt);
252 int retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
) (hstmt
);
253 if (retValue
) return NULL
;
254 ListIterator iter
= bindList
.getIterator();
255 BindSqlProjectField
*bindField
= NULL
;
256 void *ptrToFirstField
= NULL
;
258 while (iter
.hasElement())
260 bindField
= (BindSqlProjectField
*)iter
.nextElement();
261 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->value
;
262 if(len
[++icol
] == SQL_NULL_DATA
)
264 if(bindField
->value
) AllDataType::memoryset(bindField
->value
,bindField
->type
);
267 if( isSelStmt
&& NULL
== bindField
->value
)
269 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
272 switch(bindField
->type
)
275 Date
*dtCSQL
= (Date
*) bindField
->value
;
276 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
277 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
281 Time
*dtCSQL
= (Time
*) bindField
->value
;
282 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
283 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
286 case typeTimeStamp
: {
287 TimeStamp
*dtCSQL
= (TimeStamp
*) bindField
->value
;
288 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) bindField
->targetvalue
;
289 dtCSQL
->setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
290 dtCSQL
->setTime(dtTarget
->hour
,dtTarget
->minute
,
291 dtTarget
->second
, 0);//dtTarget->fraction);
295 AllDataType::cachecopyVal(bindField
->value
, bindField
->targetvalue
,
296 bindField
->type
, bindField
->length
,tdbname
);
301 return ptrToFirstField
;
304 void* SqlOdbcStatement::fetch(DbRetVal
&rv
)
306 if (!isPrepared
) return NULL
;
307 //int retValue = SQLFetch (hstmt);
308 int retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
) (hstmt
);
309 if (retValue
) { rv
= OK
; return NULL
; }
310 ListIterator iter
= bindList
.getIterator();
311 BindSqlProjectField
*bindField
= NULL
;
312 void *ptrToFirstField
= NULL
;
314 while (iter
.hasElement())
316 bindField
= (BindSqlProjectField
*)iter
.nextElement();
317 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->value
;
318 if(len
[++icol
] == SQL_NULL_DATA
)
320 if(bindField
->value
) AllDataType::memoryset(bindField
->value
,bindField
->type
);
323 if( isSelStmt
&& NULL
== bindField
->value
)
325 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
328 switch(bindField
->type
)
331 Date
*dtCSQL
= (Date
*) bindField
->value
;
332 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
333 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
337 Time
*dtCSQL
= (Time
*) bindField
->value
;
338 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
339 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
342 case typeTimeStamp
: {
343 TimeStamp
*dtCSQL
= (TimeStamp
*) bindField
->value
;
344 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) bindField
->targetvalue
;
345 dtCSQL
->setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
346 dtCSQL
->setTime(dtTarget
->hour
,dtTarget
->minute
,
347 dtTarget
->second
, 0);// dtTarget->fraction);
351 AllDataType::cachecopyVal(bindField
->value
, bindField
->targetvalue
, bindField
->type
, bindField
->length
, tdbname
);
356 return ptrToFirstField
;
359 void* SqlOdbcStatement::fetchAndPrint(bool SQL
)
361 if (!isPrepared
) return NULL
;
362 //int retValue = SQLFetch (hstmt);
363 int retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
) (hstmt
);
364 if (retValue
) return NULL
;
365 ListIterator iter
= bindList
.getIterator();
366 BindSqlProjectField
*bindField
= NULL
;
367 void *ptrToFirstField
= NULL
;
369 while (iter
.hasElement())
372 bindField
= (BindSqlProjectField
*)iter
.nextElement();
373 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
374 if(len
[icol
++] == SQL_NULL_DATA
)
379 switch(bindField
->type
)
383 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
384 dtCSQL
.set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
385 AllDataType::printVal(&dtCSQL
, bindField
->type
, bindField
->length
);
390 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
391 dtCSQL
.set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
392 AllDataType::printVal(&dtCSQL
, bindField
->type
, bindField
->length
);
395 case typeTimeStamp
: {
397 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) bindField
->targetvalue
;
398 dtCSQL
.setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
399 dtCSQL
.setTime(dtTarget
->hour
,dtTarget
->minute
,
400 dtTarget
->second
, 0);//dtTarget->fraction);
401 AllDataType::printVal(&dtCSQL
, bindField
->type
, bindField
->length
);
405 AllDataType::printVal(bindField
->targetvalue
,
406 bindField
->type
, bindField
->length
,tdbname
);
412 return ptrToFirstField
;
415 void* SqlOdbcStatement::next()
420 DbRetVal
SqlOdbcStatement::close()
422 if (!isPrepared
) return OK
;
423 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLCloseCursorPtr
)(hstmt
);
426 bool SqlOdbcStatement::chechStmtType(char *buf
)
435 if (strncasecmp (buf
, "SELECT", 6) == 0) { return true;}
438 void* SqlOdbcStatement::getFieldValuePtr( int pos
)
441 ListIterator biter
= bindList
.getIterator();
442 BindSqlProjectField
*elem
= NULL
;
444 while (biter
.hasElement())
446 elem
= (BindSqlProjectField
*) biter
.nextElement();
449 if(elem
->value
== NULL
)
454 Date
*dtCSQL
=(Date
*) elem
->jdbcBindValue
;
455 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) elem
->targetvalue
;
456 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
460 Time
*dtCSQL
= (Time
*) elem
->jdbcBindValue
;
461 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) elem
->targetvalue
;
462 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
465 case typeTimeStamp
: {
466 TimeStamp
*dtCSQL
= (TimeStamp
*) elem
->jdbcBindValue
;
467 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) elem
->targetvalue
;
468 dtCSQL
->setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
469 dtCSQL
->setTime(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
, 0);//dtTarget->fraction);
474 return elem
->targetvalue
;
481 void SqlOdbcStatement::getProjFieldType(int *data
)
483 ListIterator biter
= bindList
.getIterator();
484 BindSqlProjectField
*elem
= NULL
;
486 while (biter
.hasElement())
488 elem
= (BindSqlProjectField
*) biter
.nextElement();
489 if((tdbname
== postgres
) && typeLongLong
== elem
->type
)
490 data
[i
++] = typeString
;
492 data
[i
++] = elem
->type
;
496 void* SqlOdbcStatement::getFieldValuePtr( char *name
)
498 ListIterator biter
= bindList
.getIterator();
499 BindSqlProjectField
*elem
= NULL
;
501 while (biter
.hasElement())
503 elem
= (BindSqlProjectField
*) biter
.nextElement();
504 if ( strcpy(elem
->fName
,name
) == 0 )
506 return elem
->targetvalue
;
512 int SqlOdbcStatement::noOfProjFields()
514 if (!isPrepared
) return 0;
515 return bindList
.size();
518 int SqlOdbcStatement::noOfParamFields()
520 if (!isPrepared
) return 0;
521 return paramList
.size();
524 DbRetVal
SqlOdbcStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
526 ListIterator biter
= bindList
.getIterator();
527 BindSqlProjectField
*elem
= NULL
;
529 while (biter
.hasElement())
531 elem
= (BindSqlProjectField
*) biter
.nextElement();
532 if (count
== projpos
-1)
534 strcpy(fInfo
->fldName
, elem
->fName
);
535 fInfo
->length
= elem
->length
;
536 fInfo
->type
=elem
->type
;
544 DbRetVal
SqlOdbcStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
546 ListIterator biter
= paramList
.getIterator();
547 BindSqlField
*elem
= NULL
;
549 while (biter
.hasElement())
551 elem
= (BindSqlField
*) biter
.nextElement();
552 if (count
== parampos
-1)
554 fInfo
->length
= elem
->length
;
555 fInfo
->type
=elem
->type
;
563 DbRetVal
SqlOdbcStatement::free()
565 if(!isPrepared
) return OK
;
566 ListIterator biter
= bindList
.getIterator();
567 BindSqlProjectField
*elem
= NULL
;
568 while (biter
.hasElement())
570 elem
= (BindSqlProjectField
*) biter
.nextElement();
571 if(elem
->targetvalue
)
572 ::free(elem
->targetvalue
);
573 if(elem
->jdbcBindValue
)
574 ::free(elem
->jdbcBindValue
);
578 ListIterator piter
= paramList
.getIterator();
579 BindSqlField
*bindField
= NULL
;
580 while (piter
.hasElement())
582 bindField
= (BindSqlField
*) piter
.nextElement();
583 ::free(bindField
->value
);
584 ::free(bindField
->targetvalue
);
588 if(len
){ ::free(len
); len
= NULL
;}
589 if(paramlen
) {::free(paramlen
); paramlen
= NULL
;}
590 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
592 isProcedureCallStmt
= false;
595 void SqlOdbcStatement::setShortParam(int paramPos
, short value
)
597 if (!isPrepared
) return ;
598 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
599 AllDataType::convertToString(bindField
->value
, &value
, typeShort
, 0,tdbname
);
602 void SqlOdbcStatement::setIntParam(int paramPos
, int value
)
604 if (!isPrepared
) return ;
605 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
607 //Bug #1382 SQLDescribeParam returns the same type information, varchar
608 AllDataType::convertToString(bindField
->value
, &value
, typeInt
,0,tdbname
);
612 void SqlOdbcStatement::setLongParam(int paramPos
, long value
)
614 if (!isPrepared
) return ;
615 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
617 //Bug #1382 SQLDescribeParam returns the same type information, varchar
618 AllDataType::convertToString(bindField
->value
, &value
, typeLong
,0,tdbname
);
622 void SqlOdbcStatement::setLongLongParam(int paramPos
, long long value
)
624 if (!isPrepared
) return ;
625 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
626 AllDataType::convertToString(bindField
->value
, &value
, typeLongLong
,0,tdbname
);
629 void SqlOdbcStatement::setByteIntParam(int paramPos
, ByteInt value
)
631 if (!isPrepared
) return ;
632 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
633 AllDataType::convertToString(bindField
->value
, &value
, typeByteInt
,0,tdbname
);
636 void SqlOdbcStatement::setFloatParam(int paramPos
, float value
)
638 if (!isPrepared
) return ;
639 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
640 AllDataType::convertToString(bindField
->value
, &value
, typeFloat
,0, tdbname
);
643 void SqlOdbcStatement::setDoubleParam(int paramPos
, double value
)
645 if (!isPrepared
) return ;
646 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
647 AllDataType::convertToString(bindField
->value
, &value
, typeDouble
,0,tdbname
);
650 void SqlOdbcStatement::setStringParam(int paramPos
, char *value
)
652 if (!isPrepared
) return ;
653 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
654 if (bindField
->type
!= typeString
) return;
655 char *dest
= (char*)bindField
->value
;
656 strncpy(dest
, value
, bindField
->length
);
657 dest
[ bindField
->length
- 1] ='\0';
660 void SqlOdbcStatement::setDateParam(int paramPos
, Date value
)
662 if (!isPrepared
) return ;
663 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
664 AllDataType::convertToString(bindField
->value
, &value
, typeDate
,0,tdbname
);
667 void SqlOdbcStatement::setTimeParam(int paramPos
, Time value
)
669 if (!isPrepared
) return ;
670 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
671 AllDataType::convertToString(bindField
->value
, &value
, typeTime
,0,tdbname
);
674 void SqlOdbcStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
676 if (!isPrepared
) return ;
677 BindSqlField
*bindField
= (BindSqlField
*) paramList
.get(paramPos
);
678 AllDataType::convertToString(bindField
->value
, &value
, typeTimeStamp
,0, tdbname
);
681 void SqlOdbcStatement::setBinaryParam(int paramPos
, void *value
, int length
)
683 if (!isPrepared
) return;
684 BindSqlField
*bindField
= (BindSqlField
*) paramList
.get(paramPos
);
685 AllDataType::convertToString(bindField
->value
, value
, typeBinary
, bindField
->length
,tdbname
);
689 void SqlOdbcStatement::getPrimaryKeyFieldName(char *tablename
, char *pkfieldname
)
691 if (pkfieldname
== NULL
) return;
692 SQLCHAR outstr
[1024];
693 SQLSMALLINT outstrlen
;
698 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
699 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
701 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
703 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLSetEnvAttrPtr
)(henv
, SQL_ATTR_ODBC_VERSION
,(void *) SQL_OV_ODBC3
, 0);
704 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_DBC
, henv
, &hdbc
);
706 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
708 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDriverConnectPtr
)(hdbc
, NULL
, (SQLCHAR
*)conn
->dsn
, SQL_NTS
, outstr
, sizeof(outstr
), &outstrlen
,SQL_DRIVER_NOPROMPT
);
709 if (SQL_SUCCEEDED(retValue
)) {
710 printDebug(DM_Gateway
, "Connected to target database using dsn = %s\n", conn
->dsn
);
712 printError(ErrSysInit
, "Failed to connect to target database\n");
714 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
716 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
718 char columnname
[IDENTIFIER_LENGTH
];
719 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLPrimaryKeysPtr
)(hstmt
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, (SQLCHAR
*) tablename
, SQL_NTS
);
720 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, 4, SQL_C_CHAR
,columnname
, 129,NULL
);
721 bool isPkExists
=false;
722 if((*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
)( hstmt
) == SQL_SUCCESS
)
724 Util::str_tolower(columnname
);
725 strcpy(pkfieldname
, columnname
);
728 tdbname
= conn
->getTrDbName();
729 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
730 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
731 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
732 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
736 bool SqlOdbcStatement::isFldNull(int pos
)
738 if( len
[pos
] == SQL_NULL_DATA
)
743 bool SqlOdbcStatement::isFldNull(char *name
)
745 ListIterator iter
= bindList
.getIterator();
746 BindSqlProjectField
*bindField
= NULL
;
748 while (iter
.hasElement())
750 bindField
= (BindSqlProjectField
*)iter
.nextElement();
751 if(strcmp(name
,bindField
->fName
)==0)
757 if( len
[pos
] == SQL_NULL_DATA
)
763 void SqlOdbcStatement::setNull(int pos
)
765 paramlen
[pos
] = SQL_NULL_DATA
;
768 bool SqlOdbcStatement::isTableExists( char *name
)
771 SQLCHAR outstr
[1024];
772 SQLSMALLINT outstrlen
;
777 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
778 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
780 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
783 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLSetEnvAttrPtr
)(henv
, SQL_ATTR_ODBC_VERSION
,(void *) SQL_OV_ODBC3
, 0);
784 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_DBC
, henv
, &hdbc
);
786 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
788 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDriverConnectPtr
)(hdbc
, NULL
, (SQLCHAR
*)conn
->dsn
, SQL_NTS
, outstr
, sizeof(outstr
), &outstrlen
,SQL_DRIVER_NOPROMPT
);
789 if (SQL_SUCCEEDED(retValue
)) {
790 printDebug(DM_Gateway
, "Connected to target database using dsn = %s\n", conn
->dsn
);
792 printError(ErrSysInit
, "Failed to connect to target database\n");
795 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
797 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
799 char tablename
[IDENTIFIER_LENGTH
];
800 //retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLTablesPtr)(hstmt, (SQLCHAR*)"test", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"TABLE", SQL_NTS );
801 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLTablesPtr
)(hstmt
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, NULL
, SQL_NTS
);
802 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
,3,SQL_C_CHAR
,tablename
,sizeof(tablename
),NULL
);
803 while(SQL_SUCCEEDED(retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
)(hstmt
)))
805 if(strcmp(tablename
,name
)==0){
806 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
807 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
808 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
809 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
814 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
815 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
816 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
817 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
820 void SqlOdbcStatement::setErrorState(SQLHSTMT hStmt
)
828 ret
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLGetDiagRecPtr
)(SQL_HANDLE_STMT
, hStmt
, ++i
,
829 state
, &native
, text
, sizeof(text
), &len
);
831 if (SQL_SUCCEEDED(ret
)){
832 printf("%s:%ld:%ld:%s\n", state
, i
, native
, text
);
833 strcpy(errState
,(char*)state
);
837 DbRetVal
SqlOdbcStatement::resolveForBindField(SQLHSTMT hstmt
)
841 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLNumResultColsPtr
) (hstmt
, &totalFields
);
842 if (retValue
){ return ErrBadCall
; }
843 BindSqlProjectField
*bindProjField
= NULL
;
845 UCHAR colName
[IDENTIFIER_LENGTH
];
852 icol
= 1; colNameMax
= IDENTIFIER_LENGTH
;
855 if(isProcedureCallStmt
) isSelStmt
= true;
856 len
= (SQLINTEGER
*)malloc((totalFields
+1)*sizeof(SQLINTEGER
));
857 for(int i
=0;i
<=totalFields
;i
++) { len
[i
] = SQL_NTS
;}
859 while (icol
<= totalFields
)
861 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDescribeColPtr
)(hstmt
, icol
, colName
, colNameMax
,
862 &nameLength
, &colType
, &colLength
,
864 if (retValue
) return ErrBadCall
;
865 bindProjField
= new BindSqlProjectField();
866 strcpy(bindProjField
->fName
, (char*)colName
);
867 bindProjField
->type
= AllDataType::convertFromSQLType(colType
,colLength
,scale
,tdbname
);
868 bindProjField
->length
= AllDataType::size(bindProjField
->type
, colLength
+1);
869 bindProjField
->value
= NULL
;
870 bindProjField
->targetvalue
= NULL
;
872 if(tdbname
==postgres
&& -5 == colType
) {
873 bindProjField
->targetvalue
= AllDataType::alloc(typeString
, 128);
874 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, icol
,
875 AllDataType::convertToSQLType(typeString
),
876 bindProjField
->targetvalue
, 128, &len
[icol
]);
878 switch(bindProjField
->type
)
881 fieldsize
= colLength
+1;
882 bindProjField
->targetvalue
= malloc(fieldsize
);
885 fieldsize
= sizeof(DATE_STRUCT
);
886 bindProjField
->targetvalue
= malloc(sizeof(DATE_STRUCT
));
887 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeDate
);
890 fieldsize
= sizeof(TIME_STRUCT
);
891 bindProjField
->targetvalue
= malloc(sizeof(TIME_STRUCT
));
892 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeTime
);
895 fieldsize
= sizeof(TIMESTAMP_STRUCT
);
896 bindProjField
->targetvalue
= malloc(sizeof(TIMESTAMP_STRUCT
));
897 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeTimeStamp
);
900 bindProjField
->targetvalue
= AllDataType::alloc(bindProjField
->type
, bindProjField
->length
);
902 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, icol
,
903 AllDataType::convertToSQL_C_Type(bindProjField
->type
,tdbname
),
904 bindProjField
->targetvalue
, fieldsize
, &len
[icol
]);
906 if (retValue
) return ErrBadCall
;
907 bindList
.append(bindProjField
);
910 totalFld
= totalFields
;