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
;
30 SqlStatement::~SqlStatement()
32 if (isPrepd
) { free(); isPrepd
= false; }
35 List
SqlStatement::getTableNameList()
37 return pData
.getTableNameList();
39 SqlStatement::SqlStatement()
46 isMgmtStatement
= false;
48 void SqlStatement::setConnection(AbsSqlConnection
*conn
)
50 sqlCon
= (SqlConnection
*)conn
;
54 void SqlStatement::setSqlConnection(SqlConnection
*conn
)
59 DbRetVal
SqlStatement::executeDirect(char *str
)
64 if (rv
!= OK
) return rv
;
66 if (rv
!= OK
) return rv
;
70 DbRetVal
SqlStatement::prepare(char *stmtstr
)
73 if (! sqlCon
->isConnectionOpen()) {
74 printError(ErrNotOpen
, "Connection not open");
77 SqlStatement
*cachedStmt
= sqlCon
->findInCache(stmtstr
);
81 this->stmt
->setParsedData(&this->pData
);
82 logFine(Conf::logger
,"GOT STMT FROM CACHE: %s %x", stmtstr
, cachedStmt
);
86 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
87 Database
*sysdb
= ((DatabaseManagerImpl
*)dbMgr
)->sysDb();
88 int tries
= Conf::config
.getMutexRetries();
89 struct timeval timeout
;
90 timeout
.tv_sec
= Conf::config
.getMutexSecs();
91 timeout
.tv_usec
= Conf::config
.getMutexUSecs();
94 rv
= sysdb
->getPrepareStmtMutex();
99 "Unable to get prepare statement mutex after %d tries", Conf::config
.getMutexRetries());
102 os::select(0, 0, 0, 0, &timeout
);
105 if (isPrepared()) free();
109 yy_buffer_state
*yy_buffer
= yy_scan_string(stmtstr
);
111 if (yy_buffer
) yy_delete_buffer(yy_buffer
);
117 sysdb
->releasePrepareStmtMutex();
118 return ErrSyntaxError
;
120 if( parsedData
->getStmtType() == MgmtStatement
)
124 isMgmtStatement
= true;
125 sysdb
->releasePrepareStmtMutex();
126 logFine(Conf::logger
,"PREPARE: %s %x", stmtstr
, stmt
);
129 stmt
= StatementFactory::getStatement(parsedData
);
130 stmt
->setDbMgr(dbMgr
);
131 if( parsedData
->getStmtType() == UserStatement
)
133 UserManager
* userMgr
= sqlCon
->getConnObject().getUserManager();
134 UserTblStatement
*ustmt
= (UserTblStatement
*)stmt
;
135 ustmt
->setUserManager(userMgr
,sqlCon
->getConnObject().getUserName());
137 rv
= stmt
->resolve();
143 sysdb
->releasePrepareStmtMutex();
148 sysdb
->releasePrepareStmtMutex();
150 if (Conf::config
.getStmtCacheSize()) {
151 if (stmt
->noOfParamFields() > 0) {
153 sqlCon
->addToCache(this, stmtstr
);
156 if (Conf::config
.useCacheNoParam())
158 if (parsedData
->getCacheWorthy())
161 sqlCon
->addToCache(this, stmtstr
);
169 char* SqlStatement::getTableName()
171 return pData
.getTableName();
174 bool SqlStatement::isSelect()
176 if ((pData
.getStmtType() == SelectStatement
) || (pData
.getStmtType() == MetaStatement
)) return true;
180 bool SqlStatement::isPrepared() { return isPrepd
; }
182 DbRetVal
SqlStatement::execute(int &rowsAffected
)
185 if (! sqlCon
->isConnectionOpen()) {
186 printError(ErrNotOpen
, "Connection not open");
189 if (! isPrepared()) {
190 printError(ErrNotPrepared
, "Statement Not Prepared");
191 return ErrNotPrepared
;
193 if( isMgmtStatement
)
196 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
199 rv
= stmt
->execute(rowsAffected
);
200 if (rv
== ErrAlready
&& pData
.getStmtType() == SelectStatement
)
201 { //if previous scan is not closed, close it
202 SelStatement
*selStmt
= (SelStatement
*) stmt
;
204 rv
= stmt
->execute(rowsAffected
);
206 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
210 void* SqlStatement::fetch()
212 if (! sqlCon
->isConnectionOpen()) {
213 printError(ErrNotOpen
, "Connection not open");
216 if (! isPrepared()) {
217 printError(ErrNotPrepared
, "Statement Not Prepared");
220 if (pData
.getStmtType() == SelectStatement
) {
221 SelStatement
*selStmt
= (SelStatement
*) stmt
;
222 return selStmt
->fetch();
224 else if(pData
.getStmtType() == MetaStatement
){
225 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
226 return metaStmt
->fetch();
231 void* SqlStatement::fetch(DbRetVal
&rv
)
233 if (! sqlCon
->isConnectionOpen()) {
234 printError(ErrNotOpen
, "Connection not open");
237 if (! isPrepared()) {
238 printError(ErrNotPrepared
, "Statement Not Prepared");
241 if (pData
.getStmtType() == SelectStatement
) {
242 SelStatement
*selStmt
= (SelStatement
*) stmt
;
243 return selStmt
->fetch(rv
);
245 else if(pData
.getStmtType() == MetaStatement
){
246 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
247 return metaStmt
->fetch(rv
);
252 void* SqlStatement::fetchAndPrint(bool SQL
)
254 if (! sqlCon
->isConnectionOpen()) {
255 printError(ErrNotOpen
, "Connection not open");
258 if (! isPrepared()) {
259 printError(ErrNotPrepared
, "Statement Not Prepared");
262 if (pData
.getStmtType() != SelectStatement
) return NULL
;
263 SelStatement
*selStmt
= (SelStatement
*) stmt
;
264 return selStmt
->fetchAndPrint(SQL
);
267 DbRetVal
SqlStatement::bindParam(int pos
, void* value
)
270 rv
= stmt
->setParam(pos
, value
);
274 DbRetVal
SqlStatement::bindField(int pos
, void* value
)
277 if (pData
.getStmtType() == SelectStatement
) {
278 SelStatement
*selStmt
= (SelStatement
*) stmt
;
279 return selStmt
->setBindField(pos
, value
);
281 else if(pData
.getStmtType() == MetaStatement
){
282 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
283 return metaStmt
->setBindField(pos
, value
);
285 else { return ErrBadCall
;}
287 void* SqlStatement::next()
289 if (pData
.getStmtType() == SelectStatement
) {
290 SelStatement
*selStmt
= (SelStatement
*) stmt
;
291 return( (void*) selStmt
->next() );
293 else if(pData
.getStmtType() == MetaStatement
){
294 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
295 return( (void*) metaStmt
->next() );
300 bool SqlStatement::isFldNull(int pos
)
302 if (pData
.getStmtType() != SelectStatement
) return 0;
303 SelStatement
*selStmt
= (SelStatement
*) stmt
;
304 return (selStmt
->isFldNull(pos
));
306 bool SqlStatement::isFldNull(char *name
)
308 if (pData
.getStmtType() != SelectStatement
) return 0;
309 SelStatement
*selStmt
= (SelStatement
*) stmt
;
310 return (selStmt
->isFldNull(name
));
312 DbRetVal
SqlStatement::close()
314 if (pData
.getStmtType() == SelectStatement
) {
315 SelStatement
*selStmt
= (SelStatement
*) stmt
;
316 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
317 return selStmt
->close();
319 else if(pData
.getStmtType() == MetaStatement
){
320 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
321 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
322 return selStmt
->close();
327 void* SqlStatement::getParamValuePtr( int pos
)
329 //if (pData.getStmtType() != SelectStatement) return 0;
330 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
331 return( (void*) dmlStmt
->getParamValuePtr( pos
) );
334 char* SqlStatement::getFieldName( int pos
)
336 if (pData
.getStmtType() == SelectStatement
) {
337 SelStatement
*selStmt
= (SelStatement
*) stmt
;
338 return( (char*) selStmt
->getFieldName( pos
) );
340 else if(pData
.getStmtType() == MetaStatement
){
341 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
342 return( (char*) selStmt
->getFieldName( pos
) );
347 DataType
SqlStatement::getFieldType( int pos
)
349 if (pData
.getStmtType() == SelectStatement
) {
350 SelStatement
*selStmt
= (SelStatement
*) stmt
;
351 return( (DataType
) selStmt
->getFieldType( pos
) );
353 else if(pData
.getStmtType() == MetaStatement
){
354 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
355 return( (DataType
) selStmt
->getFieldType( pos
) );
357 else { return typeUnknown
;}
359 int SqlStatement::getFieldLength( int pos
)
361 if (pData
.getStmtType() == SelectStatement
) {
362 SelStatement
*selStmt
= (SelStatement
*) stmt
;
363 return( (int) selStmt
->getFieldLength( pos
) );
365 else if(pData
.getStmtType() == MetaStatement
){
366 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
367 return( (int) selStmt
->getFieldLength( pos
) );
372 void* SqlStatement::getFieldValuePtr( int pos
)
374 if (pData
.getStmtType() == SelectStatement
) {
375 SelStatement
*selStmt
= (SelStatement
*) stmt
;
376 return( (void*) selStmt
->getFieldValuePtr( pos
) );
378 else if(pData
.getStmtType() == MetaStatement
){
379 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
380 return( (void*) selStmt
->getFieldValuePtr( pos
) );
384 void* SqlStatement::getFieldValuePtr( char *name
)
386 if (pData
.getStmtType() == SelectStatement
) {
387 SelStatement
*selStmt
= (SelStatement
*) stmt
;
388 return( (void*) selStmt
->getFieldValuePtr( name
) );
390 else if(pData
.getStmtType() == MetaStatement
){
391 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
392 return( (void*) selStmt
->getFieldValuePtr( name
) );
397 int SqlStatement::noOfProjFields()
399 if (pData
.getStmtType() == SelectStatement
) {
400 SelStatement
*selStmt
= (SelStatement
*) stmt
;
401 return selStmt
->noOfProjFields();
403 else if(pData
.getStmtType() == MetaStatement
){
404 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
405 return selStmt
->noOfProjFields();
410 void SqlStatement::getProjFieldType(int *data
)
412 if (pData
.getStmtType() == SelectStatement
) {
413 SelStatement
*selStmt
= (SelStatement
*) stmt
;
414 return( selStmt
->getProjFieldType(data
) );
416 else if(pData
.getStmtType() == MetaStatement
){
417 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
418 return( selStmt
->getProjFieldType(data
) );
424 int SqlStatement::noOfParamFields()
426 return stmt
->noOfParamFields();
429 DbRetVal
SqlStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
432 if (pData
.getStmtType() == SelectStatement
) {
433 SelStatement
*selStmt
= (SelStatement
*) stmt
;
434 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
436 else if(pData
.getStmtType() == MetaStatement
){
437 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
438 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
439 } else { return ErrBadCall
;}
443 DbRetVal
SqlStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
446 if (pData
.getStmtType() ==SelectStatement
||
447 pData
.getStmtType() ==InsertStatement
||
448 pData
.getStmtType() ==UpdateStatement
||
449 pData
.getStmtType() ==DeleteStatement
)
452 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
453 rv
= dmlStmt
->getParamFldInfo(parampos
, fInfo
);
458 DbRetVal
SqlStatement::free()
460 logFinest(Conf::logger
,"FREE: %x", stmt
);
467 if(stmt
) delete stmt
;
470 isMgmtStatement
= false;
475 void SqlStatement::setNull(int pos
)
479 void SqlStatement::setShortParam(int paramPos
, short value
)
481 stmt
->setShortParam(paramPos
, value
);
483 void SqlStatement::setIntParam(int paramPos
, int value
)
485 stmt
->setIntParam(paramPos
, value
);
487 void SqlStatement::setLongParam(int paramPos
, long value
)
489 stmt
->setLongParam(paramPos
, value
);
491 void SqlStatement::setLongLongParam(int paramPos
, long long value
)
493 stmt
->setLongLongParam(paramPos
, value
);
495 void SqlStatement::setByteIntParam(int paramPos
, ByteInt value
)
497 stmt
->setByteIntParam(paramPos
, value
);
499 void SqlStatement::setFloatParam(int paramPos
, float value
)
501 stmt
->setFloatParam(paramPos
, value
);
503 void SqlStatement::setDoubleParam(int paramPos
, double value
)
505 stmt
->setDoubleParam(paramPos
, value
);
507 void SqlStatement::setStringParam(int paramPos
, char *value
)
509 stmt
->setStringParam(paramPos
, value
);
511 void SqlStatement::setDateParam(int paramPos
, Date value
)
513 stmt
->setDateParam(paramPos
, value
);
515 void SqlStatement::setTimeParam(int paramPos
, Time value
)
517 stmt
->setTimeParam(paramPos
, value
);
519 void SqlStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
521 stmt
->setTimeStampParam(paramPos
, value
);
523 void SqlStatement::setBinaryParam(int paramPos
, void *value
, int length
)
525 stmt
->setBinaryParam(paramPos
, value
, length
);
527 int SqlStatement::getFldPos(char *name
)
529 return stmt
->getFldPos(name
);
531 List
SqlStatement::getAllTableNames(DbRetVal
&ret
)
533 DatabaseManager
*dbMgr
= NULL
;
535 dbMgr
=sqlCon
->getConnObject().getDatabaseManager();
538 tbNmList
= dbMgr
->getAllTableNames(&rv
);
543 List
SqlStatement::getAllUserNames(DbRetVal
&ret
)
545 UserManager
*urMgr
= NULL
;
547 urMgr
=sqlCon
->getConnObject().getUserManager();
550 urNmList
= urMgr
->getAllUserNames(&rv
);
554 List
SqlStatement::getFieldNameList(const char *tblName
)
556 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
557 Table
*table
= dbMgr
->openTable(tblName
);
558 List fldNameList
= table
->getFieldNameList();
559 dbMgr
->closeTable(table
);
562 DbRetVal
SqlStatement::getFieldInfo(const char *tblName
, const char *fldName
, FieldInfo
*&info
)
564 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
565 Table
*table
= dbMgr
->openTable(tblName
);
566 DbRetVal rv
= table
->getFieldInfo(fldName
, info
);
567 dbMgr
->closeTable(table
);
570 void SqlStatement::setLoading(bool flag
)
572 if (pData
.getStmtType() == InsertStatement
||
573 pData
.getStmtType() == UpdateStatement
||
574 pData
.getStmtType() == DeleteStatement
)
576 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
577 dmlStmt
->setLoading(flag
);
582 int SqlStatement::getNoOfPagesForTable(char *tblName
)
584 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
585 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
586 return dbMgrImpl
->getNoOfPagesForTable(tblName
);
589 DbRetVal
SqlStatement::loadRecords(char *tblName
, void *buf
)
591 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
592 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
593 return dbMgrImpl
->loadRecords(tblName
, (char *) buf
);
596 DbRetVal
SqlStatement::pasteRecords(char *tblName
, void *buffer
)
598 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
599 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
600 return dbMgrImpl
->pasteRecords(tblName
, buffer
);
602 void SqlStatement::flushCacheStmt()
604 return sqlCon
->flushCacheStmt();
606 //-------------------------------------------------------------------
607 void SqlConnection::flushCacheStmt()
609 ListIterator iter
= cachedStmts
.getIterator();
610 while (iter
.hasElement()) {
611 CachedStmtNode
* node
= (CachedStmtNode
*) iter
.nextElement();
612 free(node
->sqlString
);
613 node
->sqlStmt
->setCachedStmt(false);
614 node
->sqlStmt
->free();
615 delete node
->sqlStmt
;
622 SqlStatement
* SqlConnection::findInCache(char *stmtstr
)
624 ListIterator iter
= cachedStmts
.getIterator();
625 int inputStmtLen
= strlen(stmtstr
);
626 CachedStmtNode
*node
= NULL
;
627 while ((node
= (CachedStmtNode
*)iter
.nextElement()) != NULL
)
629 if (node
->stmtLength
== inputStmtLen
)
631 if (0 == strcmp(node
->sqlString
, stmtstr
))
633 logFiner(Conf::logger
, "Statement Retrieved From Cache %x\n",
636 return node
->sqlStmt
;
642 void SqlConnection::addToCache(SqlStatement
*sqlStmt
, char* stmtString
)
644 SqlStatement
*stmt
= new SqlStatement();
646 CachedStmtNode
*node
= new CachedStmtNode();
647 node
->sqlStmt
= stmt
;
648 node
->stmtLength
= strlen(stmtString
);
649 node
->sqlString
= (char*)malloc(node
->stmtLength
+1);
650 strcpy(node
->sqlString
, stmtString
);
651 if (cachedStmts
.size() >= Conf::config
.getStmtCacheSize())
655 cachedStmts
.append(node
);
656 logFiner(Conf::logger
, "Statement added To Cache %x\n", node
->sqlStmt
);
657 logFinest(Conf::logger
, "Statement added To Cache %s\n", node
->sqlString
);
660 void SqlConnection::removeLeastUsed()
662 ListIterator iter
= cachedStmts
.getIterator();
663 CachedStmtNode
*node
= NULL
, *toRemove
=NULL
;
665 bool firstCall
= true;
666 while((node
= (CachedStmtNode
*) iter
.nextElement()) != NULL
)
670 lowHits
= node
->hits
;
671 toRemove
= node
; //if cache size is 1
674 if (lowHits
>= node
->hits
) toRemove
= node
;
676 cachedStmts
.remove(toRemove
);
677 logFiner(Conf::logger
, "Statement removed from Cache %x\n", toRemove
->sqlStmt
);
678 logFinest(Conf::logger
, "Statement removed from Cache %s\n", toRemove
->sqlString
);
681 SqlConnection::~SqlConnection()
685 if (isConnOpen
) disconnect();