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
;
27 bool SqlConnection::isInit
= false;
28 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
);
119 sysdb
->releasePrepareStmtMutex();
120 return ErrSyntaxError
;
122 if( parsedData
->getStmtType() == MgmtStatement
)
126 isMgmtStatement
= true;
127 sysdb
->releasePrepareStmtMutex();
128 logFine(Conf::logger
,"PREPARE: %s %x", stmtstr
, stmt
);
131 stmt
= StatementFactory::getStatement(parsedData
);
132 stmt
->setDbMgr(dbMgr
);
133 if( parsedData
->getStmtType() == UserStatement
)
135 UserManager
* userMgr
= sqlCon
->getConnObject().getUserManager();
136 UserTblStatement
*ustmt
= (UserTblStatement
*)stmt
;
137 ustmt
->setUserManager(userMgr
,sqlCon
->getConnObject().getUserName());
139 rv
= stmt
->resolve();
144 sysdb
->releasePrepareStmtMutex();
148 if (Conf::config
.getStmtCacheSize()) {
149 if (stmt
->noOfParamFields() > 0) {
151 sqlCon
->addToCache(this, stmtstr
);
153 else if (Conf::config
.useCacheNoParam())
155 if (parsedData
->getCacheWorthy())
158 sqlCon
->addToCache(this, stmtstr
);
163 sysdb
->releasePrepareStmtMutex();
167 char* SqlStatement::getTableName()
169 return pData
.getTableName();
172 bool SqlStatement::isSelect()
174 if ((pData
.getStmtType() == SelectStatement
) || (pData
.getStmtType() == MetaStatement
)) return true;
178 bool SqlStatement::isPrepared() { return isPrepd
; }
180 DbRetVal
SqlStatement::execute(int &rowsAffected
)
183 if (! sqlCon
->isConnectionOpen()) {
184 printError(ErrNotOpen
, "Connection not open");
187 if (! isPrepared()) {
188 printError(ErrNotPrepared
, "Statement Not Prepared");
189 return ErrNotPrepared
;
191 if( isMgmtStatement
)
194 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
197 rv
= stmt
->execute(rowsAffected
);
198 if (rv
== ErrAlready
&& pData
.getStmtType() == SelectStatement
)
199 { //if previous scan is not closed, close it
200 SelStatement
*selStmt
= (SelStatement
*) stmt
;
202 rv
= stmt
->execute(rowsAffected
);
204 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
208 void* SqlStatement::fetch()
210 if (! sqlCon
->isConnectionOpen()) {
211 printError(ErrNotOpen
, "Connection not open");
214 if (! isPrepared()) {
215 printError(ErrNotPrepared
, "Statement Not Prepared");
218 if (pData
.getStmtType() == SelectStatement
) {
219 SelStatement
*selStmt
= (SelStatement
*) stmt
;
220 return selStmt
->fetch();
222 else if(pData
.getStmtType() == MetaStatement
){
223 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
224 return metaStmt
->fetch();
229 void* SqlStatement::fetch(DbRetVal
&rv
)
231 if (! sqlCon
->isConnectionOpen()) {
232 printError(ErrNotOpen
, "Connection not open");
235 if (! isPrepared()) {
236 printError(ErrNotPrepared
, "Statement Not Prepared");
239 if (pData
.getStmtType() == SelectStatement
) {
240 SelStatement
*selStmt
= (SelStatement
*) stmt
;
241 return selStmt
->fetch(rv
);
243 else if(pData
.getStmtType() == MetaStatement
){
244 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
245 return metaStmt
->fetch(rv
);
250 void* SqlStatement::fetchAndPrint(bool SQL
)
252 if (! sqlCon
->isConnectionOpen()) {
253 printError(ErrNotOpen
, "Connection not open");
256 if (! isPrepared()) {
257 printError(ErrNotPrepared
, "Statement Not Prepared");
260 if (pData
.getStmtType() != SelectStatement
) return NULL
;
261 SelStatement
*selStmt
= (SelStatement
*) stmt
;
262 return selStmt
->fetchAndPrint(SQL
);
265 DbRetVal
SqlStatement::bindParam(int pos
, void* value
)
268 rv
= stmt
->setParam(pos
, value
);
272 DbRetVal
SqlStatement::bindField(int pos
, void* value
)
275 if (pData
.getStmtType() == SelectStatement
) {
276 SelStatement
*selStmt
= (SelStatement
*) stmt
;
277 return selStmt
->setBindField(pos
, value
);
279 else if(pData
.getStmtType() == MetaStatement
){
280 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
281 return metaStmt
->setBindField(pos
, value
);
283 else { return ErrBadCall
;}
285 void* SqlStatement::next()
287 if (pData
.getStmtType() == SelectStatement
) {
288 SelStatement
*selStmt
= (SelStatement
*) stmt
;
289 return( (void*) selStmt
->next() );
291 else if(pData
.getStmtType() == MetaStatement
){
292 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
293 return( (void*) metaStmt
->next() );
298 bool SqlStatement::isFldNull(int pos
)
300 if (pData
.getStmtType() != SelectStatement
) return 0;
301 SelStatement
*selStmt
= (SelStatement
*) stmt
;
302 return (selStmt
->isFldNull(pos
));
304 bool SqlStatement::isFldNull(char *name
)
306 if (pData
.getStmtType() != SelectStatement
) return 0;
307 SelStatement
*selStmt
= (SelStatement
*) stmt
;
308 return (selStmt
->isFldNull(name
));
310 DbRetVal
SqlStatement::close()
312 if (pData
.getStmtType() == SelectStatement
) {
313 SelStatement
*selStmt
= (SelStatement
*) stmt
;
314 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
315 return selStmt
->close();
317 else if(pData
.getStmtType() == MetaStatement
){
318 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
319 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
320 return selStmt
->close();
325 void* SqlStatement::getParamValuePtr( int pos
)
327 //if (pData.getStmtType() != SelectStatement) return 0;
328 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
329 return( (void*) dmlStmt
->getParamValuePtr( pos
) );
332 char* SqlStatement::getFieldName( int pos
)
334 if (pData
.getStmtType() == SelectStatement
) {
335 SelStatement
*selStmt
= (SelStatement
*) stmt
;
336 return( (char*) selStmt
->getFieldName( pos
) );
338 else if(pData
.getStmtType() == MetaStatement
){
339 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
340 return( (char*) selStmt
->getFieldName( pos
) );
345 DataType
SqlStatement::getFieldType( int pos
)
347 if (pData
.getStmtType() == SelectStatement
) {
348 SelStatement
*selStmt
= (SelStatement
*) stmt
;
349 return( (DataType
) selStmt
->getFieldType( pos
) );
351 else if(pData
.getStmtType() == MetaStatement
){
352 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
353 return( (DataType
) selStmt
->getFieldType( pos
) );
355 else { return typeUnknown
;}
357 int SqlStatement::getFieldLength( int pos
)
359 if (pData
.getStmtType() == SelectStatement
) {
360 SelStatement
*selStmt
= (SelStatement
*) stmt
;
361 return( (int) selStmt
->getFieldLength( pos
) );
363 else if(pData
.getStmtType() == MetaStatement
){
364 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
365 return( (int) selStmt
->getFieldLength( pos
) );
370 void* SqlStatement::getFieldValuePtr( int pos
)
372 if (pData
.getStmtType() == SelectStatement
) {
373 SelStatement
*selStmt
= (SelStatement
*) stmt
;
374 return( (void*) selStmt
->getFieldValuePtr( pos
) );
376 else if(pData
.getStmtType() == MetaStatement
){
377 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
378 return( (void*) selStmt
->getFieldValuePtr( pos
) );
382 void* SqlStatement::getFieldValuePtr( char *name
)
384 if (pData
.getStmtType() == SelectStatement
) {
385 SelStatement
*selStmt
= (SelStatement
*) stmt
;
386 return( (void*) selStmt
->getFieldValuePtr( name
) );
388 else if(pData
.getStmtType() == MetaStatement
){
389 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
390 return( (void*) selStmt
->getFieldValuePtr( name
) );
395 int SqlStatement::noOfProjFields()
397 if (pData
.getStmtType() == SelectStatement
) {
398 SelStatement
*selStmt
= (SelStatement
*) stmt
;
399 return selStmt
->noOfProjFields();
401 else if(pData
.getStmtType() == MetaStatement
){
402 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
403 return selStmt
->noOfProjFields();
408 void SqlStatement::getProjFieldType(int *data
)
410 if (pData
.getStmtType() == SelectStatement
) {
411 SelStatement
*selStmt
= (SelStatement
*) stmt
;
412 return( selStmt
->getProjFieldType(data
) );
414 else if(pData
.getStmtType() == MetaStatement
){
415 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
416 return( selStmt
->getProjFieldType(data
) );
422 int SqlStatement::noOfParamFields()
424 return stmt
->noOfParamFields();
427 DbRetVal
SqlStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
430 if (pData
.getStmtType() == SelectStatement
) {
431 SelStatement
*selStmt
= (SelStatement
*) stmt
;
432 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
434 else if(pData
.getStmtType() == MetaStatement
){
435 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
436 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
437 } else { return ErrBadCall
;}
441 DbRetVal
SqlStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
444 if (pData
.getStmtType() ==SelectStatement
||
445 pData
.getStmtType() ==InsertStatement
||
446 pData
.getStmtType() ==UpdateStatement
||
447 pData
.getStmtType() ==DeleteStatement
)
450 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
451 rv
= dmlStmt
->getParamFldInfo(parampos
, fInfo
);
456 DbRetVal
SqlStatement::free()
458 logFinest(Conf::logger
,"FREE: %x", stmt
);
465 if(stmt
) delete stmt
;
468 isMgmtStatement
= false;
473 void SqlStatement::setNull(int pos
)
477 void SqlStatement::setShortParam(int paramPos
, short value
)
479 stmt
->setShortParam(paramPos
, value
);
481 void SqlStatement::setIntParam(int paramPos
, int value
)
483 stmt
->setIntParam(paramPos
, value
);
485 void SqlStatement::setLongParam(int paramPos
, long value
)
487 stmt
->setLongParam(paramPos
, value
);
489 void SqlStatement::setLongLongParam(int paramPos
, long long value
)
491 stmt
->setLongLongParam(paramPos
, value
);
493 void SqlStatement::setByteIntParam(int paramPos
, ByteInt value
)
495 stmt
->setByteIntParam(paramPos
, value
);
497 void SqlStatement::setFloatParam(int paramPos
, float value
)
499 stmt
->setFloatParam(paramPos
, value
);
501 void SqlStatement::setDoubleParam(int paramPos
, double value
)
503 stmt
->setDoubleParam(paramPos
, value
);
505 void SqlStatement::setStringParam(int paramPos
, char *value
)
507 stmt
->setStringParam(paramPos
, value
);
509 void SqlStatement::setDateParam(int paramPos
, Date value
)
511 stmt
->setDateParam(paramPos
, value
);
513 void SqlStatement::setTimeParam(int paramPos
, Time value
)
515 stmt
->setTimeParam(paramPos
, value
);
517 void SqlStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
519 stmt
->setTimeStampParam(paramPos
, value
);
521 void SqlStatement::setBinaryParam(int paramPos
, void *value
, int length
)
523 stmt
->setBinaryParam(paramPos
, value
, length
);
525 int SqlStatement::getFldPos(char *name
)
527 return stmt
->getFldPos(name
);
529 List
SqlStatement::getAllTableNames(DbRetVal
&ret
)
531 DatabaseManager
*dbMgr
= NULL
;
533 dbMgr
=sqlCon
->getConnObject().getDatabaseManager();
536 tbNmList
= dbMgr
->getAllTableNames(&rv
);
541 List
SqlStatement::getAllUserNames(DbRetVal
&ret
)
543 UserManager
*urMgr
= NULL
;
545 urMgr
=sqlCon
->getConnObject().getUserManager();
548 urNmList
= urMgr
->getAllUserNames(&rv
);
552 List
SqlStatement::getFieldNameList(const char *tblName
)
554 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
555 Table
*table
= dbMgr
->openTable(tblName
);
556 List fldNameList
= table
->getFieldNameList();
557 dbMgr
->closeTable(table
);
560 DbRetVal
SqlStatement::getFieldInfo(const char *tblName
, const char *fldName
, FieldInfo
*&info
)
562 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
563 Table
*table
= dbMgr
->openTable(tblName
);
564 DbRetVal rv
= table
->getFieldInfo(fldName
, info
);
565 dbMgr
->closeTable(table
);
568 void SqlStatement::setLoading(bool flag
)
570 if (pData
.getStmtType() == InsertStatement
||
571 pData
.getStmtType() == UpdateStatement
||
572 pData
.getStmtType() == DeleteStatement
)
574 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
575 dmlStmt
->setLoading(flag
);
580 int SqlStatement::getNoOfPagesForTable(char *tblName
)
582 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
583 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
584 return dbMgrImpl
->getNoOfPagesForTable(tblName
);
587 DbRetVal
SqlStatement::loadRecords(char *tblName
, void *buf
)
589 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
590 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
591 return dbMgrImpl
->loadRecords(tblName
, (char *) buf
);
594 DbRetVal
SqlStatement::pasteRecords(char *tblName
, void *buffer
)
596 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
597 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
598 return dbMgrImpl
->pasteRecords(tblName
, buffer
);
600 void SqlStatement::flushCacheStmt()
602 return sqlCon
->flushCacheStmt();
604 //-------------------------------------------------------------------
605 void SqlConnection::flushCacheStmt()
607 ListIterator iter
= cachedStmts
.getIterator();
608 while (iter
.hasElement()) {
609 CachedStmtNode
* node
= (CachedStmtNode
*) iter
.nextElement();
610 free(node
->sqlString
);
611 node
->sqlStmt
->setCachedStmt(false);
612 node
->sqlStmt
->free();
613 delete node
->sqlStmt
;
620 SqlStatement
* SqlConnection::findInCache(char *stmtstr
)
622 ListIterator iter
= cachedStmts
.getIterator();
623 int inputStmtLen
= strlen(stmtstr
);
624 CachedStmtNode
*node
= NULL
;
625 while ((node
= (CachedStmtNode
*)iter
.nextElement()) != NULL
)
627 if (node
->stmtLength
== inputStmtLen
)
629 if (0 == strcmp(node
->sqlString
, stmtstr
))
631 logFiner(Conf::logger
, "Statement Retrieved From Cache %x\n",
634 return node
->sqlStmt
;
640 void SqlConnection::addToCache(SqlStatement
*sqlStmt
, char* stmtString
)
642 SqlStatement
*stmt
= new SqlStatement();
644 CachedStmtNode
*node
= new CachedStmtNode();
645 node
->sqlStmt
= stmt
;
646 node
->stmtLength
= strlen(stmtString
);
647 node
->sqlString
= (char*)malloc(node
->stmtLength
+1);
648 strcpy(node
->sqlString
, stmtString
);
649 if (cachedStmts
.size() >= Conf::config
.getStmtCacheSize())
653 cachedStmts
.append(node
);
654 logFiner(Conf::logger
, "Statement added To Cache %x\n", node
->sqlStmt
);
655 logFinest(Conf::logger
, "Statement added To Cache %s\n", node
->sqlString
);
658 void SqlConnection::removeLeastUsed()
660 ListIterator iter
= cachedStmts
.getIterator();
661 CachedStmtNode
*node
= NULL
, *toRemove
=NULL
;
663 bool firstCall
= true;
664 while((node
= (CachedStmtNode
*) iter
.nextElement()) != NULL
)
668 lowHits
= node
->hits
;
669 toRemove
= node
; //if cache size is 1
672 if (lowHits
>= node
->hits
) toRemove
= node
;
674 cachedStmts
.remove(toRemove
);
675 logFiner(Conf::logger
, "Statement removed from Cache %x\n", toRemove
->sqlStmt
);
676 logFinest(Conf::logger
, "Statement removed from Cache %s\n", toRemove
->sqlString
);
679 SqlConnection::~SqlConnection()
683 if (isConnOpen
) disconnect();
685 static void sigUsr1Handler(int sig
)
687 ListIterator iter
= SqlConnection::connList
.getIterator();
688 SqlConnection
*conn
= NULL
;
689 while (iter
.hasElement())
691 conn
= (SqlConnection
*) iter
.nextElement();
692 conn
->flushCacheStmt();
696 void SqlConnection::initialize()
698 os::signal(SIGCSQL1
, sigUsr1Handler
);