csqlcacheserver reconnect, logger rotate, monitor_server
[csql.git] / src / adapter / SqlOdbcConnection.cxx
blob238d9db8d19339646830011a3546ff8900581d1c
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;
185 DbRetVal SqlOdbcConnection::connect (char *user, char * pass)
187 DbRetVal rv = OK;
188 char tdbname[IDENTIFIER_LENGTH];
189 char *dsnAda;
190 //Get the appropriate DSN
191 dsnAda=getDsn();
193 if(strcmp(dsnAda,"")==0)
194 rv=TableConf::config.getDsnAndTdb(Conf::config.getDSN(),dsn,tdbname);
195 else
196 rv=TableConf::config.getDsnAndTdb(dsnAda,dsn,tdbname);
198 if(rv!=OK){
199 printError(rv,"Add Entry To csqlds.conf");
200 return rv;
202 setTrDbName(tdbname);
203 int retVal =0;
204 if (!symbolsLoaded) {
205 loadSymbols();
207 if (!symbolsLoaded) {
208 printError(ErrSysFatal, "Unable to load symbols. check LD_LIBRARY_PATH");
209 return ErrSysFatal;
211 retVal = (*ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_ENV,
212 SQL_NULL_HANDLE, &envHdl);
213 if (retVal)
215 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
216 return ErrSysInit;
219 (*ODBCFuncPtrs.SQLSetEnvAttrPtr)(envHdl, SQL_ATTR_ODBC_VERSION,
220 (void *) SQL_OV_ODBC3, 0);
222 retVal = (*ODBCFuncPtrs.SQLAllocHandlePtr) (SQL_HANDLE_DBC,
223 envHdl, &dbHdl);
224 if (retVal)
226 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
227 return ErrSysInit;
229 SQLCHAR outstr[1024];
230 SQLSMALLINT outstrlen;
231 retVal = (*ODBCFuncPtrs.SQLDriverConnectPtr)(dbHdl, NULL, (SQLCHAR*)dsn,
232 SQL_NTS,outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_NOPROMPT);
234 if (!SQL_SUCCEEDED(retVal)) {
235 printError(ErrSysInit, "Failed to connect to target database using dsn=%s\n", dsn);
237 SQLINTEGER i = 0;
238 SQLINTEGER native;
239 SQLCHAR state[ 7 ];
240 SQLCHAR text[256];
241 SQLSMALLINT len;
242 SQLRETURN ret;
244 fprintf(stderr,
245 "\n"
246 "The driver reported the following diagnostics whilst running "
247 "\n\n");
251 ret = (*ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_DBC, dbHdl, ++i,
252 state, &native, text, sizeof(text), &len );
254 if (SQL_SUCCEEDED(ret))
255 printf("%s:%ld:%ld:%s\n", state, i, native, text);
257 while( ret == SQL_SUCCESS );
258 rv = ErrNoConnection;
259 //rv = OK; //masking the error:tmp
261 logFine(Conf::logger, "Connecting with dsn=%s\n", dsn);
262 (*ODBCFuncPtrs.SQLSetConnectAttrPtr)(dbHdl, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
263 return rv;
267 DbRetVal SqlOdbcConnection::disconnect()
269 DbRetVal rv = OK;
270 (*ODBCFuncPtrs.SQLDisconnectPtr)(dbHdl);
271 (*ODBCFuncPtrs.SQLFreeHandlePtr) (SQL_HANDLE_DBC, dbHdl);
272 (*ODBCFuncPtrs.SQLFreeHandlePtr) (SQL_HANDLE_ENV, envHdl);
273 logFine(Conf::logger, "disconnected");
274 return rv;
276 void SqlOdbcConnection::setTrDbName(char *name)
278 if(strcasecmp(name, "mysql")==0)
279 tdbName=mysql;
280 else if(strcasecmp(name, "postgres")==0)
281 tdbName = postgres;
282 else printError(ErrNotFound,"Target Database Name is not properly set.Tdb name could be mysql, postgres, sybase, db2, oracle\n");
283 return;
285 DbRetVal SqlOdbcConnection::beginTrans(IsolationLevel isoLevel, TransSyncMode mode)
287 if (prevIsoLevel == isoLevel) return OK;
288 DbRetVal rv = OK;
289 int retVal =0;
290 SQLPOINTER iso;
292 switch(isoLevel)
294 case READ_UNCOMMITTED:
295 iso = (SQLPOINTER)SQL_TXN_READ_UNCOMMITTED;
296 break;
297 case READ_COMMITTED:
298 iso = (SQLPOINTER)SQL_TXN_READ_COMMITTED;
299 break;
300 case READ_REPEATABLE:
301 iso = (SQLPOINTER)SQL_TXN_REPEATABLE_READ;
302 break;
303 default:
304 iso = (SQLPOINTER)SQL_TXN_READ_COMMITTED;
305 break;
308 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
309 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
310 retVal = (*ODBCFuncPtrs.SQLSetConnectAttrPtr)(dbHdl, SQL_ATTR_TXN_ISOLATION, iso, 0);
311 if (!SQL_SUCCEEDED(retVal)) return ErrSysInit;
312 prevIsoLevel = isoLevel;
313 //retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
314 //if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
315 return rv;
317 DbRetVal SqlOdbcConnection::commit()
319 DbRetVal rv = OK;
320 int retVal=0;
321 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_COMMIT);
322 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
323 else
324 logFinest(Conf::logger, "Transaction Committed");
325 return rv;
327 DbRetVal SqlOdbcConnection::rollback()
329 DbRetVal rv = OK;
330 int retVal =0;
331 retVal = (*ODBCFuncPtrs.SQLTransactPtr)(envHdl, dbHdl, SQL_ROLLBACK);
332 if (!SQL_SUCCEEDED(retVal)) rv = ErrSysInit;
333 else
334 logFinest(Conf::logger, "Transaction Rollback");
335 return rv;
337 void SqlOdbcConnection::setErrorState( SQLHDBC dbc)
339 SQLINTEGER i = 0;
340 SQLINTEGER native;
341 SQLCHAR state[ 7 ];
342 SQLCHAR text[256];
343 SQLSMALLINT len;
344 SQLRETURN ret;
345 ret = (*ODBCFuncPtrs.SQLGetDiagRecPtr)(SQL_HANDLE_DBC, dbc, ++i,
346 state, &native, text, sizeof(text), &len );
348 if (SQL_SUCCEEDED(ret)){
349 printf("%s:%ld:%ld:%s\n", state, i, native, text);
350 strcpy(errState,(char*)state);