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 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 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 return elem
->targetvalue
;
456 void SqlOdbcStatement::getProjFieldType(int *data
)
458 ListIterator biter
= bindList
.getIterator();
459 BindSqlProjectField
*elem
= NULL
;
461 while (biter
.hasElement())
463 elem
= (BindSqlProjectField
*) biter
.nextElement();
464 if((tdbname
== postgres
) && typeLongLong
== elem
->type
)
465 data
[i
++] = typeString
;
467 data
[i
++] = elem
->type
;
471 void* SqlOdbcStatement::getFieldValuePtr( char *name
)
473 ListIterator biter
= bindList
.getIterator();
474 BindSqlProjectField
*elem
= NULL
;
476 while (biter
.hasElement())
478 elem
= (BindSqlProjectField
*) biter
.nextElement();
479 if ( strcpy(elem
->fName
,name
) == 0 )
481 return elem
->targetvalue
;
487 int SqlOdbcStatement::noOfProjFields()
489 if (!isPrepared
) return 0;
490 return bindList
.size();
493 int SqlOdbcStatement::noOfParamFields()
495 if (!isPrepared
) return 0;
496 return paramList
.size();
499 DbRetVal
SqlOdbcStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
501 ListIterator biter
= bindList
.getIterator();
502 BindSqlProjectField
*elem
= NULL
;
504 while (biter
.hasElement())
506 elem
= (BindSqlProjectField
*) biter
.nextElement();
507 if (count
== projpos
-1)
509 strcpy(fInfo
->fldName
, elem
->fName
);
510 fInfo
->length
= elem
->length
;
511 fInfo
->type
=elem
->type
;
519 DbRetVal
SqlOdbcStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
521 ListIterator biter
= paramList
.getIterator();
522 BindSqlField
*elem
= NULL
;
524 while (biter
.hasElement())
526 elem
= (BindSqlField
*) biter
.nextElement();
527 if (count
== parampos
-1)
529 fInfo
->length
= elem
->length
;
530 fInfo
->type
=elem
->type
;
538 DbRetVal
SqlOdbcStatement::free()
540 if(!isPrepared
) return OK
;
541 ListIterator biter
= bindList
.getIterator();
542 BindSqlProjectField
*elem
= NULL
;
543 while (biter
.hasElement())
545 elem
= (BindSqlProjectField
*) biter
.nextElement();
546 if(elem
->targetvalue
)
547 ::free(elem
->targetvalue
);
551 ListIterator piter
= paramList
.getIterator();
552 BindSqlField
*bindField
= NULL
;
553 while (piter
.hasElement())
555 bindField
= (BindSqlField
*) piter
.nextElement();
556 ::free(bindField
->value
);
557 ::free(bindField
->targetvalue
);
561 if(len
){ ::free(len
); len
= NULL
;}
562 if(paramlen
) {::free(paramlen
); paramlen
= NULL
;}
563 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
565 isProcedureCallStmt
= false;
568 void SqlOdbcStatement::setShortParam(int paramPos
, short value
)
570 if (!isPrepared
) return ;
571 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
572 AllDataType::convertToString(bindField
->value
, &value
, typeShort
, 0,tdbname
);
575 void SqlOdbcStatement::setIntParam(int paramPos
, int value
)
577 if (!isPrepared
) return ;
578 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
580 //Bug #1382 SQLDescribeParam returns the same type information, varchar
581 AllDataType::convertToString(bindField
->value
, &value
, typeInt
,0,tdbname
);
585 void SqlOdbcStatement::setLongParam(int paramPos
, long value
)
587 if (!isPrepared
) return ;
588 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
590 //Bug #1382 SQLDescribeParam returns the same type information, varchar
591 AllDataType::convertToString(bindField
->value
, &value
, typeLong
,0,tdbname
);
595 void SqlOdbcStatement::setLongLongParam(int paramPos
, long long value
)
597 if (!isPrepared
) return ;
598 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
599 AllDataType::convertToString(bindField
->value
, &value
, typeLongLong
,0,tdbname
);
602 void SqlOdbcStatement::setByteIntParam(int paramPos
, ByteInt value
)
604 if (!isPrepared
) return ;
605 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
606 AllDataType::convertToString(bindField
->value
, &value
, typeByteInt
,0,tdbname
);
609 void SqlOdbcStatement::setFloatParam(int paramPos
, float value
)
611 if (!isPrepared
) return ;
612 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
613 AllDataType::convertToString(bindField
->value
, &value
, typeFloat
,0, tdbname
);
616 void SqlOdbcStatement::setDoubleParam(int paramPos
, double value
)
618 if (!isPrepared
) return ;
619 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
620 AllDataType::convertToString(bindField
->value
, &value
, typeDouble
,0,tdbname
);
623 void SqlOdbcStatement::setStringParam(int paramPos
, char *value
)
625 if (!isPrepared
) return ;
626 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
627 if (bindField
->type
!= typeString
) return;
628 char *dest
= (char*)bindField
->value
;
629 strncpy(dest
, value
, bindField
->length
);
630 dest
[ bindField
->length
- 1] ='\0';
633 void SqlOdbcStatement::setDateParam(int paramPos
, Date value
)
635 if (!isPrepared
) return ;
636 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
637 AllDataType::convertToString(bindField
->value
, &value
, typeDate
,0,tdbname
);
640 void SqlOdbcStatement::setTimeParam(int paramPos
, Time value
)
642 if (!isPrepared
) return ;
643 BindSqlField
*bindField
= (BindSqlField
*)paramList
.get(paramPos
);
644 AllDataType::convertToString(bindField
->value
, &value
, typeTime
,0,tdbname
);
647 void SqlOdbcStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
649 if (!isPrepared
) return ;
650 BindSqlField
*bindField
= (BindSqlField
*) paramList
.get(paramPos
);
651 AllDataType::convertToString(bindField
->value
, &value
, typeTimeStamp
,0, tdbname
);
654 void SqlOdbcStatement::setBinaryParam(int paramPos
, void *value
, int length
)
656 if (!isPrepared
) return;
657 BindSqlField
*bindField
= (BindSqlField
*) paramList
.get(paramPos
);
658 AllDataType::convertToString(bindField
->value
, value
, typeBinary
, bindField
->length
,tdbname
);
662 void SqlOdbcStatement::getPrimaryKeyFieldName(char *tablename
, char *pkfieldname
)
664 if (pkfieldname
== NULL
) return;
665 SQLCHAR outstr
[1024];
666 SQLSMALLINT outstrlen
;
671 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
672 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
674 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
676 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLSetEnvAttrPtr
)(henv
, SQL_ATTR_ODBC_VERSION
,(void *) SQL_OV_ODBC3
, 0);
677 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_DBC
, henv
, &hdbc
);
679 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
681 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDriverConnectPtr
)(hdbc
, NULL
, (SQLCHAR
*)conn
->dsn
, SQL_NTS
, outstr
, sizeof(outstr
), &outstrlen
,SQL_DRIVER_NOPROMPT
);
682 if (SQL_SUCCEEDED(retValue
)) {
683 printDebug(DM_Gateway
, "Connected to target database using dsn = %s\n", conn
->dsn
);
685 printError(ErrSysInit
, "Failed to connect to target database\n");
687 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
689 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
691 char columnname
[IDENTIFIER_LENGTH
];
692 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLPrimaryKeysPtr
)(hstmt
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, (SQLCHAR
*) tablename
, SQL_NTS
);
693 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, 4, SQL_C_CHAR
,columnname
, 129,NULL
);
694 bool isPkExists
=false;
695 if((*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
)( hstmt
) == SQL_SUCCESS
)
697 Util::str_tolower(columnname
);
698 strcpy(pkfieldname
, columnname
);
701 tdbname
= conn
->getTrDbName();
702 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
703 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
704 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
705 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
709 bool SqlOdbcStatement::isFldNull(int pos
)
711 if( len
[pos
] == SQL_NULL_DATA
)
716 bool SqlOdbcStatement::isFldNull(char *name
)
718 ListIterator iter
= bindList
.getIterator();
719 BindSqlProjectField
*bindField
= NULL
;
721 while (iter
.hasElement())
723 bindField
= (BindSqlProjectField
*)iter
.nextElement();
724 if(strcmp(name
,bindField
->fName
)==0)
730 if( len
[pos
] == SQL_NULL_DATA
)
736 void SqlOdbcStatement::setNull(int pos
)
738 paramlen
[pos
] = SQL_NULL_DATA
;
741 bool SqlOdbcStatement::isTableExists( char *name
)
744 SQLCHAR outstr
[1024];
745 SQLSMALLINT outstrlen
;
750 SqlOdbcConnection
*conn
= (SqlOdbcConnection
*)con
;
751 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &henv
);
753 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
756 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLSetEnvAttrPtr
)(henv
, SQL_ATTR_ODBC_VERSION
,(void *) SQL_OV_ODBC3
, 0);
757 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_DBC
, henv
, &hdbc
);
759 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
761 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDriverConnectPtr
)(hdbc
, NULL
, (SQLCHAR
*)conn
->dsn
, SQL_NTS
, outstr
, sizeof(outstr
), &outstrlen
,SQL_DRIVER_NOPROMPT
);
762 if (SQL_SUCCEEDED(retValue
)) {
763 printDebug(DM_Gateway
, "Connected to target database using dsn = %s\n", conn
->dsn
);
765 printError(ErrSysInit
, "Failed to connect to target database\n");
768 retValue
=(*SqlOdbcConnection::ODBCFuncPtrs
.SQLAllocHandlePtr
) (SQL_HANDLE_STMT
, hdbc
, &hstmt
);
770 printError(ErrSysInit
, "Unable to allocate ODBC handle \n");
772 char tablename
[IDENTIFIER_LENGTH
];
773 //retValue = (*SqlOdbcConnection::ODBCFuncPtrs.SQLTablesPtr)(hstmt, (SQLCHAR*)"test", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"TABLE", SQL_NTS );
774 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLTablesPtr
)(hstmt
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, NULL
, SQL_NTS
, NULL
, SQL_NTS
);
775 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
,3,SQL_C_CHAR
,tablename
,sizeof(tablename
),NULL
);
776 while(SQL_SUCCEEDED(retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFetchPtr
)(hstmt
)))
778 if(strcmp(tablename
,name
)==0){
779 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
780 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
781 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
782 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
787 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_STMT
, hstmt
);
788 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDisconnectPtr
)(hdbc
);
789 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_DBC
, hdbc
);
790 (*SqlOdbcConnection::ODBCFuncPtrs
.SQLFreeHandlePtr
)(SQL_HANDLE_ENV
, henv
);
793 void SqlOdbcStatement::setErrorState(SQLHSTMT hStmt
)
801 ret
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLGetDiagRecPtr
)(SQL_HANDLE_STMT
, hStmt
, ++i
,
802 state
, &native
, text
, sizeof(text
), &len
);
804 if (SQL_SUCCEEDED(ret
)){
805 printf("%s:%ld:%ld:%s\n", state
, i
, native
, text
);
806 strcpy(errState
,(char*)state
);
810 DbRetVal
SqlOdbcStatement::resolveForBindField(SQLHSTMT hstmt
)
814 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLNumResultColsPtr
) (hstmt
, &totalFields
);
815 if (retValue
){ return ErrBadCall
; }
816 BindSqlProjectField
*bindProjField
= NULL
;
818 UCHAR colName
[IDENTIFIER_LENGTH
];
825 icol
= 1; colNameMax
= IDENTIFIER_LENGTH
;
828 if(isProcedureCallStmt
) isSelStmt
= true;
829 len
= (SQLINTEGER
*)malloc((totalFields
+1)*sizeof(SQLINTEGER
));
830 for(int i
=0;i
<=totalFields
;i
++) { len
[i
] = SQL_NTS
;}
832 while (icol
<= totalFields
)
834 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLDescribeColPtr
)(hstmt
, icol
, colName
, colNameMax
,
835 &nameLength
, &colType
, &colLength
,
837 if (retValue
) return ErrBadCall
;
838 bindProjField
= new BindSqlProjectField();
839 strcpy(bindProjField
->fName
, (char*)colName
);
840 bindProjField
->type
= AllDataType::convertFromSQLType(colType
,colLength
,scale
,tdbname
);
841 bindProjField
->length
= AllDataType::size(bindProjField
->type
, colLength
+1);
842 bindProjField
->value
= NULL
;
843 bindProjField
->targetvalue
= NULL
;
845 if(tdbname
==postgres
&& -5 == colType
) {
846 bindProjField
->targetvalue
= AllDataType::alloc(typeString
, 128);
847 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, icol
,
848 AllDataType::convertToSQLType(typeString
),
849 bindProjField
->targetvalue
, 128, &len
[icol
]);
851 switch(bindProjField
->type
)
854 fieldsize
= colLength
+1;
855 bindProjField
->targetvalue
= malloc(fieldsize
);
858 fieldsize
= sizeof(DATE_STRUCT
);
859 bindProjField
->targetvalue
= malloc(sizeof(DATE_STRUCT
));
862 fieldsize
= sizeof(TIME_STRUCT
);
863 bindProjField
->targetvalue
= malloc(sizeof(TIME_STRUCT
));
866 fieldsize
= sizeof(TIMESTAMP_STRUCT
);
867 bindProjField
->targetvalue
= malloc(sizeof(TIMESTAMP_STRUCT
));
870 bindProjField
->targetvalue
= AllDataType::alloc(bindProjField
->type
, bindProjField
->length
);
872 retValue
= (*SqlOdbcConnection::ODBCFuncPtrs
.SQLBindColPtr
)(hstmt
, icol
,
873 AllDataType::convertToSQL_C_Type(bindProjField
->type
,tdbname
),
874 bindProjField
->targetvalue
, fieldsize
, &len
[icol
]);
876 if (retValue
) return ErrBadCall
;
877 bindList
.append(bindProjField
);
880 totalFld
= totalFields
;