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 <SqlGwConnection.h>
21 #include <SqlOdbcStatement.h>
22 #include <SqlGwStatement.h>
23 #include <SqlLogStatement.h>
24 #include <CacheTableLoader.h>
25 #include <TableConfig.h>
27 DbRetVal
SqlGwStatement::executeDirect(char *stmtstr
)
31 rv
= prepare(stmtstr
);
32 if (rv
!= OK
) return rv
;
34 if (rv
!= OK
) return rv
;
38 DbRetVal
SqlGwStatement::prepare(char *stmtstr
)
40 char dsnname
[IDENTIFIER_LENGTH
];
42 char tab
[IDENTIFIER_LENGTH
];
45 bool SyntaxError
=false;
46 DbRetVal rv
= OK
,ret
=OK
;
47 char *stmtTblName
= NULL
;
49 SqlGwConnection
*conn
= (SqlGwConnection
*) con
;
50 if (!conn
->isAdptConnected() && !conn
->isCsqlConnected()) return ErrNoConnection
;
51 SqlOdbcStatement
*ada
=(SqlOdbcStatement
*) adapter
;
52 struct MultiDSN
*node
= conn
->multi_adapter_head
; //
55 if (innerStmt
) rv
= innerStmt
->prepare(stmtstr
);
56 if (rv
== OK
) isPrepared
= true;
57 if (rv
== ErrNotOpen
) connClose
=true;//new line addded for MultiDsn
58 if (rv
== ErrSyntaxError
) SyntaxError
=true;//new line addded for MultiDsn
59 stmtTblName
= innerStmt
->getTableName();
61 bool isAllcachedTableForJoin
= true;
64 StatementType stype
= innerStmt
->getStmtType();
65 printDebug(DM_Gateway
,"Table Name %s\t Stmt Type %d\n",stmtTblName
, stype
);
66 if (stype
== CacheTableStatement
|| stype
== CompactTableStatement
)
68 stmtHdlr
= CSqlHandler
;
72 ListIterator titer
=innerStmt
->getTableNameList().getIterator();
73 while (titer
.hasElement())
75 TableName
*t
= (TableName
*)titer
.nextElement();
76 ret
= TableConf::config
.isTableCached(t
->tblName
);
77 if(ret
!=OK
) isAllcachedTableForJoin
=false;
80 if(noOfTable
== 1) { isAllcachedTableForJoin
= true; }
81 mode
= TableConf::config
.getTableMode(stmtTblName
);
82 bool isCached
= TableConf::config
.isTableCached(mode
);
83 bool isSelStmt
= innerStmt
->isSelect();
84 bool localTable
= false;
85 if (rv
== OK
&& mode
== 0) localTable
= true;
86 bool isDirect
= mode
& DIRECT_CACHE
;
87 /* if((mode==2||mode==6) && !innerStmt->isSelect())
89 printError(ErrReadOnlyCache, "Partial Cache Condition Violation for Non select Dml statement\n");
90 return ErrReadOnlyCache;
93 if ((rv
== OK
) && (!isDirect
|| isSelStmt
) && isAllcachedTableForJoin
)
95 stmtHdlr
= CSqlHandler
;
96 if (localTable
|| isSelStmt
|| (( isCached
) && Conf::config
.getCacheMode()==ASYNC_MODE
))
99 //TODO::add procedures also in the below checking
100 if (!strncasecmp(stmtstr
,"INSERT", 6) == 0 &&
101 !strncasecmp(stmtstr
, "UPDATE", 6) ==0 &&
102 !strncasecmp(stmtstr
, "SELECT", 6) ==0 &&
103 !strncasecmp(stmtstr
, "DELETE", 6) ==0 &&
104 (NULL
==strstr(stmtstr
,"call ") && NULL
== strstr(stmtstr
,"CALL ")) )return rv
;
106 printDebug(DM_Gateway
, "Handled by csql %d\n", shouldCSqlHandle());
108 if (!shouldCSqlHandle()) stmtHdlr
= AdapterHandler
;
109 if ( shouldCSqlHandle() && Conf::config
.getCacheMode() == SYNC_MODE
&&
110 !isSelStmt
&& isCached
) stmtHdlr
= CSqlAndAdapterHandler
;
112 printDebug(DM_Gateway
, "Handled %d\n", stmtHdlr
);
113 strcpy(tab
, stmtTblName
);
115 /*********The below code is for MultiDsn.***********/
117 //If Prepared by CSQL and if the table is cached.
118 if(isPrepared
&& (ret
= TableConf::config
.getDsnForTable(tab
,dsn
)) == OK
) {
119 if (adapter
&& shouldAdapterHandle()) {
120 adapter
->setConnection(conn
->getAdapterConnection(dsnname
));
121 rv
= adapter
->prepare(stmtstr
);
122 if (rv
== OK
) setToCommit(dsnname
);
125 //Default adapter should prepare when table name is not found by csql's prepare(),
126 //This happens only when csql connection is down or there is a complex query.
127 if((stmtHdlr
== AdapterHandler
&& connClose
) || SyntaxError
){
128 adapter
->setConnection(conn
->getAdapterConnection(Conf::config
.getDSN()));
129 if(adapter
&& shouldAdapterHandle()){
130 rv
= adapter
->prepare(stmtstr
);
131 setToCommit(Conf::config
.getDSN());
134 //For non-cached TDB tables, where the table name is found in csql prepare.
135 if(!isPrepared
&& !SyntaxError
&& !connClose
) {
136 if(conn
->noOfCon
== 1){
137 adapter
->setConnection(conn
->getAdapterConnection(node
->dsn
));
138 if(adapter
&& shouldAdapterHandle()) {
139 rv
= adapter
->prepare(stmtstr
);
140 if(rv
== OK
) node
->toCommit
=true;
143 while(node
!= NULL
) {
145 adapter
->setConnection(conn
->getAdapterConnection(node
->dsn
));
146 if(ada
->isTableExists(tab
)){
147 if(adapter
&& shouldAdapterHandle()){
148 rv
= adapter
->prepare(stmtstr
);
149 if(rv
== OK
) node
->toCommit
=true;
154 }//while Ends here....
158 printError(ErrBadCall
, "Both adapter and csql could not prepare");
160 }else isPrepared
= true;
164 bool SqlGwStatement::shouldAdapterHandle()
166 if (stmtHdlr
== AdapterHandler
|| (stmtHdlr
== CSqlAndAdapterHandler
)) return true;
169 bool SqlGwStatement::shouldCSqlHandle()
171 SqlGwConnection
*conn
= (SqlGwConnection
*) con
;
172 if (stmtHdlr
== CSqlHandler
||
173 stmtHdlr
== CSqlAndAdapterHandler
) return true;
176 bool SqlGwStatement::isSelect()
179 if (adapter
&& shouldAdapterHandle()) retValue
= adapter
->isSelect();
180 if (innerStmt
&& shouldCSqlHandle()) retValue
= innerStmt
->isSelect();
184 DbRetVal
SqlGwStatement::execute(int &rowsAffected
)
187 SqlGwConnection
*conn
= (SqlGwConnection
*) con
;
188 if (!conn
->isAdptConnected() && !conn
->isCsqlConnected()) return ErrNoConnection
;
189 if (!isPrepared
) { return ErrNotPrepared
; }
190 if (adapter
&& shouldAdapterHandle()) {
191 rv
= adapter
->execute(rowsAffected
);
193 if (rv
!= OK
) return rv
;
194 if (shouldAdapterHandle())
196 GwHandler hdlr
= conn
->getTxnHandler();
197 if (hdlr
== NoHandler
) conn
->setTxnHandler(AdapterHandler
);
198 if (hdlr
== CSqlHandler
) conn
->setTxnHandler(CSqlAndAdapterHandler
);
200 if (innerStmt
&& shouldCSqlHandle()) rv
= innerStmt
->execute(rowsAffected
);
201 if (shouldCSqlHandle())
203 GwHandler hdlr
= conn
->getTxnHandler();
204 if (hdlr
== NoHandler
) conn
->setTxnHandler(CSqlHandler
);
205 if (hdlr
== AdapterHandler
) conn
->setTxnHandler(CSqlAndAdapterHandler
);
210 DbRetVal
SqlGwStatement::bindParam(int pos
, void* value
)
213 printError(ErrWarning
, "Deprecated and does not replicate or cache");
217 DbRetVal
SqlGwStatement::bindField(int pos
, void* value
)
220 //TODO::this will never be handled by both. check the flag for this
221 if (adapter
&& shouldAdapterHandle()) rv
= adapter
->bindField(pos
, value
);
222 if (rv
!= OK
) return rv
;
223 if (innerStmt
&& shouldCSqlHandle()) rv
= innerStmt
->bindField(pos
,value
);
227 void* SqlGwStatement::fetch()
229 //TODO::this will never be handled by both. check the flag for this
230 if (adapter
&& shouldAdapterHandle()) return adapter
->fetch();
231 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->fetch();
235 void* SqlGwStatement::fetch(DbRetVal
&rv
)
237 //TODO::this will never be handled by both. check the flag for this
238 if (!isPrepared
) { rv
= ErrNotPrepared
; return NULL
; }
239 if (adapter
&& shouldAdapterHandle()) return adapter
->fetch(rv
);
240 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->fetch(rv
);
244 void* SqlGwStatement::fetchAndPrint(bool SQL
)
246 //TODO::this will never be handled by both. check the flag for this
247 if (adapter
&& shouldAdapterHandle()) return adapter
->fetchAndPrint(SQL
);
248 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->fetchAndPrint(SQL
);
252 void* SqlGwStatement::next()
254 //TODO::this will never be handled by both. check the flag for this
255 if (adapter
&& shouldAdapterHandle()) return adapter
->next();
256 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->next();
260 DbRetVal
SqlGwStatement::close()
262 //TODO::this will never be handled by both. check the flag for this
263 if (adapter
&& shouldAdapterHandle()) return adapter
->close();
264 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->close();
268 void* SqlGwStatement::getFieldValuePtr( int pos
)
270 //TODO::this will never be handled by both. check the flag for this
271 if (adapter
&& shouldAdapterHandle()) return adapter
->getFieldValuePtr(pos
);
272 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->getFieldValuePtr(pos
);
275 void SqlGwStatement::getProjFieldType(int *data
)
277 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->getProjFieldType(data
);
278 if (adapter
&& shouldAdapterHandle()) return adapter
->getProjFieldType(data
);
281 void* SqlGwStatement::getFieldValuePtr( char *name
)
283 if (adapter
&& shouldAdapterHandle()) return adapter
->getFieldValuePtr(name
);
284 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->getFieldValuePtr(name
);
287 int SqlGwStatement::noOfProjFields()
289 //TODO::this will never be handled by both. check the flag for this
290 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->noOfProjFields();
291 if (adapter
&& shouldAdapterHandle()) return adapter
->noOfProjFields();
295 int SqlGwStatement::noOfParamFields()
297 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->noOfParamFields();
298 if (adapter
&& shouldAdapterHandle()) return adapter
->noOfParamFields();
302 DbRetVal
SqlGwStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
304 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->getProjFldInfo(projpos
, fInfo
);
305 if (adapter
&& shouldAdapterHandle()) return adapter
->getProjFldInfo(projpos
, fInfo
);
309 DbRetVal
SqlGwStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
311 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->getParamFldInfo(parampos
, fInfo
);
312 if (adapter
&& shouldAdapterHandle()) return adapter
->getParamFldInfo(parampos
, fInfo
);
316 DbRetVal
SqlGwStatement::free()
319 if (!isPrepared
) return OK
;
320 if (adapter
&& shouldAdapterHandle()) rv
= adapter
->free();
321 if (innerStmt
&& shouldCSqlHandle()) rv
= innerStmt
->free();
322 stmtHdlr
= NoHandler
;
326 void SqlGwStatement::setShortParam(int paramPos
, short value
)
328 if (adapter
&& shouldAdapterHandle()) adapter
->setShortParam(paramPos
, value
);
329 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setShortParam(paramPos
,value
);
332 void SqlGwStatement::setIntParam(int paramPos
, int value
)
334 if (adapter
&& shouldAdapterHandle()) adapter
->setIntParam(paramPos
, value
);
335 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setIntParam(paramPos
,value
);
339 void SqlGwStatement::setLongParam(int paramPos
, long value
)
341 if (adapter
&& shouldAdapterHandle()) adapter
->setLongParam(paramPos
, value
);
342 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setLongParam(paramPos
,value
);
346 void SqlGwStatement::setLongLongParam(int paramPos
, long long value
)
348 if (adapter
&& shouldAdapterHandle()) adapter
->setLongLongParam(paramPos
, value
);
349 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setLongLongParam(paramPos
,value
);
352 void SqlGwStatement::setByteIntParam(int paramPos
, ByteInt value
)
354 if (adapter
&& shouldAdapterHandle()) adapter
->setByteIntParam(paramPos
, value
);
355 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setByteIntParam(paramPos
,value
);
358 void SqlGwStatement::setFloatParam(int paramPos
, float value
)
360 if (adapter
&& shouldAdapterHandle()) adapter
->setFloatParam(paramPos
, value
);
361 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setFloatParam(paramPos
,value
);
364 void SqlGwStatement::setDoubleParam(int paramPos
, double value
)
366 if (adapter
&& shouldAdapterHandle()) adapter
->setDoubleParam(paramPos
, value
);
367 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setDoubleParam(paramPos
,value
);
371 void SqlGwStatement::setStringParam(int paramPos
, char *value
)
373 if (adapter
&& shouldAdapterHandle()) adapter
->setStringParam(paramPos
, value
);
374 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setStringParam(paramPos
,value
);
377 void SqlGwStatement::setDateParam(int paramPos
, Date value
)
379 if (adapter
&& shouldAdapterHandle()) adapter
->setDateParam(paramPos
, value
);
380 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setDateParam(paramPos
,value
);
383 void SqlGwStatement::setTimeParam(int paramPos
, Time value
)
385 if (adapter
&& shouldAdapterHandle()) adapter
->setTimeParam(paramPos
, value
);
386 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setTimeParam(paramPos
,value
);
389 void SqlGwStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
391 if (adapter
&& shouldAdapterHandle()) adapter
->setTimeStampParam(paramPos
, value
);
392 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setTimeStampParam(paramPos
,value
);
395 void SqlGwStatement::setBinaryParam(int paramPos
, void *value
, int length
)
397 if (adapter
&& shouldAdapterHandle()) adapter
->setBinaryParam(paramPos
, value
, length
);
398 if (innerStmt
&& shouldCSqlHandle()) innerStmt
->setBinaryParam(paramPos
,value
, length
);
400 bool SqlGwStatement::isFldNull(int pos
)
402 if (adapter
&& shouldAdapterHandle()) return adapter
->isFldNull(pos
);
403 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->isFldNull(pos
);
406 bool SqlGwStatement::isFldNull(char *name
)
408 if (adapter
&& shouldAdapterHandle()) return adapter
->isFldNull(name
);
409 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->isFldNull(name
);
412 void SqlGwStatement::setNull(int pos
)
414 if (adapter
&& shouldAdapterHandle()) adapter
->setNull(pos
);
415 if (innerStmt
&& shouldCSqlHandle()) innerStmt
-> setNull(pos
);
417 List
SqlGwStatement::getAllTableNames(DbRetVal
&ret
)
419 printf("in csql\n"); if (innerStmt
) return innerStmt
->getAllTableNames(ret
);
420 printf("in Target Db\n"); if (adapter
) adapter
->getAllTableNames(ret
);
422 List
SqlGwStatement::getAllUserNames(DbRetVal
&ret
)
424 if (innerStmt
) return innerStmt
->getAllTableNames(ret
);
425 if (adapter
) adapter
->getAllTableNames(ret
);
428 ResultSetPlan
SqlGwStatement::getResultSetPlan()
430 if (adapter
&& shouldAdapterHandle()) return adapter
->getResultSetPlan();
431 if (innerStmt
&& shouldCSqlHandle()) return innerStmt
->getResultSetPlan();
434 long long SqlGwStatement::getLastInsertedVal(DbRetVal
&rv
)
436 if (innerStmt
) return innerStmt
->getLastInsertedVal(rv
);
437 if (adapter
) return adapter
->getLastInsertedVal(rv
);
440 //Function for COMMIT according to its name DSN
441 void SqlGwStatement::setToCommit(char *dsName
)
443 SqlGwConnection
*conn
= (SqlGwConnection
*) con
;
444 struct MultiDSN
*node
= conn
->multi_adapter_head
;
446 if(strcmp(dsName
,node
->dsn
)==0){