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 ***************************************************************************/
21 #include <Statement.h>
22 #include <SqlStatement.h>
26 extern ParsedData
*parsedData
;
29 bool SqlConnection::isInit
= false;
30 List
SqlConnection::connList
;
33 SqlStatement::~SqlStatement()
35 if (isPrepd
) { free(); isPrepd
= false; }
38 List
SqlStatement::getTableNameList()
40 return pData
.getTableNameList();
42 SqlStatement::SqlStatement()
49 isMgmtStatement
= false;
51 void SqlStatement::setConnection(AbsSqlConnection
*conn
)
53 sqlCon
= (SqlConnection
*)conn
;
57 void SqlStatement::setSqlConnection(SqlConnection
*conn
)
62 DbRetVal
SqlStatement::executeDirect(char *str
)
67 if (rv
!= OK
) return rv
;
69 if (rv
!= OK
) return rv
;
73 DbRetVal
SqlStatement::prepare(char *stmtstr
)
76 if (! sqlCon
->isConnectionOpen()) {
77 printError(ErrNotOpen
, "Connection not open");
80 SqlStatement
*cachedStmt
= sqlCon
->findInCache(stmtstr
);
84 this->stmt
->setParsedData(&this->pData
);
85 logFine(Conf::logger
,"GOT STMT FROM CACHE: %s %x", stmtstr
, cachedStmt
);
89 int ret
= ProcessManager::prepareMutex
.tryLock(10, 1000);
92 printError(ErrLockTimeOut
, "Unable to get prepare mutex");
93 return ErrLockTimeOut
;
96 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
97 if (isPrepared()) free();
101 yy_buffer_state
*yy_buffer
= yy_scan_string(stmtstr
);
103 if (yy_buffer
) yy_delete_buffer(yy_buffer
);
108 ProcessManager::prepareMutex
.releaseLock(-1, false);
109 return ErrSyntaxError
;
111 if( parsedData
->getStmtType() == MgmtStatement
)
115 isMgmtStatement
= true;
116 ProcessManager::prepareMutex
.releaseLock(-1, false);
117 logFine(Conf::logger
,"PREPARE: %s %x", stmtstr
, stmt
);
120 stmt
= StatementFactory::getStatement(parsedData
);
121 stmt
->setDbMgr(dbMgr
);
122 if( parsedData
->getStmtType() == UserStatement
)
124 UserManager
* userMgr
= sqlCon
->getConnObject().getUserManager();
125 UserTblStatement
*ustmt
= (UserTblStatement
*)stmt
;
126 ustmt
->setUserManager(userMgr
,sqlCon
->getConnObject().getUserName());
128 rv
= stmt
->resolve();
133 ProcessManager::prepareMutex
.releaseLock(-1, false);
137 if (Conf::config
.getStmtCacheSize()) {
138 if (stmt
->noOfParamFields() > 0) {
140 sqlCon
->addToCache(this, stmtstr
);
141 }else if (Conf::config
.useCacheNoParam())
143 if (parsedData
->getCacheWorthy())
146 sqlCon
->addToCache(this, stmtstr
);
151 ProcessManager::prepareMutex
.releaseLock(-1, false);
155 char* SqlStatement::getTableName()
157 return pData
.getTableName();
160 bool SqlStatement::isSelect()
162 if ((pData
.getStmtType() == SelectStatement
) || (pData
.getStmtType() == MetaStatement
)) return true;
166 bool SqlStatement::isPrepared() { return isPrepd
; }
168 DbRetVal
SqlStatement::execute(int &rowsAffected
)
171 if (! sqlCon
->isConnectionOpen()) {
172 printError(ErrNotOpen
, "Connection not open");
175 if (! isPrepared()) {
176 printError(ErrNotPrepared
, "Statement Not Prepared");
177 return ErrNotPrepared
;
179 if( isMgmtStatement
)
182 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
185 rv
= stmt
->execute(rowsAffected
);
186 if (rv
== ErrAlready
&& pData
.getStmtType() == SelectStatement
)
187 { //if previous scan is not closed, close it
188 SelStatement
*selStmt
= (SelStatement
*) stmt
;
190 rv
= stmt
->execute(rowsAffected
);
192 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
196 void* SqlStatement::fetch()
198 if (! sqlCon
->isConnectionOpen()) {
199 printError(ErrNotOpen
, "Connection not open");
202 if (! isPrepared()) {
203 printError(ErrNotPrepared
, "Statement Not Prepared");
206 if (pData
.getStmtType() == SelectStatement
) {
207 SelStatement
*selStmt
= (SelStatement
*) stmt
;
208 return selStmt
->fetch();
210 else if(pData
.getStmtType() == MetaStatement
){
211 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
212 return metaStmt
->fetch();
217 void* SqlStatement::fetch(DbRetVal
&rv
)
219 if (! sqlCon
->isConnectionOpen()) {
220 printError(ErrNotOpen
, "Connection not open");
223 if (! isPrepared()) {
224 printError(ErrNotPrepared
, "Statement Not Prepared");
227 if (pData
.getStmtType() == SelectStatement
) {
228 SelStatement
*selStmt
= (SelStatement
*) stmt
;
229 return selStmt
->fetch(rv
);
231 else if(pData
.getStmtType() == MetaStatement
){
232 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
233 return metaStmt
->fetch(rv
);
238 void* SqlStatement::fetchAndPrint(bool SQL
)
240 if (! sqlCon
->isConnectionOpen()) {
241 printError(ErrNotOpen
, "Connection not open");
244 if (! isPrepared()) {
245 printError(ErrNotPrepared
, "Statement Not Prepared");
248 if (pData
.getStmtType() != SelectStatement
) return NULL
;
249 SelStatement
*selStmt
= (SelStatement
*) stmt
;
250 return selStmt
->fetchAndPrint(SQL
);
253 DbRetVal
SqlStatement::bindParam(int pos
, void* value
)
256 rv
= stmt
->setParam(pos
, value
);
260 DbRetVal
SqlStatement::bindField(int pos
, void* value
)
263 if (pData
.getStmtType() == SelectStatement
) {
264 SelStatement
*selStmt
= (SelStatement
*) stmt
;
265 return selStmt
->setBindField(pos
, value
);
267 else if(pData
.getStmtType() == MetaStatement
){
268 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
269 return metaStmt
->setBindField(pos
, value
);
271 else { return ErrBadCall
;}
273 void* SqlStatement::next()
275 if (pData
.getStmtType() == SelectStatement
) {
276 SelStatement
*selStmt
= (SelStatement
*) stmt
;
277 return( (void*) selStmt
->next() );
279 else if(pData
.getStmtType() == MetaStatement
){
280 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
281 return( (void*) metaStmt
->next() );
286 bool SqlStatement::isFldNull(int pos
)
288 if (pData
.getStmtType() != SelectStatement
) return 0;
289 SelStatement
*selStmt
= (SelStatement
*) stmt
;
290 return (selStmt
->isFldNull(pos
));
292 bool SqlStatement::isFldNull(char *name
)
294 if (pData
.getStmtType() != SelectStatement
) return 0;
295 SelStatement
*selStmt
= (SelStatement
*) stmt
;
296 return (selStmt
->isFldNull(name
));
298 DbRetVal
SqlStatement::close()
300 if (pData
.getStmtType() == SelectStatement
) {
301 SelStatement
*selStmt
= (SelStatement
*) stmt
;
302 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
303 return selStmt
->close();
305 else if(pData
.getStmtType() == MetaStatement
){
306 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
307 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
308 return selStmt
->close();
313 void* SqlStatement::getParamValuePtr( int pos
)
315 //if (pData.getStmtType() != SelectStatement) return 0;
316 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
317 return( (void*) dmlStmt
->getParamValuePtr( pos
) );
320 char* SqlStatement::getFieldName( int pos
)
322 if (pData
.getStmtType() == SelectStatement
) {
323 SelStatement
*selStmt
= (SelStatement
*) stmt
;
324 return( (char*) selStmt
->getFieldName( pos
) );
326 else if(pData
.getStmtType() == MetaStatement
){
327 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
328 return( (char*) selStmt
->getFieldName( pos
) );
333 DataType
SqlStatement::getFieldType( int pos
)
335 if (pData
.getStmtType() == SelectStatement
) {
336 SelStatement
*selStmt
= (SelStatement
*) stmt
;
337 return( (DataType
) selStmt
->getFieldType( pos
) );
339 else if(pData
.getStmtType() == MetaStatement
){
340 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
341 return( (DataType
) selStmt
->getFieldType( pos
) );
343 else { return typeUnknown
;}
345 int SqlStatement::getFieldLength( int pos
)
347 if (pData
.getStmtType() == SelectStatement
) {
348 SelStatement
*selStmt
= (SelStatement
*) stmt
;
349 return( (int) selStmt
->getFieldLength( pos
) );
351 else if(pData
.getStmtType() == MetaStatement
){
352 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
353 return( (int) selStmt
->getFieldLength( pos
) );
358 void* SqlStatement::getFieldValuePtr( int pos
)
360 if (pData
.getStmtType() == SelectStatement
) {
361 SelStatement
*selStmt
= (SelStatement
*) stmt
;
362 return( (void*) selStmt
->getFieldValuePtr( pos
) );
364 else if(pData
.getStmtType() == MetaStatement
){
365 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
366 return( (void*) selStmt
->getFieldValuePtr( pos
) );
370 void* SqlStatement::getFieldValuePtr( char *name
)
372 if (pData
.getStmtType() == SelectStatement
) {
373 SelStatement
*selStmt
= (SelStatement
*) stmt
;
374 return( (void*) selStmt
->getFieldValuePtr( name
) );
376 else if(pData
.getStmtType() == MetaStatement
){
377 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
378 return( (void*) selStmt
->getFieldValuePtr( name
) );
383 int SqlStatement::noOfProjFields()
385 if (pData
.getStmtType() == SelectStatement
) {
386 SelStatement
*selStmt
= (SelStatement
*) stmt
;
387 return selStmt
->noOfProjFields();
389 else if(pData
.getStmtType() == MetaStatement
){
390 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
391 return selStmt
->noOfProjFields();
396 void SqlStatement::getProjFieldType(int *data
)
398 if (pData
.getStmtType() == SelectStatement
) {
399 SelStatement
*selStmt
= (SelStatement
*) stmt
;
400 return( selStmt
->getProjFieldType(data
) );
402 else if(pData
.getStmtType() == MetaStatement
){
403 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
404 return( selStmt
->getProjFieldType(data
) );
410 int SqlStatement::noOfParamFields()
412 return stmt
->noOfParamFields();
415 DbRetVal
SqlStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
418 if (pData
.getStmtType() == SelectStatement
) {
419 SelStatement
*selStmt
= (SelStatement
*) stmt
;
420 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
422 else if(pData
.getStmtType() == MetaStatement
){
423 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
424 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
425 } else { return ErrBadCall
;}
429 DbRetVal
SqlStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
432 if (pData
.getStmtType() ==SelectStatement
||
433 pData
.getStmtType() ==InsertStatement
||
434 pData
.getStmtType() ==UpdateStatement
||
435 pData
.getStmtType() ==DeleteStatement
)
438 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
439 rv
= dmlStmt
->getParamFldInfo(parampos
, fInfo
);
444 DbRetVal
SqlStatement::free()
446 logFinest(Conf::logger
,"FREE: %x", stmt
);
453 if(stmt
) delete stmt
;
456 isMgmtStatement
= false;
461 void SqlStatement::setNull(int pos
)
465 void SqlStatement::setShortParam(int paramPos
, short value
)
467 stmt
->setShortParam(paramPos
, value
);
469 void SqlStatement::setIntParam(int paramPos
, int value
)
471 stmt
->setIntParam(paramPos
, value
);
473 void SqlStatement::setLongParam(int paramPos
, long value
)
475 stmt
->setLongParam(paramPos
, value
);
477 void SqlStatement::setLongLongParam(int paramPos
, long long value
)
479 stmt
->setLongLongParam(paramPos
, value
);
481 void SqlStatement::setByteIntParam(int paramPos
, ByteInt value
)
483 stmt
->setByteIntParam(paramPos
, value
);
485 void SqlStatement::setFloatParam(int paramPos
, float value
)
487 stmt
->setFloatParam(paramPos
, value
);
489 void SqlStatement::setDoubleParam(int paramPos
, double value
)
491 stmt
->setDoubleParam(paramPos
, value
);
493 void SqlStatement::setStringParam(int paramPos
, char *value
)
495 stmt
->setStringParam(paramPos
, value
);
497 void SqlStatement::setDateParam(int paramPos
, Date value
)
499 stmt
->setDateParam(paramPos
, value
);
501 void SqlStatement::setTimeParam(int paramPos
, Time value
)
503 stmt
->setTimeParam(paramPos
, value
);
505 void SqlStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
507 stmt
->setTimeStampParam(paramPos
, value
);
509 void SqlStatement::setBinaryParam(int paramPos
, void *value
, int length
)
511 stmt
->setBinaryParam(paramPos
, value
, length
);
513 int SqlStatement::getFldPos(char *name
)
515 return stmt
->getFldPos(name
);
517 List
SqlStatement::getAllTableNames(DbRetVal
&ret
)
519 DatabaseManager
*dbMgr
= NULL
;
521 dbMgr
=sqlCon
->getConnObject().getDatabaseManager();
524 tbNmList
= dbMgr
->getAllTableNames(&rv
);
529 List
SqlStatement::getAllUserNames(DbRetVal
&ret
)
531 UserManager
*urMgr
= NULL
;
533 urMgr
=sqlCon
->getConnObject().getUserManager();
536 urNmList
= urMgr
->getAllUserNames(&rv
);
540 List
SqlStatement::getFieldNameList(const char *tblName
)
542 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
543 Table
*table
= dbMgr
->openTable(tblName
);
546 printError(ErrLockTimeOut
, "Unable to open table %s", tblName
);
549 List fldNameList
= table
->getFieldNameList();
550 dbMgr
->closeTable(table
);
553 DbRetVal
SqlStatement::getFieldInfo(const char *tblName
, const char *fldName
, FieldInfo
*&info
)
555 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
556 Table
*table
= dbMgr
->openTable(tblName
);
558 printError(ErrLockTimeOut
, "Unable to open table %s", tblName
);
559 return ErrLockTimeOut
;
561 DbRetVal rv
= table
->getFieldInfo(fldName
, info
);
562 dbMgr
->closeTable(table
);
565 void SqlStatement::setLoading(bool flag
)
567 if (pData
.getStmtType() == InsertStatement
||
568 pData
.getStmtType() == UpdateStatement
||
569 pData
.getStmtType() == DeleteStatement
)
571 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
572 dmlStmt
->setLoading(flag
);
577 int SqlStatement::getNoOfPagesForTable(char *tblName
)
579 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
580 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
581 return dbMgrImpl
->getNoOfPagesForTable(tblName
);
584 DbRetVal
SqlStatement::loadRecords(char *tblName
, void *buf
)
586 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
587 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
588 return dbMgrImpl
->loadRecords(tblName
, (char *) buf
);
591 DbRetVal
SqlStatement::pasteRecords(char *tblName
, void *buffer
)
593 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
594 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
595 return dbMgrImpl
->pasteRecords(tblName
, buffer
);
597 void SqlStatement::flushCacheStmt()
599 return sqlCon
->flushCacheStmt();
601 //-------------------------------------------------------------------
602 void SqlConnection::flushCacheStmt()
604 ListIterator iter
= cachedStmts
.getIterator();
605 while (iter
.hasElement()) {
606 CachedStmtNode
* node
= (CachedStmtNode
*) iter
.nextElement();
607 free(node
->sqlString
);
608 node
->sqlStmt
->setCachedStmt(false);
609 node
->sqlStmt
->free();
610 delete node
->sqlStmt
;
617 SqlStatement
* SqlConnection::findInCache(char *stmtstr
)
619 ListIterator iter
= cachedStmts
.getIterator();
620 int inputStmtLen
= strlen(stmtstr
);
621 CachedStmtNode
*node
= NULL
;
622 while ((node
= (CachedStmtNode
*)iter
.nextElement()) != NULL
)
624 if (node
->stmtLength
== inputStmtLen
)
626 if (0 == strcmp(node
->sqlString
, stmtstr
))
628 logFiner(Conf::logger
, "Statement Retrieved From Cache %x\n",
631 return node
->sqlStmt
;
637 void SqlConnection::addToCache(SqlStatement
*sqlStmt
, char* stmtString
)
639 SqlStatement
*stmt
= new SqlStatement();
641 CachedStmtNode
*node
= new CachedStmtNode();
642 node
->sqlStmt
= stmt
;
643 node
->stmtLength
= strlen(stmtString
);
644 node
->sqlString
= (char*)malloc(node
->stmtLength
+1);
645 strcpy(node
->sqlString
, stmtString
);
646 if (cachedStmts
.size() >= Conf::config
.getStmtCacheSize())
650 cachedStmts
.append(node
);
651 logFiner(Conf::logger
, "Statement added To Cache %x\n", node
->sqlStmt
);
652 logFinest(Conf::logger
, "Statement added To Cache %s\n", node
->sqlString
);
655 void SqlConnection::removeLeastUsed()
657 ListIterator iter
= cachedStmts
.getIterator();
658 CachedStmtNode
*node
= NULL
, *toRemove
=NULL
;
660 bool firstCall
= true;
661 while((node
= (CachedStmtNode
*) iter
.nextElement()) != NULL
)
665 lowHits
= node
->hits
;
666 toRemove
= node
; //if cache size is 1
669 if (lowHits
>= node
->hits
) toRemove
= node
;
671 cachedStmts
.remove(toRemove
);
672 logFiner(Conf::logger
, "Statement removed from Cache %x\n", toRemove
->sqlStmt
);
673 logFinest(Conf::logger
, "Statement removed from Cache %s\n", toRemove
->sqlString
);
676 SqlConnection::~SqlConnection()
680 if (isConnOpen
) disconnect();
682 static void sigUsr1Handler(int sig
)
684 ListIterator iter
= SqlConnection::connList
.getIterator();
685 SqlConnection
*conn
= NULL
;
686 while (iter
.hasElement())
688 conn
= (SqlConnection
*) iter
.nextElement();
689 conn
->flushCacheStmt();
691 os::signal(SIGCSQL1
, sigUsr1Handler
);
694 void SqlConnection::initialize()
696 os::signal(SIGCSQL1
, sigUsr1Handler
);