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
;
36 logFinest(Conf::logger
, "executeDirect %s", stmtstr
);
40 DbRetVal
SqlOdbcStatement::prepare(char *stmtstr
)
43 if (innerStmt
) rv
= ErrBadCall
;
44 if (rv
!= OK
) return rv
;
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
);
56 // setErrorState(hstmt);
57 printError(ErrSysInternal
, "Unable to prepare statement");
58 return ErrSysInternal
;
60 isSelStmt
=chechStmtType(stmtstr
);
62 if(strstr(stmtstr
,"call ")!=NULL
|| strstr(stmtstr
,"CALL ")!=NULL
)
64 logFinest(Conf::logger
, "Procedure call statement =true");
65 isProcedureCallStmt
=true;
68 tdbname
= conn
->getTrDbName();
69 rv
= resolveForBindField(hstmt
);
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
;
83 logFinest(Conf::logger
, "NumParams %d", totalFields
);
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,
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
;
102 switch(bindField
->type
)
105 fieldsize
= bindField
->length
;
106 bindField
->targetvalue
= malloc(fieldsize
);
109 fieldsize
= sizeof(DATE_STRUCT
);
110 bindField
->targetvalue
= malloc(sizeof(DATE_STRUCT
));
113 fieldsize
= sizeof(TIME_STRUCT
);
114 bindField
->targetvalue
= malloc(sizeof(TIME_STRUCT
));
117 fieldsize
= sizeof(TIMESTAMP_STRUCT
);
118 bindField
->targetvalue
= malloc(sizeof(TIMESTAMP_STRUCT
));
121 bindField
->targetvalue
= AllDataType::alloc(bindField
->type
, cLength
);
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
, ¶mlen
[icol
]);
130 if (retValue
) return ErrBadCall
;
131 paramList
.append(bindField
);
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
);
140 bool SqlOdbcStatement::isSelect()
146 DbRetVal
SqlOdbcStatement::execute(int &rowsAffected
)
149 if (!isPrepared
) return ErrNotPrepared
;
151 ListIterator iter
= paramList
.getIterator();
152 BindSqlField
*bindField
= NULL
;
154 while (iter
.hasElement())
156 bindField
= (BindSqlField
*)iter
.nextElement();
157 if(paramlen
[++col
] == SQL_NULL_DATA
){
158 ::free(bindField
->targetvalue
);
159 bindField
->targetvalue
= NULL
;
162 switch(bindField
->type
)
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();
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();
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();
192 AllDataType::cachecopyVal(bindField
->targetvalue
, bindField
->value
,
193 bindField
->type
, bindField
->length
);
198 //int retValue = SQLExecute (hstmt);
199 if(isProcedureCallStmt
)
201 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLExecutePtr
) (hstmt
);
202 if ((retValue
!= SQL_SUCCESS
) && (retValue
!= SQL_SUCCESS_WITH_INFO
)) {
205 rv
= resolveForBindField(hstmt
);
206 if(rv
!=OK
) return rv
;
207 logFinest(Conf::logger
, "Procedure executed");
209 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLExecutePtr
) (hstmt
);
210 if ((retValue
!= SQL_SUCCESS
) && (retValue
!= SQL_SUCCESS_WITH_INFO
)) {
211 // setErrorState(hstmt);
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;
222 DbRetVal
SqlOdbcStatement::bindParam(int pos
, void* value
)
225 printError(ErrWarning
, "Deprecated. Use setParamXXX instead\n");
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");
238 bindField
->value
= value
;
242 //void SqlOdbcStatement::setNullInfo(Table *table)
243 void SqlOdbcStatement::setNullInfo(AbsSqlStatement
*stmt
)
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
;
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
);
274 if( isSelStmt
&& NULL
== bindField
->value
)
276 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
279 switch(bindField
->type
)
282 Date
*dtCSQL
= (Date
*) bindField
->value
;
283 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
284 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
288 Time
*dtCSQL
= (Time
*) bindField
->value
;
289 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
290 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
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);
302 AllDataType::cachecopyVal(bindField
->value
, bindField
->targetvalue
,
303 bindField
->type
, bindField
->length
,tdbname
);
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
;
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
);
330 if( isSelStmt
&& NULL
== bindField
->value
)
332 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
335 switch(bindField
->type
)
338 Date
*dtCSQL
= (Date
*) bindField
->value
;
339 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
340 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
344 Time
*dtCSQL
= (Time
*) bindField
->value
;
345 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
346 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
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);
358 AllDataType::cachecopyVal(bindField
->value
, bindField
->targetvalue
, bindField
->type
, bindField
->length
, tdbname
);
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
;
376 while (iter
.hasElement())
379 bindField
= (BindSqlProjectField
*)iter
.nextElement();
380 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
381 if(len
[icol
++] == SQL_NULL_DATA
)
386 switch(bindField
->type
)
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
);
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
);
402 case typeTimeStamp
: {
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
);
412 AllDataType::printVal(bindField
->targetvalue
,
413 bindField
->type
, bindField
->length
,tdbname
);
419 return ptrToFirstField
;
422 void* SqlOdbcStatement::next()
427 DbRetVal
SqlOdbcStatement::close()
429 if (!isPrepared
) return OK
;
430 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLCloseCursorPtr
)(hstmt
);
431 logFinest(Conf::logger
, "CloseCursor");
434 bool SqlOdbcStatement::chechStmtType(char *buf
)
443 if (strncasecmp (buf
, "SELECT", 6) == 0) { return true;}
446 void* SqlOdbcStatement::getFieldValuePtr( int pos
)
449 ListIterator biter
= bindList
.getIterator();
450 BindSqlProjectField
*elem
= NULL
;
452 while (biter
.hasElement())
454 elem
= (BindSqlProjectField
*) biter
.nextElement();
457 if(elem
->value
== NULL
)
462 Date
*dtCSQL
=(Date
*) elem
->jdbcBindValue
;
463 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) elem
->targetvalue
;
464 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
468 Time
*dtCSQL
= (Time
*) elem
->jdbcBindValue
;
469 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) elem
->targetvalue
;
470 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
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);
482 return elem
->targetvalue
;
489 void SqlOdbcStatement::getProjFieldType(int *data
)
491 ListIterator biter
= bindList
.getIterator();
492 BindSqlProjectField
*elem
= NULL
;
494 while (biter
.hasElement())
496 elem
= (BindSqlProjectField
*) biter
.nextElement();
497 if((tdbname
== postgres
) && typeLongLong
== elem
->type
)
498 data
[i
++] = typeString
;
500 data
[i
++] = elem
->type
;
504 void* SqlOdbcStatement::getFieldValuePtr( char *name
)
506 ListIterator biter
= bindList
.getIterator();
507 BindSqlProjectField
*elem
= NULL
;
509 while (biter
.hasElement())
511 elem
= (BindSqlProjectField
*) biter
.nextElement();
512 if ( strcpy(elem
->fName
,name
) == 0 )
514 return elem
->targetvalue
;
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
;
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
;
552 DbRetVal
SqlOdbcStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
554 ListIterator biter
= paramList
.getIterator();
555 BindSqlField
*elem
= NULL
;
557 while (biter
.hasElement())
559 elem
= (BindSqlField
*) biter
.nextElement();
560 if (count
== parampos
-1)
562 fInfo
->length
= elem
->length
;
563 fInfo
->type
=elem
->type
;
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
);
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
);
596 if(len
){ ::free(len
); len
= NULL
;}
597 if(paramlen
) {::free(paramlen
); paramlen
= NULL
;}
598 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
600 isProcedureCallStmt
= false;
601 logFinest(Conf::logger
, "Statement Freed");
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
);
611 void SqlOdbcStatement::setIntParam(int paramPos
, int value
)
613 if (!isPrepared
) return ;
614 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
616 //Bug #1382 SQLDescribeParam returns the same type information, varchar
617 AllDataType::convertToString(bindField
->value
, &value
, typeInt
,0,tdbname
);
621 void SqlOdbcStatement::setLongParam(int paramPos
, long value
)
623 if (!isPrepared
) return ;
624 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
626 //Bug #1382 SQLDescribeParam returns the same type information, varchar
627 AllDataType::convertToString(bindField
->value
, &value
, typeLong
,0,tdbname
);
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
);
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
);
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
);
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
);
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';
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
);
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
);
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
);
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
);
698 void SqlOdbcStatement::getPrimaryKeyFieldName(char *tablename
, char *pkfieldname
)
700 if (pkfieldname
== NULL
) return;
701 SQLCHAR outstr
[1024];
702 SQLSMALLINT outstrlen
;
707 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
708 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
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
);
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
);
721 printError(ErrSysInit
, "Failed to connect to target database\n");
723 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
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
);
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
);
745 bool SqlOdbcStatement::isFldNull(int pos
)
747 if( len
[pos
] == SQL_NULL_DATA
)
752 bool SqlOdbcStatement::isFldNull(char *name
)
754 ListIterator iter
= bindList
.getIterator();
755 BindSqlProjectField
*bindField
= NULL
;
757 while (iter
.hasElement())
759 bindField
= (BindSqlProjectField
*)iter
.nextElement();
760 if(strcmp(name
,bindField
->fName
)==0)
766 if( len
[pos
] == SQL_NULL_DATA
)
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
;
786 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
787 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
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
);
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
);
801 printError(ErrSysInit
, "Failed to connect to target database\n");
804 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
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
);
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
);
829 void SqlOdbcStatement::setErrorState(SQLHSTMT hStmt
)
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
)
850 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLNumResultColsPtr
) (hstmt
, &totalFields
);
851 if (retValue
){ return ErrBadCall
; }
852 BindSqlProjectField
*bindProjField
= NULL
;
854 UCHAR colName
[IDENTIFIER_LENGTH
];
861 icol
= 1; colNameMax
= IDENTIFIER_LENGTH
;
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
,
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
;
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
]);
887 switch(bindProjField
->type
)
890 fieldsize
= colLength
+1;
891 bindProjField
->targetvalue
= malloc(fieldsize
);
894 fieldsize
= sizeof(DATE_STRUCT
);
895 bindProjField
->targetvalue
= malloc(sizeof(DATE_STRUCT
));
896 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeDate
);
899 fieldsize
= sizeof(TIME_STRUCT
);
900 bindProjField
->targetvalue
= malloc(sizeof(TIME_STRUCT
));
901 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeTime
);
904 fieldsize
= sizeof(TIMESTAMP_STRUCT
);
905 bindProjField
->targetvalue
= malloc(sizeof(TIMESTAMP_STRUCT
));
906 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeTimeStamp
);
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
);
919 totalFld
= totalFields
;