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 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
90 Database
*sysdb
= ((DatabaseManagerImpl
*)dbMgr
)->sysDb();
91 int tries
= Conf::config
.getMutexRetries();
92 struct timeval timeout
;
93 timeout
.tv_sec
= Conf::config
.getMutexSecs();
94 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
97 rv
= sysdb
->getPrepareStmtMutex();
102 "Unable to get prepare statement mutex after %d tries", Conf::config
.getMutexRetries());
105 os::select(0, 0, 0, 0, &timeout
);
108 if (isPrepared()) free();
112 yy_buffer_state
*yy_buffer
= yy_scan_string(stmtstr
);
114 if (yy_buffer
) yy_delete_buffer(yy_buffer
);
120 sysdb
->releasePrepareStmtMutex();
121 return ErrSyntaxError
;
123 if( parsedData
->getStmtType() == MgmtStatement
)
127 isMgmtStatement
= true;
128 sysdb
->releasePrepareStmtMutex();
129 logFine(Conf::logger
,"PREPARE: %s %x", stmtstr
, stmt
);
132 stmt
= StatementFactory::getStatement(parsedData
);
133 stmt
->setDbMgr(dbMgr
);
134 if( parsedData
->getStmtType() == UserStatement
)
136 UserManager
* userMgr
= sqlCon
->getConnObject().getUserManager();
137 UserTblStatement
*ustmt
= (UserTblStatement
*)stmt
;
138 ustmt
->setUserManager(userMgr
,sqlCon
->getConnObject().getUserName());
140 rv
= stmt
->resolve();
146 sysdb
->releasePrepareStmtMutex();
150 if (Conf::config
.getStmtCacheSize()) {
151 if (stmt
->noOfParamFields() > 0) {
153 sqlCon
->addToCache(this, stmtstr
);
154 }else if (Conf::config
.useCacheNoParam())
156 if (parsedData
->getCacheWorthy())
159 sqlCon
->addToCache(this, stmtstr
);
164 sysdb
->releasePrepareStmtMutex();
168 char* SqlStatement::getTableName()
170 return pData
.getTableName();
173 bool SqlStatement::isSelect()
175 if ((pData
.getStmtType() == SelectStatement
) || (pData
.getStmtType() == MetaStatement
)) return true;
179 bool SqlStatement::isPrepared() { return isPrepd
; }
181 DbRetVal
SqlStatement::execute(int &rowsAffected
)
184 if (! sqlCon
->isConnectionOpen()) {
185 printError(ErrNotOpen
, "Connection not open");
188 if (! isPrepared()) {
189 printError(ErrNotPrepared
, "Statement Not Prepared");
190 return ErrNotPrepared
;
192 if( isMgmtStatement
)
195 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
198 rv
= stmt
->execute(rowsAffected
);
199 if (rv
== ErrAlready
&& pData
.getStmtType() == SelectStatement
)
200 { //if previous scan is not closed, close it
201 SelStatement
*selStmt
= (SelStatement
*) stmt
;
203 rv
= stmt
->execute(rowsAffected
);
205 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
209 void* SqlStatement::fetch()
211 if (! sqlCon
->isConnectionOpen()) {
212 printError(ErrNotOpen
, "Connection not open");
215 if (! isPrepared()) {
216 printError(ErrNotPrepared
, "Statement Not Prepared");
219 if (pData
.getStmtType() == SelectStatement
) {
220 SelStatement
*selStmt
= (SelStatement
*) stmt
;
221 return selStmt
->fetch();
223 else if(pData
.getStmtType() == MetaStatement
){
224 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
225 return metaStmt
->fetch();
230 void* SqlStatement::fetch(DbRetVal
&rv
)
232 if (! sqlCon
->isConnectionOpen()) {
233 printError(ErrNotOpen
, "Connection not open");
236 if (! isPrepared()) {
237 printError(ErrNotPrepared
, "Statement Not Prepared");
240 if (pData
.getStmtType() == SelectStatement
) {
241 SelStatement
*selStmt
= (SelStatement
*) stmt
;
242 return selStmt
->fetch(rv
);
244 else if(pData
.getStmtType() == MetaStatement
){
245 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
246 return metaStmt
->fetch(rv
);
251 void* SqlStatement::fetchAndPrint(bool SQL
)
253 if (! sqlCon
->isConnectionOpen()) {
254 printError(ErrNotOpen
, "Connection not open");
257 if (! isPrepared()) {
258 printError(ErrNotPrepared
, "Statement Not Prepared");
261 if (pData
.getStmtType() != SelectStatement
) return NULL
;
262 SelStatement
*selStmt
= (SelStatement
*) stmt
;
263 return selStmt
->fetchAndPrint(SQL
);
266 DbRetVal
SqlStatement::bindParam(int pos
, void* value
)
269 rv
= stmt
->setParam(pos
, value
);
273 DbRetVal
SqlStatement::bindField(int pos
, void* value
)
276 if (pData
.getStmtType() == SelectStatement
) {
277 SelStatement
*selStmt
= (SelStatement
*) stmt
;
278 return selStmt
->setBindField(pos
, value
);
280 else if(pData
.getStmtType() == MetaStatement
){
281 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
282 return metaStmt
->setBindField(pos
, value
);
284 else { return ErrBadCall
;}
286 void* SqlStatement::next()
288 if (pData
.getStmtType() == SelectStatement
) {
289 SelStatement
*selStmt
= (SelStatement
*) stmt
;
290 return( (void*) selStmt
->next() );
292 else if(pData
.getStmtType() == MetaStatement
){
293 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
294 return( (void*) metaStmt
->next() );
299 bool SqlStatement::isFldNull(int pos
)
301 if (pData
.getStmtType() != SelectStatement
) return 0;
302 SelStatement
*selStmt
= (SelStatement
*) stmt
;
303 return (selStmt
->isFldNull(pos
));
305 bool SqlStatement::isFldNull(char *name
)
307 if (pData
.getStmtType() != SelectStatement
) return 0;
308 SelStatement
*selStmt
= (SelStatement
*) stmt
;
309 return (selStmt
->isFldNull(name
));
311 DbRetVal
SqlStatement::close()
313 if (pData
.getStmtType() == SelectStatement
) {
314 SelStatement
*selStmt
= (SelStatement
*) stmt
;
315 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
316 return selStmt
->close();
318 else if(pData
.getStmtType() == MetaStatement
){
319 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
320 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
321 return selStmt
->close();
326 void* SqlStatement::getParamValuePtr( int pos
)
328 //if (pData.getStmtType() != SelectStatement) return 0;
329 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
330 return( (void*) dmlStmt
->getParamValuePtr( pos
) );
333 char* SqlStatement::getFieldName( int pos
)
335 if (pData
.getStmtType() == SelectStatement
) {
336 SelStatement
*selStmt
= (SelStatement
*) stmt
;
337 return( (char*) selStmt
->getFieldName( pos
) );
339 else if(pData
.getStmtType() == MetaStatement
){
340 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
341 return( (char*) selStmt
->getFieldName( pos
) );
346 DataType
SqlStatement::getFieldType( int pos
)
348 if (pData
.getStmtType() == SelectStatement
) {
349 SelStatement
*selStmt
= (SelStatement
*) stmt
;
350 return( (DataType
) selStmt
->getFieldType( pos
) );
352 else if(pData
.getStmtType() == MetaStatement
){
353 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
354 return( (DataType
) selStmt
->getFieldType( pos
) );
356 else { return typeUnknown
;}
358 int SqlStatement::getFieldLength( int pos
)
360 if (pData
.getStmtType() == SelectStatement
) {
361 SelStatement
*selStmt
= (SelStatement
*) stmt
;
362 return( (int) selStmt
->getFieldLength( pos
) );
364 else if(pData
.getStmtType() == MetaStatement
){
365 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
366 return( (int) selStmt
->getFieldLength( pos
) );
371 void* SqlStatement::getFieldValuePtr( int pos
)
373 if (pData
.getStmtType() == SelectStatement
) {
374 SelStatement
*selStmt
= (SelStatement
*) stmt
;
375 return( (void*) selStmt
->getFieldValuePtr( pos
) );
377 else if(pData
.getStmtType() == MetaStatement
){
378 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
379 return( (void*) selStmt
->getFieldValuePtr( pos
) );
383 void* SqlStatement::getFieldValuePtr( char *name
)
385 if (pData
.getStmtType() == SelectStatement
) {
386 SelStatement
*selStmt
= (SelStatement
*) stmt
;
387 return( (void*) selStmt
->getFieldValuePtr( name
) );
389 else if(pData
.getStmtType() == MetaStatement
){
390 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
391 return( (void*) selStmt
->getFieldValuePtr( name
) );
396 int SqlStatement::noOfProjFields()
398 if (pData
.getStmtType() == SelectStatement
) {
399 SelStatement
*selStmt
= (SelStatement
*) stmt
;
400 return selStmt
->noOfProjFields();
402 else if(pData
.getStmtType() == MetaStatement
){
403 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
404 return selStmt
->noOfProjFields();
409 void SqlStatement::getProjFieldType(int *data
)
411 if (pData
.getStmtType() == SelectStatement
) {
412 SelStatement
*selStmt
= (SelStatement
*) stmt
;
413 return( selStmt
->getProjFieldType(data
) );
415 else if(pData
.getStmtType() == MetaStatement
){
416 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
417 return( selStmt
->getProjFieldType(data
) );
423 int SqlStatement::noOfParamFields()
425 return stmt
->noOfParamFields();
428 DbRetVal
SqlStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
431 if (pData
.getStmtType() == SelectStatement
) {
432 SelStatement
*selStmt
= (SelStatement
*) stmt
;
433 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
435 else if(pData
.getStmtType() == MetaStatement
){
436 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
437 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
438 } else { return ErrBadCall
;}
442 DbRetVal
SqlStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
445 if (pData
.getStmtType() ==SelectStatement
||
446 pData
.getStmtType() ==InsertStatement
||
447 pData
.getStmtType() ==UpdateStatement
||
448 pData
.getStmtType() ==DeleteStatement
)
451 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
452 rv
= dmlStmt
->getParamFldInfo(parampos
, fInfo
);
457 DbRetVal
SqlStatement::free()
459 logFinest(Conf::logger
,"FREE: %x", stmt
);
466 if(stmt
) delete stmt
;
469 isMgmtStatement
= false;
474 void SqlStatement::setNull(int pos
)
478 void SqlStatement::setShortParam(int paramPos
, short value
)
480 stmt
->setShortParam(paramPos
, value
);
482 void SqlStatement::setIntParam(int paramPos
, int value
)
484 stmt
->setIntParam(paramPos
, value
);
486 void SqlStatement::setLongParam(int paramPos
, long value
)
488 stmt
->setLongParam(paramPos
, value
);
490 void SqlStatement::setLongLongParam(int paramPos
, long long value
)
492 stmt
->setLongLongParam(paramPos
, value
);
494 void SqlStatement::setByteIntParam(int paramPos
, ByteInt value
)
496 stmt
->setByteIntParam(paramPos
, value
);
498 void SqlStatement::setFloatParam(int paramPos
, float value
)
500 stmt
->setFloatParam(paramPos
, value
);
502 void SqlStatement::setDoubleParam(int paramPos
, double value
)
504 stmt
->setDoubleParam(paramPos
, value
);
506 void SqlStatement::setStringParam(int paramPos
, char *value
)
508 stmt
->setStringParam(paramPos
, value
);
510 void SqlStatement::setDateParam(int paramPos
, Date value
)
512 stmt
->setDateParam(paramPos
, value
);
514 void SqlStatement::setTimeParam(int paramPos
, Time value
)
516 stmt
->setTimeParam(paramPos
, value
);
518 void SqlStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
520 stmt
->setTimeStampParam(paramPos
, value
);
522 void SqlStatement::setBinaryParam(int paramPos
, void *value
, int length
)
524 stmt
->setBinaryParam(paramPos
, value
, length
);
526 int SqlStatement::getFldPos(char *name
)
528 return stmt
->getFldPos(name
);
530 List
SqlStatement::getAllTableNames(DbRetVal
&ret
)
532 DatabaseManager
*dbMgr
= NULL
;
534 dbMgr
=sqlCon
->getConnObject().getDatabaseManager();
537 tbNmList
= dbMgr
->getAllTableNames(&rv
);
542 List
SqlStatement::getAllUserNames(DbRetVal
&ret
)
544 UserManager
*urMgr
= NULL
;
546 urMgr
=sqlCon
->getConnObject().getUserManager();
549 urNmList
= urMgr
->getAllUserNames(&rv
);
553 List
SqlStatement::getFieldNameList(const char *tblName
)
555 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
556 Table
*table
= dbMgr
->openTable(tblName
);
559 printError(ErrLockTimeOut
, "Unable to open table %s", tblName
);
562 List fldNameList
= table
->getFieldNameList();
563 dbMgr
->closeTable(table
);
566 DbRetVal
SqlStatement::getFieldInfo(const char *tblName
, const char *fldName
, FieldInfo
*&info
)
568 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
569 Table
*table
= dbMgr
->openTable(tblName
);
571 printError(ErrLockTimeOut
, "Unable to open table %s", tblName
);
572 return ErrLockTimeOut
;
574 DbRetVal rv
= table
->getFieldInfo(fldName
, info
);
575 dbMgr
->closeTable(table
);
578 void SqlStatement::setLoading(bool flag
)
580 if (pData
.getStmtType() == InsertStatement
||
581 pData
.getStmtType() == UpdateStatement
||
582 pData
.getStmtType() == DeleteStatement
)
584 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
585 dmlStmt
->setLoading(flag
);
590 int SqlStatement::getNoOfPagesForTable(char *tblName
)
592 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
593 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
594 return dbMgrImpl
->getNoOfPagesForTable(tblName
);
597 DbRetVal
SqlStatement::loadRecords(char *tblName
, void *buf
)
599 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
600 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
601 return dbMgrImpl
->loadRecords(tblName
, (char *) buf
);
604 DbRetVal
SqlStatement::pasteRecords(char *tblName
, void *buffer
)
606 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
607 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
608 return dbMgrImpl
->pasteRecords(tblName
, buffer
);
610 void SqlStatement::flushCacheStmt()
612 return sqlCon
->flushCacheStmt();
614 //-------------------------------------------------------------------
615 void SqlConnection::flushCacheStmt()
617 ListIterator iter
= cachedStmts
.getIterator();
618 while (iter
.hasElement()) {
619 CachedStmtNode
* node
= (CachedStmtNode
*) iter
.nextElement();
620 free(node
->sqlString
);
621 node
->sqlStmt
->setCachedStmt(false);
622 node
->sqlStmt
->free();
623 delete node
->sqlStmt
;
630 SqlStatement
* SqlConnection::findInCache(char *stmtstr
)
632 ListIterator iter
= cachedStmts
.getIterator();
633 int inputStmtLen
= strlen(stmtstr
);
634 CachedStmtNode
*node
= NULL
;
635 while ((node
= (CachedStmtNode
*)iter
.nextElement()) != NULL
)
637 if (node
->stmtLength
== inputStmtLen
)
639 if (0 == strcmp(node
->sqlString
, stmtstr
))
641 logFiner(Conf::logger
, "Statement Retrieved From Cache %x\n",
644 return node
->sqlStmt
;
650 void SqlConnection::addToCache(SqlStatement
*sqlStmt
, char* stmtString
)
652 SqlStatement
*stmt
= new SqlStatement();
654 CachedStmtNode
*node
= new CachedStmtNode();
655 node
->sqlStmt
= stmt
;
656 node
->stmtLength
= strlen(stmtString
);
657 node
->sqlString
= (char*)malloc(node
->stmtLength
+1);
658 strcpy(node
->sqlString
, stmtString
);
659 if (cachedStmts
.size() >= Conf::config
.getStmtCacheSize())
663 cachedStmts
.append(node
);
664 logFiner(Conf::logger
, "Statement added To Cache %x\n", node
->sqlStmt
);
665 logFinest(Conf::logger
, "Statement added To Cache %s\n", node
->sqlString
);
668 void SqlConnection::removeLeastUsed()
670 ListIterator iter
= cachedStmts
.getIterator();
671 CachedStmtNode
*node
= NULL
, *toRemove
=NULL
;
673 bool firstCall
= true;
674 while((node
= (CachedStmtNode
*) iter
.nextElement()) != NULL
)
678 lowHits
= node
->hits
;
679 toRemove
= node
; //if cache size is 1
682 if (lowHits
>= node
->hits
) toRemove
= node
;
684 cachedStmts
.remove(toRemove
);
685 logFiner(Conf::logger
, "Statement removed from Cache %x\n", toRemove
->sqlStmt
);
686 logFinest(Conf::logger
, "Statement removed from Cache %s\n", toRemove
->sqlString
);
689 SqlConnection::~SqlConnection()
693 if (isConnOpen
) disconnect();
695 static void sigUsr1Handler(int sig
)
697 ListIterator iter
= SqlConnection::connList
.getIterator();
698 SqlConnection
*conn
= NULL
;
699 while (iter
.hasElement())
701 conn
= (SqlConnection
*) iter
.nextElement();
702 conn
->flushCacheStmt();
704 os::signal(SIGCSQL1
, sigUsr1Handler
);
707 void SqlConnection::initialize()
709 os::signal(SIGCSQL1
, sigUsr1Handler
);