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 SqlOdbcConnection
*sqlOdbcCon
= (SqlOdbcConnection
*)con
;
314 if (! sqlOdbcCon
->isConnectionOpen()) {
315 printError(ErrNotOpen
, "Connection not open");
316 rv
= ErrNoConnection
;
319 if (!isPrepared
) return NULL
;
320 //int retValue = SQLFetch (hstmt);
321 int retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
) (hstmt
);
322 if (retValue
) { rv
= OK
; return NULL
; }
323 ListIterator iter
= bindList
.getIterator();
324 BindSqlProjectField
*bindField
= NULL
;
325 void *ptrToFirstField
= NULL
;
327 while (iter
.hasElement())
329 bindField
= (BindSqlProjectField
*)iter
.nextElement();
330 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->value
;
331 if(len
[++icol
] == SQL_NULL_DATA
)
333 if(bindField
->value
) AllDataType::memoryset(bindField
->value
,bindField
->type
);
336 if( isSelStmt
&& NULL
== bindField
->value
)
338 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
341 switch(bindField
->type
)
344 Date
*dtCSQL
= (Date
*) bindField
->value
;
345 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
346 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
350 Time
*dtCSQL
= (Time
*) bindField
->value
;
351 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
352 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
355 case typeTimeStamp
: {
356 TimeStamp
*dtCSQL
= (TimeStamp
*) bindField
->value
;
357 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) bindField
->targetvalue
;
358 dtCSQL
->setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
359 dtCSQL
->setTime(dtTarget
->hour
,dtTarget
->minute
,
360 dtTarget
->second
, 0);// dtTarget->fraction);
364 AllDataType::cachecopyVal(bindField
->value
, bindField
->targetvalue
, bindField
->type
, bindField
->length
, tdbname
);
369 return ptrToFirstField
;
372 void* SqlOdbcStatement::fetchAndPrint(bool SQL
)
374 if (!isPrepared
) return NULL
;
375 //int retValue = SQLFetch (hstmt);
376 int retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
) (hstmt
);
377 if (retValue
) return NULL
;
378 ListIterator iter
= bindList
.getIterator();
379 BindSqlProjectField
*bindField
= NULL
;
380 void *ptrToFirstField
= NULL
;
382 while (iter
.hasElement())
385 bindField
= (BindSqlProjectField
*)iter
.nextElement();
386 if (ptrToFirstField
== NULL
) ptrToFirstField
=bindField
->targetvalue
;
387 if(len
[icol
++] == SQL_NULL_DATA
)
392 switch(bindField
->type
)
396 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) bindField
->targetvalue
;
397 dtCSQL
.set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
398 AllDataType::printVal(&dtCSQL
, bindField
->type
, bindField
->length
);
403 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) bindField
->targetvalue
;
404 dtCSQL
.set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
405 AllDataType::printVal(&dtCSQL
, bindField
->type
, bindField
->length
);
408 case typeTimeStamp
: {
410 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) bindField
->targetvalue
;
411 dtCSQL
.setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
412 dtCSQL
.setTime(dtTarget
->hour
,dtTarget
->minute
,
413 dtTarget
->second
, 0);//dtTarget->fraction);
414 AllDataType::printVal(&dtCSQL
, bindField
->type
, bindField
->length
);
418 AllDataType::printVal(bindField
->targetvalue
,
419 bindField
->type
, bindField
->length
,tdbname
);
425 return ptrToFirstField
;
428 void* SqlOdbcStatement::next()
433 DbRetVal
SqlOdbcStatement::close()
435 if (!isPrepared
) return OK
;
436 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLCloseCursorPtr
)(hstmt
);
437 logFinest(Conf::logger
, "CloseCursor");
440 bool SqlOdbcStatement::chechStmtType(char *buf
)
449 if (strncasecmp (buf
, "SELECT", 6) == 0) { return true;}
452 void* SqlOdbcStatement::getFieldValuePtr( int pos
)
455 ListIterator biter
= bindList
.getIterator();
456 BindSqlProjectField
*elem
= NULL
;
458 while (biter
.hasElement())
460 elem
= (BindSqlProjectField
*) biter
.nextElement();
463 if(elem
->value
== NULL
)
468 Date
*dtCSQL
=(Date
*) elem
->jdbcBindValue
;
469 DATE_STRUCT
*dtTarget
= (DATE_STRUCT
*) elem
->targetvalue
;
470 dtCSQL
->set(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
474 Time
*dtCSQL
= (Time
*) elem
->jdbcBindValue
;
475 TIME_STRUCT
*dtTarget
= (TIME_STRUCT
*) elem
->targetvalue
;
476 dtCSQL
->set(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
);
479 case typeTimeStamp
: {
480 TimeStamp
*dtCSQL
= (TimeStamp
*) elem
->jdbcBindValue
;
481 TIMESTAMP_STRUCT
*dtTarget
= (TIMESTAMP_STRUCT
*) elem
->targetvalue
;
482 dtCSQL
->setDate(dtTarget
->year
,dtTarget
->month
,dtTarget
->day
);
483 dtCSQL
->setTime(dtTarget
->hour
,dtTarget
->minute
,dtTarget
->second
, 0);//dtTarget->fraction);
488 return elem
->targetvalue
;
495 void SqlOdbcStatement::getProjFieldType(int *data
)
497 ListIterator biter
= bindList
.getIterator();
498 BindSqlProjectField
*elem
= NULL
;
500 while (biter
.hasElement())
502 elem
= (BindSqlProjectField
*) biter
.nextElement();
503 if((tdbname
== postgres
) && typeLongLong
== elem
->type
)
504 data
[i
++] = typeString
;
506 data
[i
++] = elem
->type
;
510 void* SqlOdbcStatement::getFieldValuePtr( char *name
)
512 ListIterator biter
= bindList
.getIterator();
513 BindSqlProjectField
*elem
= NULL
;
515 while (biter
.hasElement())
517 elem
= (BindSqlProjectField
*) biter
.nextElement();
518 if ( strcpy(elem
->fName
,name
) == 0 )
520 return elem
->targetvalue
;
526 int SqlOdbcStatement::noOfProjFields()
528 if (!isPrepared
) return 0;
529 return bindList
.size();
532 int SqlOdbcStatement::noOfParamFields()
534 if (!isPrepared
) return 0;
535 return paramList
.size();
538 DbRetVal
SqlOdbcStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
540 ListIterator biter
= bindList
.getIterator();
541 BindSqlProjectField
*elem
= NULL
;
543 while (biter
.hasElement())
545 elem
= (BindSqlProjectField
*) biter
.nextElement();
546 if (count
== projpos
-1)
548 strcpy(fInfo
->fldName
, elem
->fName
);
549 fInfo
->length
= elem
->length
;
550 fInfo
->type
=elem
->type
;
558 DbRetVal
SqlOdbcStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
560 ListIterator biter
= paramList
.getIterator();
561 BindSqlField
*elem
= NULL
;
563 while (biter
.hasElement())
565 elem
= (BindSqlField
*) biter
.nextElement();
566 if (count
== parampos
-1)
568 fInfo
->length
= elem
->length
;
569 fInfo
->type
=elem
->type
;
577 DbRetVal
SqlOdbcStatement::free()
579 if(!isPrepared
) return OK
;
580 ListIterator biter
= bindList
.getIterator();
581 BindSqlProjectField
*elem
= NULL
;
582 while (biter
.hasElement())
584 elem
= (BindSqlProjectField
*) biter
.nextElement();
585 if(elem
->targetvalue
)
586 ::free(elem
->targetvalue
);
587 if(elem
->jdbcBindValue
)
588 ::free(elem
->jdbcBindValue
);
592 ListIterator piter
= paramList
.getIterator();
593 BindSqlField
*bindField
= NULL
;
594 while (piter
.hasElement())
596 bindField
= (BindSqlField
*) piter
.nextElement();
597 ::free(bindField
->value
);
598 ::free(bindField
->targetvalue
);
602 if(len
){ ::free(len
); len
= NULL
;}
603 if(paramlen
) {::free(paramlen
); paramlen
= NULL
;}
604 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
606 isProcedureCallStmt
= false;
607 logFinest(Conf::logger
, "Statement Freed");
610 void SqlOdbcStatement::setShortParam(int paramPos
, short value
)
612 if (!isPrepared
) return ;
613 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
614 AllDataType::convertToString(bindField
->value
, &value
, typeShort
, 0,tdbname
);
617 void SqlOdbcStatement::setIntParam(int paramPos
, int value
)
619 if (!isPrepared
) return ;
620 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
622 //Bug #1382 SQLDescribeParam returns the same type information, varchar
623 AllDataType::convertToString(bindField
->value
, &value
, typeInt
,0,tdbname
);
627 void SqlOdbcStatement::setLongParam(int paramPos
, long value
)
629 if (!isPrepared
) return ;
630 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
632 //Bug #1382 SQLDescribeParam returns the same type information, varchar
633 AllDataType::convertToString(bindField
->value
, &value
, typeLong
,0,tdbname
);
637 void SqlOdbcStatement::setLongLongParam(int paramPos
, long long value
)
639 if (!isPrepared
) return ;
640 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
641 AllDataType::convertToString(bindField
->value
, &value
, typeLongLong
,0,tdbname
);
644 void SqlOdbcStatement::setByteIntParam(int paramPos
, ByteInt value
)
646 if (!isPrepared
) return ;
647 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
648 AllDataType::convertToString(bindField
->value
, &value
, typeByteInt
,0,tdbname
);
651 void SqlOdbcStatement::setFloatParam(int paramPos
, float value
)
653 if (!isPrepared
) return ;
654 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
655 AllDataType::convertToString(bindField
->value
, &value
, typeFloat
,0, tdbname
);
658 void SqlOdbcStatement::setDoubleParam(int paramPos
, double value
)
660 if (!isPrepared
) return ;
661 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
662 AllDataType::convertToString(bindField
->value
, &value
, typeDouble
,0,tdbname
);
665 void SqlOdbcStatement::setStringParam(int paramPos
, char *value
)
667 if (!isPrepared
) return ;
668 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
669 if (bindField
->type
!= typeString
) return;
670 char *dest
= (char*)bindField
->value
;
671 strncpy(dest
, value
, bindField
->length
);
672 dest
[ bindField
->length
- 1] ='\0';
675 void SqlOdbcStatement::setDateParam(int paramPos
, Date value
)
677 if (!isPrepared
) return ;
678 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
679 AllDataType::convertToString(bindField
->value
, &value
, typeDate
,0,tdbname
);
682 void SqlOdbcStatement::setTimeParam(int paramPos
, Time value
)
684 if (!isPrepared
) return ;
685 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
686 AllDataType::convertToString(bindField
->value
, &value
, typeTime
,0,tdbname
);
689 void SqlOdbcStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
691 if (!isPrepared
) return ;
692 BindSqlField
*bindField
= (BindSqlField
*) paramList
.get(paramPos
);
693 AllDataType::convertToString(bindField
->value
, &value
, typeTimeStamp
,0, tdbname
);
696 void SqlOdbcStatement::setBinaryParam(int paramPos
, void *value
, int length
)
698 if (!isPrepared
) return;
699 BindSqlField
*bindField
= (BindSqlField
*) paramList
.get(paramPos
);
700 AllDataType::convertToString(bindField
->value
, value
, typeBinary
, bindField
->length
,tdbname
);
704 void SqlOdbcStatement::getPrimaryKeyFieldName(char *tablename
, char *pkfieldname
)
706 if (pkfieldname
== NULL
) return;
707 SQLCHAR outstr
[1024];
708 SQLSMALLINT outstrlen
;
713 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
714 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
716 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
718 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLSetEnvAttrPtr
)(henv
, SQL_ATTR_ODBC_VERSION
,(void *) SQL_OV_ODBC3
, 0);
719 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_DBC
, henv
, &hdbc
);
721 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
723 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDriverConnectPtr
)(hdbc
, NULL
, (SQLCHAR
*)conn
->dsn
, SQL_NTS
, outstr
, sizeof(outstr
), &outstrlen
,SQL_DRIVER_NOPROMPT
);
724 if (SQL_SUCCEEDED(retValue
)) {
725 printDebug(DM_Gateway
, "Connected to target database using dsn = %s\n", conn
->dsn
);
727 printError(ErrSysInit
, "Failed to connect to target database\n");
729 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
731 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
733 char columnname
[IDENTIFIER_LENGTH
];
734 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLPrimaryKeysPtr
)(hstmt
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, (SQLCHAR
*) tablename
, SQL_NTS
);
735 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, 4, SQL_C_CHAR
,columnname
, 129,NULL
);
736 bool isPkExists
=false;
737 if((*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
)( hstmt
) == SQL_SUCCESS
)
739 Util::str_tolower(columnname
);
740 strcpy(pkfieldname
, columnname
);
743 tdbname
= conn
->getTrDbName();
744 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
745 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
746 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
747 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
751 bool SqlOdbcStatement::isFldNull(int pos
)
753 if( len
[pos
] == SQL_NULL_DATA
)
758 bool SqlOdbcStatement::isFldNull(char *name
)
760 ListIterator iter
= bindList
.getIterator();
761 BindSqlProjectField
*bindField
= NULL
;
763 while (iter
.hasElement())
765 bindField
= (BindSqlProjectField
*)iter
.nextElement();
766 if(strcmp(name
,bindField
->fName
)==0)
772 if( len
[pos
] == SQL_NULL_DATA
)
778 void SqlOdbcStatement::setNull(int pos
)
780 paramlen
[pos
] = SQL_NULL_DATA
;
783 bool SqlOdbcStatement::isTableExists( char *name
)
786 SQLCHAR outstr
[1024];
787 SQLSMALLINT outstrlen
;
792 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
793 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
795 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
798 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLSetEnvAttrPtr
)(henv
, SQL_ATTR_ODBC_VERSION
,(void *) SQL_OV_ODBC3
, 0);
799 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_DBC
, henv
, &hdbc
);
801 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
803 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDriverConnectPtr
)(hdbc
, NULL
, (SQLCHAR
*)conn
->dsn
, SQL_NTS
, outstr
, sizeof(outstr
), &outstrlen
,SQL_DRIVER_NOPROMPT
);
804 if (SQL_SUCCEEDED(retValue
)) {
805 printDebug(DM_Gateway
, "Connected to target database using dsn = %s\n", conn
->dsn
);
807 printError(ErrSysInit
, "Failed to connect to target database\n");
810 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
812 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
814 char tablename
[IDENTIFIER_LENGTH
];
815 //retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLTablesPtr)(hstmt, (SQLCHAR*)"test", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"TABLE", SQL_NTS );
816 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLTablesPtr
)(hstmt
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, NULL
, SQL_NTS
);
817 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
,3,SQL_C_CHAR
,tablename
,sizeof(tablename
),NULL
);
818 while(SQL_SUCCEEDED(retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
)(hstmt
)))
820 if(strcmp(tablename
,name
)==0){
821 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
822 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
823 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
824 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
829 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
830 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
831 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
832 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
835 void SqlOdbcStatement::setErrorState(SQLHSTMT hStmt
)
843 ret
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLGetDiagRecPtr
)(SQL_HANDLE_STMT
, hStmt
, ++i
,
844 state
, &native
, text
, sizeof(text
), &len
);
846 if (SQL_SUCCEEDED(ret
)){
847 printf("%s:%ld:%ld:%s\n", state
, i
, native
, text
);
848 strcpy(errState
,(char*)state
);
852 DbRetVal
SqlOdbcStatement::resolveForBindField(SQLHSTMT hstmt
)
856 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLNumResultColsPtr
) (hstmt
, &totalFields
);
857 if (retValue
){ return ErrBadCall
; }
858 BindSqlProjectField
*bindProjField
= NULL
;
860 UCHAR colName
[IDENTIFIER_LENGTH
];
867 icol
= 1; colNameMax
= IDENTIFIER_LENGTH
;
870 if(isProcedureCallStmt
) isSelStmt
= true;
871 len
= (SQLINTEGER
*)malloc((totalFields
+1)*sizeof(SQLINTEGER
));
872 for(int i
=0;i
<=totalFields
;i
++) { len
[i
] = SQL_NTS
;}
874 while (icol
<= totalFields
)
876 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDescribeColPtr
)(hstmt
, icol
, colName
, colNameMax
,
877 &nameLength
, &colType
, &colLength
,
879 if (retValue
) return ErrBadCall
;
880 bindProjField
= new BindSqlProjectField();
881 strcpy(bindProjField
->fName
, (char*)colName
);
882 bindProjField
->type
= AllDataType::convertFromSQLType(colType
,colLength
,scale
,tdbname
);
883 bindProjField
->length
= AllDataType::size(bindProjField
->type
, colLength
+1);
884 bindProjField
->value
= NULL
;
885 bindProjField
->targetvalue
= NULL
;
887 if(tdbname
==postgres
&& -5 == colType
) {
888 bindProjField
->targetvalue
= AllDataType::alloc(typeString
, 128);
889 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, icol
,
890 AllDataType::convertToSQLType(typeString
),
891 bindProjField
->targetvalue
, 128, &len
[icol
]);
893 switch(bindProjField
->type
)
897 fieldsize
= colLength
+1;
898 bindProjField
->targetvalue
= malloc(fieldsize
);
901 fieldsize
= sizeof(DATE_STRUCT
);
902 bindProjField
->targetvalue
= malloc(sizeof(DATE_STRUCT
));
903 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeDate
);
906 fieldsize
= sizeof(TIME_STRUCT
);
907 bindProjField
->targetvalue
= malloc(sizeof(TIME_STRUCT
));
908 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeTime
);
911 fieldsize
= sizeof(TIMESTAMP_STRUCT
);
912 bindProjField
->targetvalue
= malloc(sizeof(TIMESTAMP_STRUCT
));
913 bindProjField
->jdbcBindValue
= AllDataType::alloc(typeTimeStamp
);
916 bindProjField
->targetvalue
= AllDataType::alloc(bindProjField
->type
, bindProjField
->length
);
918 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, icol
,
919 AllDataType::convertToSQL_C_Type(bindProjField
->type
,tdbname
),
920 bindProjField
->targetvalue
, fieldsize
, &len
[icol
]);
922 if (retValue
) return ErrBadCall
;
923 bindList
.append(bindProjField
);
926 totalFld
= totalFields
;