statement caching modifications and cache stmt display
[csql.git] / src / adapter / SqlOdbcConnection.cxx
blob57f2a78e4f1bddddb5f5162e732ebf694456303f
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include<os.h>
21 #include <SqlOdbcConnection.h>
22 #include <CSql.h>
23 #include<TableConfig.h>
24 #include <dlfcn.h>
25 bool SqlOdbcConnection::symbolsLoaded= false;
26 struct SQLFuncPtrs SqlOdbcConnection::ODBCFuncPtrs;
28 DbRetVal SqlOdbcConnection::loadSymbols()
30 #ifdef x86_64
31 void *handle = RTLD_DEFAULT;
32 #else
33 void *handle = (void*) -1l;
34 #endif
35 ODBCFuncPtrs.SQLAllocHandlePtr = (SQLRETURN (*)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*))dlsym(handle, "SQLAllocHandle");
36 if (!ODBCFuncPtrs.SQLAllocHandlePtr){
38 if (handle == RTLD_DEFAULT) handle = (void*) -1l; else handle = RTLD_DEFAULT;
39 ODBCFuncPtrs.SQLAllocHandlePtr = (SQLRETURN (*)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*))dlsym(handle, "SQLAllocHandle");
40 if (!ODBCFuncPtrs.SQLAllocHandlePtr) {
41 printError(ErrSysInternal, "Symbol lookup failed\n");
42 return ErrSysInternal;
45 ODBCFuncPtrs.SQLSetEnvAttrPtr = (SQLRETURN (*)(SQLHENV, SQLINTEGER, SQLPOINTER, SQLINTEGER ))dlsym(handle, "SQLSetEnvAttr");
46 if (!ODBCFuncPtrs.SQLSetEnvAttrPtr){
47 printError(ErrSysInternal, "Symbol lookup failed\n");
48 return ErrSysInternal;
51 ODBCFuncPtrs.SQLDriverConnectPtr = (SQLRETURN (*)(SQLHDBC, SQLHWND, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLUSMALLINT ))dlsym(handle, "SQLDriverConnect");
52 if (!ODBCFuncPtrs.SQLDriverConnectPtr){
53 printError(ErrSysInternal, "Symbol lookup failed\n");
54 return ErrSysInternal;
57 ODBCFuncPtrs.SQLGetDiagRecPtr = (SQLRETURN (*)(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*))dlsym(handle, "SQLGetDiagRec");
58 if (!ODBCFuncPtrs.SQLGetDiagRecPtr){
59 printError(ErrSysInternal, "Symbol lookup failed\n");
60 return ErrSysInternal;
63 ODBCFuncPtrs.SQLSetConnectAttrPtr = (SQLRETURN (*)(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER ))dlsym(handle, "SQLSetConnectAttr");
64 if (!ODBCFuncPtrs.SQLSetConnectAttrPtr){
65 printError(ErrSysInternal, "Symbol lookup failed\n");
66 return ErrSysInternal;
69 ODBCFuncPtrs.SQLProcedureColumnsPtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR *, SQLSMALLINT, SQLCHAR *, SQLSMALLINT, SQLCHAR *, SQLSMALLINT, SQLCHAR *, SQLSMALLINT))dlsym(handle, "SQLProcedureColumns");
70 if (!ODBCFuncPtrs.SQLProcedureColumnsPtr){
71 printError(ErrSysInternal, "Symbol lookup failed\n");
72 return ErrSysInternal;
75 ODBCFuncPtrs.SQLFreeHandlePtr = (SQLRETURN (*)(SQLSMALLINT,SQLHANDLE))dlsym(handle, "SQLFreeHandle");
76 if (!ODBCFuncPtrs.SQLFreeHandlePtr){
77 printError(ErrSysInternal, "Symbol lookup failed\n");
78 return ErrSysInternal;
81 ODBCFuncPtrs.SQLTransactPtr = (SQLRETURN (*)(SQLHENV, SQLHDBC, SQLUSMALLINT ))dlsym(handle, "SQLTransact");
82 if (!ODBCFuncPtrs.SQLTransactPtr){
83 printError(ErrSysInternal, "Symbol lookup failed\n");
84 return ErrSysInternal;
87 ODBCFuncPtrs.SQLExecDirectPtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLINTEGER ))dlsym(handle, "SQLExecDirect");
88 if (!ODBCFuncPtrs.SQLExecDirectPtr){
89 printError(ErrSysInternal, "Symbol lookup failed\n");
90 return ErrSysInternal;
93 ODBCFuncPtrs.SQLPreparePtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLINTEGER ))dlsym(handle, "SQLPrepare");
94 if (!ODBCFuncPtrs.SQLPreparePtr){
95 printError(ErrSysInternal, "Symbol lookup failed\n");
96 return ErrSysInternal;
99 ODBCFuncPtrs.SQLNumResultColsPtr = (SQLRETURN (*)(SQLHSTMT, SQLSMALLINT* ))dlsym(handle, "SQLNumResultCols");
100 if (!ODBCFuncPtrs.SQLNumResultColsPtr){
101 printError(ErrSysInternal, "Symbol lookup failed\n");
102 return ErrSysInternal;
105 ODBCFuncPtrs.SQLDescribeColPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLULEN*,SQLSMALLINT*, SQLSMALLINT* ))dlsym(handle, "SQLDescribeCol");
106 if (!ODBCFuncPtrs.SQLDescribeColPtr){
107 printError(ErrSysInternal, "Symbol lookup failed\n");
108 return ErrSysInternal;
111 ODBCFuncPtrs.SQLBindColPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN* ))dlsym(handle, "SQLBindCol");
112 if (!ODBCFuncPtrs.SQLBindColPtr){
113 printError(ErrSysInternal, "Symbol lookup failed\n");
114 return ErrSysInternal;
117 ODBCFuncPtrs.SQLNumParamsPtr = (SQLRETURN (*)(SQLHSTMT, SQLSMALLINT* ))dlsym(handle, "SQLNumParams");
118 if (!ODBCFuncPtrs.SQLNumParamsPtr){
119 printError(ErrSysInternal, "Symbol lookup failed\n");
120 return ErrSysInternal;
123 ODBCFuncPtrs.SQLDescribeParamPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT*, SQLULEN*, SQLSMALLINT*, SQLSMALLINT* ))dlsym(handle, "SQLDescribeParam");
124 if (!ODBCFuncPtrs.SQLDescribeParamPtr){
125 printError(ErrSysInternal, "Symbol lookup failed\n");
126 return ErrSysInternal;
129 ODBCFuncPtrs.SQLBindParameterPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLULEN, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN* ))dlsym(handle, "SQLBindParameter");
130 if (!ODBCFuncPtrs.SQLBindParameterPtr){
131 printError(ErrSysInternal, "Symbol lookup failed\n");
132 return ErrSysInternal;
135 ODBCFuncPtrs.SQLExecutePtr = (SQLRETURN (*)(SQLHSTMT ))dlsym(handle, "SQLExecute");
136 if (!ODBCFuncPtrs.SQLExecutePtr){
137 printError(ErrSysInternal, "Symbol lookup failed\n");
138 return ErrSysInternal;
141 ODBCFuncPtrs.SQLRowCountPtr = (SQLRETURN (*)(SQLHSTMT, SQLLEN* ))dlsym(handle, "SQLRowCount");
142 if (!ODBCFuncPtrs.SQLRowCountPtr){
143 printError(ErrSysInternal, "Symbol lookup failed\n");
144 return ErrSysInternal;
147 ODBCFuncPtrs.SQLFetchPtr = (SQLRETURN (*)(SQLHSTMT ))dlsym(handle, "SQLFetch");
148 if (!ODBCFuncPtrs.SQLFetchPtr){
149 printError(ErrSysInternal, "Symbol lookup failed\n");
150 return ErrSysInternal;
153 ODBCFuncPtrs.SQLCloseCursorPtr = (SQLRETURN (*)(SQLHSTMT ))dlsym(handle, "SQLCloseCursor");
154 if (!ODBCFuncPtrs.SQLCloseCursorPtr){
155 printError(ErrSysInternal, "Symbol lookup failed\n");
156 return ErrSysInternal;
159 ODBCFuncPtrs.SQLPrimaryKeysPtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT ))dlsym(handle, "SQLPrimaryKeys");
160 if (!ODBCFuncPtrs.SQLPrimaryKeysPtr){
161 printError(ErrSysInternal, "Symbol lookup failed\n");
162 return ErrSysInternal;
165 ODBCFuncPtrs.SQLGetDataPtr = (SQLRETURN (*)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER, SQLLEN,SQLLEN* ))dlsym(handle, "SQLGetData");
166 if (!ODBCFuncPtrs.SQLGetDataPtr){
167 printError(ErrSysInternal, "Symbol lookup failed\n");
168 return ErrSysInternal;
171 ODBCFuncPtrs.SQLDisconnectPtr = (SQLRETURN (*)(SQLHDBC))dlsym(handle, "SQLDisconnect");
172 if (!ODBCFuncPtrs.SQLDisconnectPtr){
173 printError(ErrSysInternal, "Symbol lookup failed\n");
174 return ErrSysInternal;
176 ODBCFuncPtrs.SQLTablesPtr =(SQLRETURN (*)(SQLHSTMT ,SQLCHAR *, SQLSMALLINT , SQLCHAR * , SQLSMALLINT, SQLCHAR *, SQLSMALLINT, SQLCHAR*,SQLSMALLINT))dlsym(handle,"SQLTables");
177 if (!ODBCFuncPtrs.SQLTablesPtr){
178 printError(ErrSysInternal, "Symbol lookup failed\n");
179 return ErrSysInternal;
182 symbolsLoaded=true;
183 return OK;
186 DbRetVal SqlOdbcConnection::connect (char *user, char * pass)
188 DbRetVal rv = OK;
189 char tdbname[IDENTIFIER_LENGTH];
190 char *dsnAda;
191 //Get the appropriate DSN
192 dsnAda=getDsn();
194 if(strcmp(dsnAda,"")==0)
195 rv=TableConf::config.getDsnAndTdb(Conf::config.getDSN(),dsn,tdbname);
196 else
197 rv=TableConf::config.getDsnAndTdb(dsnAda,dsn,tdbname);
199 if(rv!=OK){
200 printError(rv,"Add Entry To csqlds.conf");
201 return rv;
203 setTrDbName(tdbname);
204 int retVal =0;
205 if (!symbolsLoaded) {
206 loadSymbols();
208 if (!symbolsLoaded) {
209 printError(ErrSysFatal, "Unable to load symbols. check LD_LIBRARY_PATH");
210 return ErrSysFatal;
212 retVal = (*ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_ENV,
213 SQL_NULL_HANDLE, &envHdl);
214 if (retVal)
216 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
217 return ErrSysInit;
220 (*ODBCFuncPtrs.SQLSetEnvAttrPtr)(envHdl, SQL_ATTR_ODBC_VERSION,
221 (void *) SQL_OV_ODBC3, 0);
223 retVal = (*ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_DBC,
224 envHdl, &dbHdl);
225 if (retVal)
227 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
228 return ErrSysInit;
230 SQLCHAR outstr[1024];
231 SQLSMALLINT outstrlen;
232 retVal = (*ODBCFuncPtrs.SQLDriverConnectPtr)(dbHdl, NULL, (SQLCHAR*)dsn,
233 SQL_NTS,outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_NOPROMPT);
235 if (!SQL_SUCCEEDED(retVal)) {
236 printError(ErrSysInit, "Failed to connect to target database using dsn=%s\n", dsn);
238 SQLINTEGER i = 0;
239 SQLINTEGER native;
240 SQLCHAR state[ 7 ];
241 SQLCHAR text[256];
242 SQLSMALLINT len;
243 SQLRETURN ret;
245 fprintf(stderr,
246 "\n"
247 "The driver reported the following diagnostics whilst running "
248 "\n\n");
252 ret = (*ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_DBC, dbHdl, ++i,
253 state, &native, text, sizeof(text), &len );
255 if (SQL_SUCCEEDED(ret))
256 printf("%s:%ld:%ld:%s\n", state, i, native, text);
258 while( ret == SQL_SUCCESS );
259 rv = ErrNoConnection;
260 //rv = OK; //masking the error:tmp
262 logFine(Conf::logger, "Connecting with dsn=%s\n", dsn);
263 (*ODBCFuncPtrs.SQLSetConnectAttrPtr)(dbHdl, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
264 if (rv == OK) isConnOpen = true;
265 return rv;
269 DbRetVal SqlOdbcConnection::disconnect()
271 DbRetVal rv = OK;
272 (*ODBCFuncPtrs.SQLDisconnectPtr)(dbHdl);
273 (*ODBCFuncPtrs.SQLFreeHandlePtr) (SQL_HANDLE_DBC, dbHdl);
274 (*ODBCFuncPtrs.SQLFreeHandlePtr) (SQL_HANDLE_ENV, envHdl);
275 logFine(Conf::logger, "disconnected");
276 if (rv == OK) isConnOpen = false;
277 return rv;
280 void SqlOdbcConnection::setTrDbName(char *name)
282 if(strcasecmp(name, "mysql")==0)
283 tdbName=mysql;
284 else if(strcasecmp(name, "postgres")==0)
285 tdbName = postgres;
286 else printError(ErrNotFound,"Target Database Name is not properly set.Tdb name could be mysql, postgres, sybase, db2, oracle\n");
287 return;
290 DbRetVal SqlOdbcConnection::beginTrans(IsolationLevel isoLevel, TransSyncMode mode)
292 if (prevIsoLevel == isoLevel) return OK;
293 DbRetVal rv = OK;
294 int retVal =0;
295 SQLPOINTER iso;
297 switch(isoLevel)
299 case READ_UNCOMMITTED:
300 iso = (SQLPOINTER)SQL_TXN_READ_UNCOMMITTED;
301 break;
302 case READ_COMMITTED:
303 iso = (SQLPOINTER)SQL_TXN_READ_COMMITTED;
304 break;
305 case READ_REPEATABLE:
306 iso = (SQLPOINTER)SQL_TXN_REPEATABLE_READ;
307 break;
308 default:
309 iso = (SQLPOINTER)SQL_TXN_READ_COMMITTED;
310 break;
313 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
314 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
315 retVal = (*ODBCFuncPtrs.SQLSetConnectAttrPtr)(dbHdl, SQL_ATTR_TXN_ISOLATION, iso, 0);
316 if (!SQL_SUCCEEDED(retVal)) return ErrSysInit;
317 prevIsoLevel = isoLevel;
318 //retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
319 //if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
320 return rv;
323 DbRetVal SqlOdbcConnection::commit()
325 DbRetVal rv = OK;
326 int retVal=0;
327 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_COMMIT);
328 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
329 else
330 logFinest(Conf::logger, "Transaction Committed");
331 return rv;
334 DbRetVal SqlOdbcConnection::rollback()
336 DbRetVal rv = OK;
337 int retVal =0;
338 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
339 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
340 else
341 logFinest(Conf::logger, "Transaction Rollback");
342 return rv;
345 void SqlOdbcConnection::setErrorState( SQLHDBC dbc)
347 SQLINTEGER i = 0;
348 SQLINTEGER native;
349 SQLCHAR state[ 7 ];
350 SQLCHAR text[256];
351 SQLSMALLINT len;
352 SQLRETURN ret;
353 ret = (*ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_DBC, dbc, ++i,
354 state, &native, text, sizeof(text), &len );
356 if (SQL_SUCCEEDED(ret)){
357 printf("%s:%ld:%ld:%s\n", state, i, native, text);
358 strcpy(errState,(char*)state);