fix for trie index
[csql.git] / src / sql / SqlStatement.cxx
blob2b0186c1c8ec175dddd725d2aee9dad816a7abe4
1 /**************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
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. *
9 * *
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. *
14 * *
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 <os.h>
21 #include <Statement.h>
22 #include <SqlStatement.h>
23 #include <dmllex.h>
24 #include <Recover.h>
26 char *lexInput;
27 extern ParsedData *parsedData;
29 int yyparse ();
30 bool SqlConnection::isInit = false;
31 #if (defined MMDB && defined EMBED)
32 bool SqlConnection::firstThread = false;
33 GlobalUniqueID SqlConnection::UID;
34 #endif
35 List SqlConnection::connList;
37 SqlStatement::~SqlStatement()
39 if (sqlStmtString) { ::free(sqlStmtString); sqlStmtString=NULL;}
40 if (isPrepd) { free(); isPrepd = false; }
43 void SqlStatement::setParamValues(AbsSqlStatement *sqlStmt, int parampos, DataType type, int length, void *value)
45 switch(type)
47 case typeInt:
48 sqlStmt->setIntParam(parampos, *(int*)value);
49 break;
50 case typeLong:
51 sqlStmt->setLongParam(parampos, *(long*)value);
52 break;
53 case typeLongLong:
54 sqlStmt->setLongLongParam(parampos, *(long long*)value);
55 break;
56 case typeShort:
57 sqlStmt->setShortParam(parampos, *(short*)value);
58 break;
59 case typeByteInt:
60 sqlStmt->setByteIntParam(parampos, *(char*)value);
61 break;
62 case typeDouble:
63 sqlStmt->setDoubleParam(parampos, *(double*)value);
64 break;
65 case typeFloat:
66 sqlStmt->setFloatParam(parampos, *(float*)value);
67 break;
68 case typeDate:
69 sqlStmt->setDateParam(parampos, *(Date*)value);
70 break;
71 case typeTime:
72 sqlStmt->setTimeParam(parampos, *(Time*)value);
73 break;
74 case typeTimeStamp:
75 sqlStmt->setTimeStampParam(parampos, *(TimeStamp*)value);
76 break;
77 case typeVarchar:
78 case typeString:
80 sqlStmt->setStringParam(parampos, (char*)value);
81 break;
83 case typeBinary:
84 sqlStmt->setBinaryParam(parampos, (char *) value, length);
85 break;
86 default:
87 printf("unknown type\n");
88 break;
90 return;
93 void *SqlStatement::fillBindBuffer(TDBInfo tdbName, DataType type, void *&valBuf, int length, int nRecords)
95 BindBuffer *bBuf = NULL;
96 switch(type)
98 case typeDate:
99 bBuf = new BindBuffer();
100 bBuf->csql = valBuf;
101 bBuf->type = typeDate;
102 bBuf->length = sizeof(DATE_STRUCT);
103 bBuf->targetdb = malloc(nRecords * bBuf->length);
104 memset(bBuf->targetdb, 0, nRecords * bBuf->length);
105 valBuf = bBuf->targetdb;
106 break;
107 case typeTime:
108 bBuf = new BindBuffer();
109 bBuf->csql = valBuf;
110 bBuf->type = typeTime;
111 bBuf->length = sizeof(TIME_STRUCT);
112 bBuf->targetdb = malloc(nRecords * bBuf->length);
113 memset(bBuf->targetdb, 0, nRecords * bBuf->length);
114 valBuf = bBuf->targetdb;
115 break;
116 case typeTimeStamp:
117 bBuf = new BindBuffer();
118 bBuf->csql = valBuf;
119 bBuf->type = typeTimeStamp;
120 bBuf->length = sizeof(TIMESTAMP_STRUCT);
121 bBuf->targetdb = malloc(nRecords * bBuf->length);
122 memset(bBuf->targetdb, 0, nRecords * bBuf->length);
123 valBuf = bBuf->targetdb;
124 break;
125 case typeLongLong:
127 if( tdbName == postgres)
129 bBuf = new BindBuffer();
130 bBuf->type = typeLongLong;
131 bBuf->length = 40;
132 bBuf->csql = valBuf;
133 int size = nRecords*AllDataType::size(typeString,bBuf->length);
134 bBuf->targetdb = malloc(size);
135 memset(bBuf->targetdb, 0, size);
136 valBuf = bBuf->targetdb;
137 break;
138 }else
140 bBuf = new BindBuffer();
141 bBuf->type = type;
142 bBuf->csql = valBuf;
143 bBuf->length = length;
144 break;
147 case typeVarchar:
148 case typeString:
150 bBuf = new BindBuffer();
151 bBuf->type = typeString;
152 bBuf->csql = valBuf;
153 bBuf->length = length;
154 break;
156 default:
157 bBuf = new BindBuffer();
158 bBuf->type = type;
159 bBuf->csql = valBuf;
160 bBuf->length = length;
161 break;
163 bBuf->nullData = (SQLLEN *) malloc(nRecords * sizeof(SQLLEN));
164 for (int i = 0; i < nRecords; i++) bBuf->nullData[i] = SQL_NTS;
165 return bBuf;
169 List SqlStatement::getTableNameList()
171 return pData.getTableNameList();
173 SqlStatement::SqlStatement()
175 innerStmt = NULL;
176 sqlCon = NULL;
177 stmt = NULL;
178 isPrepd = false;
179 isCachedStmt=false;
180 isMgmtStatement = false;
181 sqlStmtString = NULL;
182 dontCache = false;
184 void SqlStatement::setConnection(AbsSqlConnection *conn)
186 sqlCon = (SqlConnection*)conn;
187 con = conn;
190 void SqlStatement::setSqlConnection(SqlConnection *conn)
192 sqlCon = conn;
195 DbRetVal SqlStatement::executeDirect(char *str)
197 DbRetVal rv = OK;
198 int rows = 0;
199 rv = prepare(str);
200 if (rv != OK) return rv;
201 rv = execute(rows);
202 if (rv != OK) return rv;
203 return rv;
206 void SqlStatement::setStmtString(char *ststr)
208 if (sqlStmtString) { ::free(sqlStmtString); sqlStmtString=NULL; }
209 sqlStmtString = (char*) malloc(strlen(ststr)+1);
210 strcpy(sqlStmtString, ststr);
213 DbRetVal SqlStatement::prepare()
215 return prepareInt(sqlStmtString);
218 DbRetVal SqlStatement::prepare(char *stmtstr)
220 if (sqlStmtString) { ::free(sqlStmtString); sqlStmtString=NULL;}
221 sqlStmtString = (char*) malloc(strlen(stmtstr)+1);
222 strcpy(sqlStmtString, stmtstr);
223 return prepareInt(stmtstr);
226 DbRetVal SqlStatement::prepareInt(char *stmtstr)
228 DbRetVal rv = OK;
229 if (! sqlCon->isConnectionOpen()) {
230 printError(ErrNotOpen, "Connection not open");
231 return ErrNotOpen;
233 SqlStatement *cachedStmt = sqlCon->findInCache(stmtstr);
234 if (cachedStmt)
236 *this = *cachedStmt;
237 this->stmt->setParsedData(&this->pData);
238 isCachedStmt=true;
239 logFine(Conf::logger,"GOT STMT FROM CACHE: %s %x", stmtstr, cachedStmt);
240 return OK;
242 // take mutex here
243 int ret = ProcessManager::prepareMutex.tryLock(10, 1000);
244 if (ret != 0)
246 printError(ErrLockTimeOut, "Unable to get prepare mutex");
247 return ErrLockTimeOut;
250 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
251 if (isPrepared()) free();
252 lexInput = stmtstr;
253 parsedData = &pData;
255 yy_buffer_state *yy_buffer= yy_scan_string(stmtstr);
256 int rc = yyparse();
257 if (yy_buffer) yy_delete_buffer(yy_buffer);
258 if (rc != 0)
260 free();
261 parsedData = NULL;
262 ProcessManager::prepareMutex.releaseLock(-1, false);
263 return ErrSyntaxError;
265 if( parsedData->getStmtType() == MgmtStatement)
267 isPrepd = true;
268 parsedData = NULL;
269 isMgmtStatement = true;
270 ProcessManager::prepareMutex.releaseLock(-1, false);
271 logFine(Conf::logger,"PREPARE: %s %x", stmtstr, stmt);
272 return OK;
274 stmt = StatementFactory::getStatement(parsedData);
275 stmt->setDbMgr(dbMgr);
276 if( parsedData->getStmtType() == UserStatement)
278 UserManager* userMgr = sqlCon->getConnObject().getUserManager();
279 UserTblStatement *ustmt = (UserTblStatement *)stmt;
280 ustmt->setUserManager(userMgr,sqlCon->getConnObject().getUserName());
282 rv = stmt->resolve();
283 if (rv != OK)
285 free();
286 parsedData = NULL;
287 ProcessManager::prepareMutex.releaseLock(-1, false);
288 return rv;
290 isPrepd = true;
291 if (!isCachedStmt && Conf::config.getStmtCacheSize() && !getDontCache()) {
292 if (stmt->noOfParamFields() > 0) {
293 isCachedStmt = true;
294 sqlCon->addToCache(this, stmtstr);
295 } else if (Conf::config.useCacheNoParam()) {
296 if (parsedData->getCacheWorthy()) {
297 isCachedStmt = true;
298 sqlCon->addToCache(this, stmtstr);
301 } else { printf("stmtstring '%s' not cached\n", stmtstr); }
302 parsedData = NULL;
303 ProcessManager::prepareMutex.releaseLock(-1, false);
304 return OK;
307 char* SqlStatement::getTableName()
309 return pData.getTableName();
312 bool SqlStatement::isSelect()
314 if ((pData.getStmtType() == SelectStatement) || (pData.getStmtType() == MetaStatement)) return true;
315 return false;
318 bool SqlStatement::isPrepared() { return isPrepd; }
320 DbRetVal SqlStatement::execute(int &rowsAffected)
322 DbRetVal rv = OK;
323 if (! sqlCon->isConnectionOpen()) {
324 printError(ErrNotOpen, "Connection not open");
325 return ErrNotOpen;
327 if (! isPrepared()) {
328 printError(ErrNotPrepared, "Statement Not Prepared");
329 return ErrNotPrepared;
331 if( isMgmtStatement )
333 flushCacheStmt();
334 logFiner(Conf::logger,"EXECUTE: %x", stmt);
335 return OK;
337 rv = stmt->execute(rowsAffected);
338 if (rv == ErrAlready && pData.getStmtType() == SelectStatement )
339 { //if previous scan is not closed, close it
340 SelStatement *selStmt = (SelStatement*) stmt;
341 selStmt->close();
342 rv = stmt->execute(rowsAffected);
344 logFiner(Conf::logger,"EXECUTE: %x", stmt);
345 return rv;
348 void* SqlStatement::fetch()
350 if (! sqlCon->isConnectionOpen()) {
351 printError(ErrNotOpen, "Connection not open");
352 return NULL;
354 if (! isPrepared()) {
355 printError(ErrNotPrepared, "Statement Not Prepared");
356 return NULL;
358 if (pData.getStmtType() == SelectStatement ) {
359 SelStatement *selStmt = (SelStatement*) stmt;
360 return selStmt->fetch();
362 else if(pData.getStmtType() == MetaStatement){
363 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
364 return metaStmt->fetch();
366 else { return NULL;}
369 void* SqlStatement::fetch(DbRetVal &rv)
371 if (! sqlCon->isConnectionOpen()) {
372 printError(ErrNotOpen, "Connection not open");
373 rv = ErrNoConnection;
374 return NULL;
376 if (! isPrepared()) {
377 printError(ErrNotPrepared, "Statement Not Prepared");
378 return NULL;
380 if (pData.getStmtType() == SelectStatement ) {
381 SelStatement *selStmt = (SelStatement*) stmt;
382 return selStmt->fetch(rv);
384 else if(pData.getStmtType() == MetaStatement){
385 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
386 return metaStmt->fetch(rv);
388 else { return NULL;}
391 void* SqlStatement::fetchAndPrint(bool SQL)
393 if (! sqlCon->isConnectionOpen()) {
394 printError(ErrNotOpen, "Connection not open");
395 return NULL;
397 if (! isPrepared()) {
398 printError(ErrNotPrepared, "Statement Not Prepared");
399 return NULL;
401 if (pData.getStmtType() != SelectStatement) return NULL;
402 SelStatement *selStmt = (SelStatement*) stmt;
403 return selStmt->fetchAndPrint(SQL);
406 DbRetVal SqlStatement::bindParam(int pos, void* value)
408 DbRetVal rv = OK;
409 rv = stmt->setParam(pos, value);
410 return rv;
413 DbRetVal SqlStatement::bindField(int pos, void* value)
415 DbRetVal rv = OK;
416 if (pData.getStmtType() == SelectStatement ) {
417 SelStatement *selStmt = (SelStatement*) stmt;
418 return selStmt->setBindField(pos, value);
420 else if(pData.getStmtType() == MetaStatement){
421 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
422 return metaStmt->setBindField(pos, value);
424 else { return ErrBadCall;}
426 void* SqlStatement::next()
428 if (pData.getStmtType() == SelectStatement ) {
429 SelStatement *selStmt = (SelStatement*) stmt;
430 return( (void*) selStmt->next() );
432 else if(pData.getStmtType() == MetaStatement){
433 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
434 return( (void*) metaStmt->next() );
436 else { return 0;}
439 bool SqlStatement::isFldNull(int pos)
441 if (pData.getStmtType() != SelectStatement) return 0;
442 SelStatement *selStmt = (SelStatement*) stmt;
443 return (selStmt->isFldNull(pos));
445 bool SqlStatement::isFldNull(char *name)
447 if (pData.getStmtType() != SelectStatement) return 0;
448 SelStatement *selStmt = (SelStatement*) stmt;
449 return (selStmt->isFldNull(name));
451 DbRetVal SqlStatement::close()
453 if (pData.getStmtType() == SelectStatement ) {
454 SelStatement *selStmt = (SelStatement*) stmt;
455 logFinest(Conf::logger,"CLOSE: %x", stmt);
456 return selStmt->close();
458 else if(pData.getStmtType() == MetaStatement){
459 MetadataStatement *selStmt = (MetadataStatement*) stmt;
460 logFinest(Conf::logger,"CLOSE: %x", stmt);
461 return selStmt->close();
463 else { return OK;}
466 void* SqlStatement::getParamValuePtr( int pos )
468 //if (pData.getStmtType() != SelectStatement) return 0;
469 DmlStatement *dmlStmt = (DmlStatement*) stmt;
470 return( (void*) dmlStmt->getParamValuePtr( pos ) );
473 char* SqlStatement::getFieldName( int pos )
475 if (pData.getStmtType() == SelectStatement ) {
476 SelStatement *selStmt = (SelStatement*) stmt;
477 return( (char*) selStmt->getFieldName( pos ) );
479 else if(pData.getStmtType() == MetaStatement){
480 MetadataStatement *selStmt = (MetadataStatement*) stmt;
481 return( (char*) selStmt->getFieldName( pos ) );
483 else { return 0;}
486 DataType SqlStatement::getFieldType( int pos )
488 if (pData.getStmtType() == SelectStatement ) {
489 SelStatement *selStmt = (SelStatement*) stmt;
490 return( (DataType) selStmt->getFieldType( pos ) );
492 else if(pData.getStmtType() == MetaStatement){
493 MetadataStatement *selStmt = (MetadataStatement*) stmt;
494 return( (DataType) selStmt->getFieldType( pos ) );
496 else { return typeUnknown;}
498 int SqlStatement::getFieldLength( int pos )
500 if (pData.getStmtType() == SelectStatement ) {
501 SelStatement *selStmt = (SelStatement*) stmt;
502 return( (int) selStmt->getFieldLength( pos ) );
504 else if(pData.getStmtType() == MetaStatement){
505 MetadataStatement *selStmt = (MetadataStatement*) stmt;
506 return( (int) selStmt->getFieldLength( pos ) );
508 else { return 0;}
511 void* SqlStatement::getFieldValuePtr( int pos )
513 if (pData.getStmtType() == SelectStatement ) {
514 SelStatement *selStmt = (SelStatement*) stmt;
515 return( (void*) selStmt->getFieldValuePtr( pos ) );
517 else if(pData.getStmtType() == MetaStatement){
518 MetadataStatement *selStmt = (MetadataStatement*) stmt;
519 return( (void*) selStmt->getFieldValuePtr( pos ) );
521 else { return 0;}
523 void* SqlStatement::getFieldValuePtr( char *name )
525 if (pData.getStmtType() == SelectStatement ) {
526 SelStatement *selStmt = (SelStatement*) stmt;
527 return( (void*) selStmt->getFieldValuePtr( name ) );
529 else if(pData.getStmtType() == MetaStatement){
530 MetadataStatement *selStmt = (MetadataStatement*) stmt;
531 return( (void*) selStmt->getFieldValuePtr( name ) );
533 else { return NULL;}
536 int SqlStatement::noOfProjFields()
538 if (pData.getStmtType() == SelectStatement ) {
539 SelStatement *selStmt = (SelStatement*) stmt;
540 return selStmt->noOfProjFields();
542 else if(pData.getStmtType() == MetaStatement){
543 MetadataStatement *selStmt = (MetadataStatement*) stmt;
544 return selStmt->noOfProjFields();
546 else { return 0;}
549 void SqlStatement::getProjFieldType(int *data)
551 if (pData.getStmtType() == SelectStatement ) {
552 SelStatement *selStmt = (SelStatement*) stmt;
553 return( selStmt->getProjFieldType(data) );
555 else if(pData.getStmtType() == MetaStatement){
556 MetadataStatement *selStmt = (MetadataStatement*) stmt;
557 return( selStmt->getProjFieldType(data) );
563 int SqlStatement::noOfParamFields()
565 if (NULL == stmt) return 0;
566 else return stmt->noOfParamFields();
569 DbRetVal SqlStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
571 DbRetVal rv = OK;
572 if (pData.getStmtType() == SelectStatement ) {
573 SelStatement *selStmt = (SelStatement*) stmt;
574 rv = selStmt->getProjFldInfo(projpos, fInfo);
576 else if(pData.getStmtType() == MetaStatement){
577 MetadataStatement *selStmt = (MetadataStatement*) stmt;
578 rv = selStmt->getProjFldInfo(projpos, fInfo);
579 } else { return ErrBadCall;}
580 return rv;
583 DbRetVal SqlStatement::getParamFldInfo (int parampos, FieldInfo *&fInfo)
585 DbRetVal rv = OK;
586 if (pData.getStmtType() ==SelectStatement ||
587 pData.getStmtType() ==InsertStatement ||
588 pData.getStmtType() ==UpdateStatement ||
589 pData.getStmtType() ==DeleteStatement)
592 DmlStatement *dmlStmt = (DmlStatement*) stmt;
593 rv = dmlStmt->getParamFldInfo(parampos, fInfo);
595 return rv;
598 DbRetVal SqlStatement::free()
600 logFinest(Conf::logger,"FREE: %x", stmt);
601 if (isCachedStmt) {
602 stmt=NULL;
603 pData.init();
604 isPrepd = false;
605 if (sqlStmtString) {
606 sqlCon->setStmtNotInUse(sqlStmtString);
607 ::free(sqlStmtString);
608 sqlStmtString=NULL;
610 isCachedStmt = false;
611 return OK;
613 if(stmt) delete stmt;
614 stmt = NULL;
615 pData.reset();
616 isMgmtStatement = false;
617 isPrepd = false;
618 isCachedStmt = false;
619 if (sqlStmtString) { ::free(sqlStmtString); sqlStmtString=NULL; }
620 return OK;
623 void SqlStatement::setNull(int pos)
625 stmt->setNull(pos);
627 void SqlStatement::setShortParam(int paramPos, short value)
629 stmt->setShortParam(paramPos, value);
631 void SqlStatement::setIntParam(int paramPos, int value)
633 stmt->setIntParam(paramPos, value);
635 void SqlStatement::setLongParam(int paramPos, long value)
637 stmt->setLongParam(paramPos, value);
639 void SqlStatement::setLongLongParam(int paramPos, long long value)
641 stmt->setLongLongParam(paramPos, value);
643 void SqlStatement::setByteIntParam(int paramPos, ByteInt value)
645 stmt->setByteIntParam(paramPos, value);
647 void SqlStatement::setFloatParam(int paramPos, float value)
649 stmt->setFloatParam(paramPos, value);
651 void SqlStatement::setDoubleParam(int paramPos, double value)
653 stmt->setDoubleParam(paramPos, value);
655 void SqlStatement::setStringParam(int paramPos, char *value)
657 stmt->setStringParam(paramPos, value);
659 void SqlStatement::setDateParam(int paramPos, Date value)
661 stmt->setDateParam(paramPos, value);
663 void SqlStatement::setTimeParam(int paramPos, Time value)
665 stmt->setTimeParam(paramPos, value);
667 void SqlStatement::setTimeStampParam(int paramPos, TimeStamp value)
669 stmt->setTimeStampParam(paramPos, value);
671 void SqlStatement::setBinaryParam(int paramPos, void *value, int length)
673 stmt->setBinaryParam(paramPos, value, length);
675 int SqlStatement::getFldPos(char *name)
677 return stmt->getFldPos(name);
679 long long SqlStatement::getLastInsertedVal(DbRetVal &rv)
681 return stmt->getLastInsertedVal(rv);
683 List SqlStatement::getAllTableNames(DbRetVal &ret)
685 DatabaseManager *dbMgr = NULL;
686 List tbNmList;
687 dbMgr=sqlCon->getConnObject().getDatabaseManager();
688 int rv = ret;
689 if(dbMgr != NULL) tbNmList = dbMgr->getAllTableNames(&rv);
690 ret = (DbRetVal) rv;
691 return tbNmList;
694 List SqlStatement::getAllUserNames(DbRetVal &ret)
696 UserManager *urMgr = NULL;
697 List urNmList;
698 urMgr=sqlCon->getConnObject().getUserManager();
699 int rv = ret;
700 if(urMgr != NULL)
701 urNmList = urMgr->getAllUserNames(&rv);
702 ret = (DbRetVal) rv;
703 return urNmList;
705 List SqlStatement::getFieldNameList(const char *tblName, DbRetVal &rv)
707 List fldNameList;
708 if (isPrepared()) {
709 fldNameList = stmt->getFieldNameList(tblName, rv);
710 return fldNameList;
712 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
713 Table *table = dbMgr->openTable(tblName);
714 if (NULL == table) {
715 List dummyList;
716 printError(ErrLockTimeOut, "Unable to open table %s", tblName);
717 return dummyList;
719 fldNameList = table->getFieldNameList();
720 dbMgr->closeTable(table);
721 return fldNameList;
723 DbRetVal SqlStatement::getFieldInfo(const char *tblName, const char *fldName, FieldInfo *&info)
725 DbRetVal rv = OK;
726 if (isPrepared()) {
727 rv = stmt->getFieldInfo(tblName, fldName, info);
728 return rv;
730 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
731 Table *table = dbMgr->openTable(tblName);
732 if (NULL == table) {
733 printError(ErrLockTimeOut, "Unable to open table %s", tblName);
734 return ErrLockTimeOut;
736 rv = table->getFieldInfo(fldName, info);
737 dbMgr->closeTable(table);
738 return rv;
740 void SqlStatement::setLoading(bool flag)
742 if (pData.getStmtType() == InsertStatement||
743 pData.getStmtType() == UpdateStatement||
744 pData.getStmtType() == DeleteStatement)
746 DmlStatement *dmlStmt = (DmlStatement*) stmt;
747 dmlStmt->setLoading(flag);
749 return;
752 int SqlStatement::getNoOfPagesForTable(char *tblName)
754 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
755 DatabaseManagerImpl *dbMgrImpl = (DatabaseManagerImpl *)dbMgr;
756 return dbMgrImpl->getNoOfPagesForTable(tblName);
759 DbRetVal SqlStatement::loadRecords(char *tblName, void *buf)
761 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
762 DatabaseManagerImpl *dbMgrImpl = (DatabaseManagerImpl *)dbMgr;
763 return dbMgrImpl->loadRecords(tblName, (char *) buf);
766 DbRetVal SqlStatement::pasteRecords(char *tblName, void *buffer)
768 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
769 DatabaseManagerImpl *dbMgrImpl = (DatabaseManagerImpl *)dbMgr;
770 return dbMgrImpl->pasteRecords(tblName, buffer);
772 void SqlStatement::flushCacheStmt()
774 return sqlCon->flushCacheStmt();
777 void SqlStatement::resetStmtString() {
778 sqlStmtString=NULL;
780 //-------------------------------------------------------------------
782 static void sigTermHandler(int sig)
784 ListIterator iter= SqlConnection::connList.getIterator();
785 SqlConnection *conn = NULL;
786 while (iter.hasElement())
788 conn = (SqlConnection*) iter.nextElement();
789 conn->flushCacheStmt();
790 if (conn->isConnectionOpen()) conn->disconnect();
792 exit(0);
795 DbRetVal SqlConnection::connect (char *user, char * pass)
797 DbRetVal ret = conn.open(user, pass);
798 if (ret != OK) return ret;
799 if (ret == OK) isConnOpen = true;
800 if (!isInit) initialize();
801 connList.append(this);
802 DbRetVal rv = OK;
803 #if (defined MMDB && EMBED)
804 os::signal(SIGINT, sigTermHandler);
805 os::signal(SIGTERM, sigTermHandler);
806 if (Conf::config.useDurability() && !firstThread) {
807 Recovery recovery;
808 rv = recovery.recoverCsqlDB(this);
809 //rv = recoverCsqlDB(this);
810 if (rv != OK) {
811 printError(ErrSysInternal, "Recovery Failed");
812 return rv;
814 firstThread = true;
816 rollback(); //for drop table execute in redo log
817 #endif
818 return ret;
821 void SqlConnection::flushCacheStmt()
823 ListIterator iter = cachedStmts.getIterator();
824 while (iter.hasElement()) {
825 CachedStmtNode* node = (CachedStmtNode*) iter.nextElement();
826 //do not delete when the statement is currently in use.
827 //otherwise it leads to illegal memory access when application
828 //calls any method on this statement
829 if (node->inUse) continue;
830 //if (node->inUse) node->inUse = 0;
831 free(node->sqlString);
832 node->sqlStmt->setCachedStmt(false);
833 node->sqlStmt->free();
834 delete node->sqlStmt;
835 delete node;
837 cachedStmts.reset();
838 return;
841 void SqlConnection::setStmtNotInUse(char *stmtstr)
843 ListIterator iter = cachedStmts.getIterator();
844 int inputStmtLen = strlen(stmtstr);
845 CachedStmtNode *node = NULL;
846 while ((node = (CachedStmtNode*)iter.nextElement()) != NULL)
848 if (node->stmtLength == inputStmtLen)
850 if (0 == strcmp(node->sqlString, stmtstr))
852 node->inUse =0;
853 return;
859 SqlStatement* SqlConnection::findInCache(char *stmtstr)
861 ListIterator iter = cachedStmts.getIterator();
862 int inputStmtLen = strlen(stmtstr);
863 CachedStmtNode *node = NULL;
864 while ((node = (CachedStmtNode*)iter.nextElement()) != NULL)
866 if (node->stmtLength == inputStmtLen)
868 if (0 == strcmp(node->sqlString, stmtstr))
870 logFiner(Conf::logger, "Statement Retrieved From Cache %x\n",
871 node->sqlStmt);
872 node->hits++;
873 node->inUse = 1;
874 return node->sqlStmt;
878 return NULL;
881 void SqlConnection::addToCache(SqlStatement *sqlStmt, char* stmtString)
883 SqlStatement *stmt = new SqlStatement();
884 *stmt= *sqlStmt;
885 CachedStmtNode *node = new CachedStmtNode();
886 node->sqlStmt = stmt;
887 node->stmtLength = strlen(stmtString);
888 node->sqlString = (char*)malloc(node->stmtLength+1);
889 node->inUse=1;
890 strcpy(node->sqlString, stmtString);
891 if (cachedStmts.size() >= Conf::config.getStmtCacheSize())
893 removeLeastUsed();
895 node->sqlStmt->resetStmtString();
896 cachedStmts.append(node);
897 logFiner(Conf::logger, "Statement added To Cache %x\n", node->sqlStmt);
898 logFinest(Conf::logger, "Statement added To Cache %s\n", node->sqlString);
899 return ;
902 void SqlConnection::removeLeastUsed()
904 ListIterator iter = cachedStmts.getIterator();
905 CachedStmtNode *node = NULL, *toRemove =NULL;
906 int lowHits = 0;
907 bool firstCall = true;
908 while((node = (CachedStmtNode*) iter.nextElement()) != NULL)
910 if (firstCall) {
911 firstCall = false;
912 lowHits = node->hits;
913 toRemove = node; //if cache size is 1
914 continue;
916 if (lowHits >= node->hits) toRemove = node;
918 cachedStmts.remove(toRemove);
919 //TODO::check whether there is memory leak for list elements
920 logFiner(Conf::logger, "Statement removed from Cache %x\n", toRemove->sqlStmt);
921 logFinest(Conf::logger, "Statement removed from Cache %s\n", toRemove->sqlString);
922 delete toRemove; toRemove = NULL;
923 return;
926 SqlConnection::~SqlConnection()
928 flushCacheStmt();
929 if (isConnOpen) disconnect();
930 innerConn = NULL;
933 static void sigUsr1Handler(int sig)
935 ListIterator iter= SqlConnection::connList.getIterator();
936 SqlConnection *conn = NULL;
937 while (iter.hasElement())
939 conn = (SqlConnection*) iter.nextElement();
940 conn->flushCacheStmt();
942 os::signal(SIGCSQL1, sigUsr1Handler);
943 return;
946 static void exithandler(void)
948 ListIterator iter= SqlConnection::connList.getIterator();
949 SqlConnection *conn = NULL;
950 while (iter.hasElement())
952 conn = (SqlConnection*) iter.nextElement();
953 conn->flushCacheStmt();
954 conn->disconnect();
957 void SqlConnection::displayStmtCache()
959 ListIterator iter = cachedStmts.getIterator();
960 CachedStmtNode *node = NULL;
961 printf("STATEMENT CACHE START \n");
962 while ((node = (CachedStmtNode*)iter.nextElement()) != NULL)
964 node->display();
966 printf("STATEMENT CACHE END\n");
969 void SqlConnection::initialize()
971 os::signal(SIGCSQL1, sigUsr1Handler);
972 #if (defined MMDB && defined EMBED)
973 os::atexit(exithandler);
974 #endif
975 isInit = true;