*** empty log message ***
[csql.git] / src / adapter / SqlOdbcConnection.cxx
blobfd93aa31a8e86e824ab0ecafb33b557ed53542f7
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 bool SqlOdbcConnection::symbolsLoaded= false;
25 struct SQLFuncPtrs SqlOdbcConnection::ODBCFuncPtrs;
27 DbRetVal SqlOdbcConnection::loadSymbols()
30 #ifdef WINNT
31 HMODULE this_process;
32 GetModuleHandleEx(0,0,&this_process);
33 HMODULE handle = GetModuleHandle(0);
34 #else
35 #ifdef x86_64
36 void *handle = RTLD_DEFAULT;
37 #else
38 void *handle = (void*) -1l;
39 #endif
40 #endif
42 ODBCFuncPtrs.SQLAllocHandlePtr = (SQLRETURN (*)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*))os::dlsym(
43 handle, "SQLAllocHandle");
44 if (!ODBCFuncPtrs.SQLAllocHandlePtr){
45 #ifndef WINNT
46 if (handle == RTLD_DEFAULT) handle = (void*) -1l; else handle = RTLD_DEFAULT;
47 #endif
48 ODBCFuncPtrs.SQLAllocHandlePtr = (SQLRETURN (*)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*))os::dlsym(
49 handle, "SQLAllocHandle");
50 if (!ODBCFuncPtrs.SQLAllocHandlePtr) {
51 printError(ErrSysInternal, "Symbol lookup failed\n");
52 return ErrSysInternal;
55 ODBCFuncPtrs.SQLSetEnvAttrPtr = (SQLRETURN (*)(SQLHENV, SQLINTEGER, SQLPOINTER, SQLINTEGER ))os::dlsym(handle, "SQLSetEnvAttr");
56 if (!ODBCFuncPtrs.SQLSetEnvAttrPtr){
57 printError(ErrSysInternal, "Symbol lookup failed\n");
58 return ErrSysInternal;
61 ODBCFuncPtrs.SQLDriverConnectPtr = (SQLRETURN (*)(SQLHDBC, SQLHWND, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLUSMALLINT ))os::dlsym(handle, "SQLDriverConnect");
62 if (!ODBCFuncPtrs.SQLDriverConnectPtr){
63 printError(ErrSysInternal, "Symbol lookup failed\n");
64 return ErrSysInternal;
67 ODBCFuncPtrs.SQLGetDiagRecPtr = (SQLRETURN (*)(SQLSMALLINT, SQLHANDLE, SQLSMALLINT, SQLCHAR*, SQLINTEGER*, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*))os::dlsym(handle, "SQLGetDiagRec");
68 if (!ODBCFuncPtrs.SQLGetDiagRecPtr){
69 printError(ErrSysInternal, "Symbol lookup failed\n");
70 return ErrSysInternal;
73 ODBCFuncPtrs.SQLSetConnectAttrPtr = (SQLRETURN (*)(SQLHDBC, SQLINTEGER, SQLPOINTER, SQLINTEGER ))os::dlsym(handle, "SQLSetConnectAttr");
74 if (!ODBCFuncPtrs.SQLSetConnectAttrPtr){
75 printError(ErrSysInternal, "Symbol lookup failed\n");
76 return ErrSysInternal;
78 ODBCFuncPtrs.SQLSetStmtAttrPtr = (SQLRETURN (*)(SQLHSTMT, SQLINTEGER, SQLPOINTER, SQLINTEGER ))os::dlsym(handle, "SQLSetStmtAttr");
79 if (!ODBCFuncPtrs.SQLSetStmtAttrPtr){
80 printError(ErrSysInternal, "Symbol lookup failed\n");
81 return ErrSysInternal;
84 ODBCFuncPtrs.SQLProcedureColumnsPtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR *, SQLSMALLINT, SQLCHAR *, SQLSMALLINT, SQLCHAR *, SQLSMALLINT, SQLCHAR *, SQLSMALLINT))os::dlsym(handle, "SQLProcedureColumns");
85 if (!ODBCFuncPtrs.SQLProcedureColumnsPtr){
86 printError(ErrSysInternal, "Symbol lookup failed\n");
87 return ErrSysInternal;
90 ODBCFuncPtrs.SQLFreeHandlePtr = (SQLRETURN (*)(SQLSMALLINT,SQLHANDLE))os::dlsym(handle, "SQLFreeHandle");
91 if (!ODBCFuncPtrs.SQLFreeHandlePtr){
92 printError(ErrSysInternal, "Symbol lookup failed\n");
93 return ErrSysInternal;
96 ODBCFuncPtrs.SQLTransactPtr = (SQLRETURN (*)(SQLHENV, SQLHDBC, SQLUSMALLINT ))os::dlsym(handle, "SQLTransact");
97 if (!ODBCFuncPtrs.SQLTransactPtr){
98 printError(ErrSysInternal, "Symbol lookup failed\n");
99 return ErrSysInternal;
102 ODBCFuncPtrs.SQLExecDirectPtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLINTEGER ))os::dlsym(handle, "SQLExecDirect");
103 if (!ODBCFuncPtrs.SQLExecDirectPtr){
104 printError(ErrSysInternal, "Symbol lookup failed\n");
105 return ErrSysInternal;
108 ODBCFuncPtrs.SQLPreparePtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLINTEGER ))os::dlsym(handle, "SQLPrepare");
109 if (!ODBCFuncPtrs.SQLPreparePtr){
110 printError(ErrSysInternal, "Symbol lookup failed\n");
111 return ErrSysInternal;
114 ODBCFuncPtrs.SQLNumResultColsPtr = (SQLRETURN (*)(SQLHSTMT, SQLSMALLINT* ))os::dlsym(handle, "SQLNumResultCols");
115 if (!ODBCFuncPtrs.SQLNumResultColsPtr){
116 printError(ErrSysInternal, "Symbol lookup failed\n");
117 return ErrSysInternal;
120 ODBCFuncPtrs.SQLDescribeColPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLCHAR*, SQLSMALLINT, SQLSMALLINT*, SQLSMALLINT*, SQLULEN*,SQLSMALLINT*, SQLSMALLINT* ))os::dlsym(handle, "SQLDescribeCol");
121 if (!ODBCFuncPtrs.SQLDescribeColPtr){
122 printError(ErrSysInternal, "Symbol lookup failed\n");
123 return ErrSysInternal;
126 ODBCFuncPtrs.SQLBindColPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN* ))os::dlsym(handle, "SQLBindCol");
127 if (!ODBCFuncPtrs.SQLBindColPtr){
128 printError(ErrSysInternal, "Symbol lookup failed\n");
129 return ErrSysInternal;
132 ODBCFuncPtrs.SQLNumParamsPtr = (SQLRETURN (*)(SQLHSTMT, SQLSMALLINT* ))os::dlsym(handle, "SQLNumParams");
133 if (!ODBCFuncPtrs.SQLNumParamsPtr){
134 printError(ErrSysInternal, "Symbol lookup failed\n");
135 return ErrSysInternal;
138 ODBCFuncPtrs.SQLDescribeParamPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT*, SQLULEN*, SQLSMALLINT*, SQLSMALLINT* ))os::dlsym(handle, "SQLDescribeParam");
139 if (!ODBCFuncPtrs.SQLDescribeParamPtr){
140 printError(ErrSysInternal, "Symbol lookup failed\n");
141 return ErrSysInternal;
144 ODBCFuncPtrs.SQLBindParameterPtr = (SQLRETURN (*)(SQLHSTMT, SQLUSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLSMALLINT, SQLULEN, SQLSMALLINT, SQLPOINTER, SQLLEN, SQLLEN* ))os::dlsym(handle, "SQLBindParameter");
145 if (!ODBCFuncPtrs.SQLBindParameterPtr){
146 printError(ErrSysInternal, "Symbol lookup failed\n");
147 return ErrSysInternal;
150 ODBCFuncPtrs.SQLExecutePtr = (SQLRETURN (*)(SQLHSTMT ))os::dlsym(handle, "SQLExecute");
151 if (!ODBCFuncPtrs.SQLExecutePtr){
152 printError(ErrSysInternal, "Symbol lookup failed\n");
153 return ErrSysInternal;
156 ODBCFuncPtrs.SQLRowCountPtr = (SQLRETURN (*)(SQLHSTMT, SQLLEN* ))os::dlsym(handle, "SQLRowCount");
157 if (!ODBCFuncPtrs.SQLRowCountPtr){
158 printError(ErrSysInternal, "Symbol lookup failed\n");
159 return ErrSysInternal;
162 ODBCFuncPtrs.SQLFetchPtr = (SQLRETURN (*)(SQLHSTMT ))os::dlsym(handle, "SQLFetch");
163 if (!ODBCFuncPtrs.SQLFetchPtr){
164 printError(ErrSysInternal, "Symbol lookup failed\n");
165 return ErrSysInternal;
168 ODBCFuncPtrs.SQLFetchScrollPtr = (SQLRETURN (*)(SQLHSTMT, SQLSMALLINT, SQLLEN))os::dlsym(handle, "SQLFetchScroll");
169 if (!ODBCFuncPtrs.SQLFetchScrollPtr){
170 printError(ErrSysInternal, "Symbol lookup failed\n");
171 return ErrSysInternal;
174 ODBCFuncPtrs.SQLCloseCursorPtr = (SQLRETURN (*)(SQLHSTMT ))os::dlsym(handle, "SQLCloseCursor");
175 if (!ODBCFuncPtrs.SQLCloseCursorPtr){
176 printError(ErrSysInternal, "Symbol lookup failed\n");
177 return ErrSysInternal;
180 ODBCFuncPtrs.SQLPrimaryKeysPtr = (SQLRETURN (*)(SQLHSTMT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT, SQLCHAR*, SQLSMALLINT ))os::dlsym(handle, "SQLPrimaryKeys");
181 if (!ODBCFuncPtrs.SQLPrimaryKeysPtr){
182 printError(ErrSysInternal, "Symbol lookup failed\n");
183 return ErrSysInternal;
186 ODBCFuncPtrs.SQLGetDataPtr = (SQLRETURN (*)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER, SQLLEN,SQLLEN* ))os::dlsym(handle, "SQLGetData");
187 if (!ODBCFuncPtrs.SQLGetDataPtr){
188 printError(ErrSysInternal, "Symbol lookup failed\n");
189 return ErrSysInternal;
192 ODBCFuncPtrs.SQLDisconnectPtr = (SQLRETURN (*)(SQLHDBC))os::dlsym(handle, "SQLDisconnect");
193 if (!ODBCFuncPtrs.SQLDisconnectPtr){
194 printError(ErrSysInternal, "Symbol lookup failed\n");
195 return ErrSysInternal;
197 ODBCFuncPtrs.SQLTablesPtr =(SQLRETURN (*)(SQLHSTMT ,SQLCHAR *, SQLSMALLINT , SQLCHAR * , SQLSMALLINT, SQLCHAR *, SQLSMALLINT, SQLCHAR*,SQLSMALLINT))os::dlsym(handle,"SQLTables");
198 if (!ODBCFuncPtrs.SQLTablesPtr){
199 printError(ErrSysInternal, "Symbol lookup failed\n");
200 return ErrSysInternal;
204 symbolsLoaded=true;
205 return OK;
208 DbRetVal SqlOdbcConnection::connect (char *user, char * pass)
210 DbRetVal rv = OK;
211 char tdbname[IDENTIFIER_LENGTH];
212 char *dsname = getDsName();
214 if(strcmp(dsname,"")==0)
215 rv=TableConf::config.getDsnAndTdb(Conf::config.getDSN(), dsString,
216 tdbname);
217 else
218 rv=TableConf::config.getDsnAndTdb(dsname,dsString,tdbname);
220 if(rv!=OK){
221 printError(rv,"Add Entry To csqlds.conf");
222 return rv;
224 setTrDbName(tdbname);
225 int retVal =0;
226 if (!symbolsLoaded) {
227 loadSymbols();
229 if (!symbolsLoaded) {
230 printError(ErrSysFatal, "Unable to load symbols. check LD_LIBRARY_PATH");
231 return ErrSysFatal;
233 retVal = (*ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_ENV,
234 SQL_NULL_HANDLE, &envHdl);
235 if (retVal)
237 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
238 return ErrSysInit;
241 (*ODBCFuncPtrs.SQLSetEnvAttrPtr)(envHdl, SQL_ATTR_ODBC_VERSION,
242 (void *) SQL_OV_ODBC3, 0);
244 retVal = (*ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_DBC,
245 envHdl, &dbHdl);
246 if (retVal)
248 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
249 return ErrSysInit;
251 SQLCHAR outstr[1024];
252 SQLSMALLINT outstrlen;
253 retVal = (*ODBCFuncPtrs.SQLDriverConnectPtr)(dbHdl, NULL, (SQLCHAR*)dsString, SQL_NTS,outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_NOPROMPT);
255 if (!SQL_SUCCEEDED(retVal)) {
256 printError(ErrSysInit, "Failed to connect to target database using dsn=%s\n", dsString);
258 SQLINTEGER i = 0;
259 SQLINTEGER native;
260 SQLCHAR state[ 7 ];
261 SQLCHAR text[256];
262 SQLSMALLINT len;
263 SQLRETURN ret;
265 fprintf(stderr,
266 "\n"
267 "The driver reported the following diagnostics whilst running "
268 "\n\n");
272 ret = (*ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_DBC, dbHdl, ++i,
273 state, &native, text, sizeof(text), &len );
275 if (SQL_SUCCEEDED(ret))
276 printf("%s:%ld:%ld:%s\n", state, i, native, text);
278 while( ret == SQL_SUCCESS );
279 rv = ErrNoConnection;
280 //rv = OK; //masking the error:tmp
282 logFine(Conf::logger, "Connecting with dsn=%s\n", dsString);
283 (*ODBCFuncPtrs.SQLSetConnectAttrPtr)(dbHdl, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
284 if (rv == OK) isConnOpen = true;
285 return rv;
289 DbRetVal SqlOdbcConnection::disconnect()
291 DbRetVal rv = OK;
292 (*ODBCFuncPtrs.SQLDisconnectPtr)(dbHdl);
293 (*ODBCFuncPtrs.SQLFreeHandlePtr) (SQL_HANDLE_DBC, dbHdl);
294 (*ODBCFuncPtrs.SQLFreeHandlePtr) (SQL_HANDLE_ENV, envHdl);
295 logFine(Conf::logger, "disconnected");
296 if (rv == OK) isConnOpen = false;
297 return rv;
300 void SqlOdbcConnection::setTrDbName(char *name)
302 if(strcasecmp(name, "mysql")==0)
303 tdbName=mysql;
304 else if(strcasecmp(name, "postgres")==0)
305 tdbName = postgres;
306 else printError(ErrNotFound,"Target Database Name is not properly set.Tdb name could be mysql, postgres, sybase, db2, oracle\n");
307 return;
310 DbRetVal SqlOdbcConnection::beginTrans(IsolationLevel isoLevel, TransSyncMode mode)
312 if (prevIsoLevel == isoLevel) return OK;
313 DbRetVal rv = OK;
314 int retVal =0;
315 SQLPOINTER iso;
317 switch(isoLevel)
319 case READ_UNCOMMITTED:
320 iso = (SQLPOINTER)SQL_TXN_READ_UNCOMMITTED;
321 break;
322 case READ_COMMITTED:
323 iso = (SQLPOINTER)SQL_TXN_READ_COMMITTED;
324 break;
325 case READ_REPEATABLE:
326 iso = (SQLPOINTER)SQL_TXN_REPEATABLE_READ;
327 break;
328 default:
329 iso = (SQLPOINTER)SQL_TXN_READ_COMMITTED;
330 break;
333 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
334 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
335 retVal = (*ODBCFuncPtrs.SQLSetConnectAttrPtr)(dbHdl, SQL_ATTR_TXN_ISOLATION, iso, 0);
336 if (!SQL_SUCCEEDED(retVal)) return ErrSysInit;
337 prevIsoLevel = isoLevel;
338 //retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
339 //if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
340 return rv;
343 DbRetVal SqlOdbcConnection::commit()
345 DbRetVal rv = OK;
346 int retVal=0;
347 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_COMMIT);
348 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
349 else
350 logFinest(Conf::logger, "Transaction Committed");
351 return rv;
354 DbRetVal SqlOdbcConnection::rollback()
356 DbRetVal rv = OK;
357 int retVal =0;
358 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
359 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
360 else
361 logFinest(Conf::logger, "Transaction Rollback");
362 return rv;
365 void SqlOdbcConnection::setErrorState( SQLHDBC dbc)
367 SQLINTEGER i = 0;
368 SQLINTEGER native;
369 SQLCHAR state[ 7 ];
370 SQLCHAR text[256];
371 SQLSMALLINT len;
372 SQLRETURN ret;
373 ret = (*ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_DBC, dbc, ++i,
374 state, &native, text, sizeof(text), &len );
376 if (SQL_SUCCEEDED(ret)){
377 printf("%s:%ld:%ld:%s\n", state, i, native, text);
378 strcpy(errState,(char*)state);