checkpoint server changes
[csql.git] / src / sql / SqlStatement.cxx
blobff6d71a051ba0d4ec92543bab1aec8bd22274de1
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>
25 char *lexInput;
26 extern ParsedData *parsedData;
28 int yyparse ();
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()
44 innerStmt = NULL;
45 sqlCon = NULL;
46 stmt = NULL;
47 isPrepd = false;
48 isCachedStmt=false;
49 isMgmtStatement = false;
51 void SqlStatement::setConnection(AbsSqlConnection *conn)
53 sqlCon = (SqlConnection*)conn;
54 con = conn;
57 void SqlStatement::setSqlConnection(SqlConnection *conn)
59 sqlCon = conn;
62 DbRetVal SqlStatement::executeDirect(char *str)
64 DbRetVal rv = OK;
65 int rows = 0;
66 rv = prepare(str);
67 if (rv != OK) return rv;
68 rv = execute(rows);
69 if (rv != OK) return rv;
70 return rv;
73 DbRetVal SqlStatement::prepare(char *stmtstr)
75 DbRetVal rv = OK;
76 if (! sqlCon->isConnectionOpen()) {
77 printError(ErrNotOpen, "Connection not open");
78 return ErrNotOpen;
80 SqlStatement *cachedStmt = sqlCon->findInCache(stmtstr);
81 if (cachedStmt)
83 *this = *cachedStmt;
84 this->stmt->setParsedData(&this->pData);
85 logFine(Conf::logger,"GOT STMT FROM CACHE: %s %x", stmtstr, cachedStmt);
86 return OK;
88 // take mutex here
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();
96 while (true) {
97 rv = sysdb->getPrepareStmtMutex();
98 if (rv == OK) break;
99 tries--;
100 if (tries == 0) {
101 printError(rv,
102 "Unable to get prepare statement mutex after %d tries", Conf::config.getMutexRetries());
103 return rv;
105 os::select(0, 0, 0, 0, &timeout);
108 if (isPrepared()) free();
109 lexInput = stmtstr;
110 parsedData = &pData;
112 yy_buffer_state *yy_buffer= yy_scan_string(stmtstr);
113 int rc = yyparse();
114 if (yy_buffer) yy_delete_buffer(yy_buffer);
115 if (rc != 0)
117 free();
118 parsedData = NULL;
119 //yyrestart(yyin);
120 sysdb->releasePrepareStmtMutex();
121 return ErrSyntaxError;
123 if( parsedData->getStmtType() == MgmtStatement)
125 isPrepd = true;
126 parsedData = NULL;
127 isMgmtStatement = true;
128 sysdb->releasePrepareStmtMutex();
129 logFine(Conf::logger,"PREPARE: %s %x", stmtstr, stmt);
130 return OK;
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();
141 if (rv != OK)
143 free();
144 parsedData = NULL;
145 //yyrestart(yyin);
146 sysdb->releasePrepareStmtMutex();
147 return rv;
149 isPrepd = true;
150 if (Conf::config.getStmtCacheSize()) {
151 if (stmt->noOfParamFields() > 0) {
152 isCachedStmt = true;
153 sqlCon->addToCache(this, stmtstr);
154 }else if (Conf::config.useCacheNoParam())
156 if (parsedData->getCacheWorthy())
158 isCachedStmt = true;
159 sqlCon->addToCache(this, stmtstr);
163 parsedData = NULL;
164 sysdb->releasePrepareStmtMutex();
165 return OK;
168 char* SqlStatement::getTableName()
170 return pData.getTableName();
173 bool SqlStatement::isSelect()
175 if ((pData.getStmtType() == SelectStatement) || (pData.getStmtType() == MetaStatement)) return true;
176 return false;
179 bool SqlStatement::isPrepared() { return isPrepd; }
181 DbRetVal SqlStatement::execute(int &rowsAffected)
183 DbRetVal rv = OK;
184 if (! sqlCon->isConnectionOpen()) {
185 printError(ErrNotOpen, "Connection not open");
186 return ErrNotOpen;
188 if (! isPrepared()) {
189 printError(ErrNotPrepared, "Statement Not Prepared");
190 return ErrNotPrepared;
192 if( isMgmtStatement )
194 flushCacheStmt();
195 logFiner(Conf::logger,"EXECUTE: %x", stmt);
196 return OK;
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;
202 selStmt->close();
203 rv = stmt->execute(rowsAffected);
205 logFiner(Conf::logger,"EXECUTE: %x", stmt);
206 return rv;
209 void* SqlStatement::fetch()
211 if (! sqlCon->isConnectionOpen()) {
212 printError(ErrNotOpen, "Connection not open");
213 return NULL;
215 if (! isPrepared()) {
216 printError(ErrNotPrepared, "Statement Not Prepared");
217 return NULL;
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();
227 else { return NULL;}
230 void* SqlStatement::fetch(DbRetVal &rv)
232 if (! sqlCon->isConnectionOpen()) {
233 printError(ErrNotOpen, "Connection not open");
234 return NULL;
236 if (! isPrepared()) {
237 printError(ErrNotPrepared, "Statement Not Prepared");
238 return NULL;
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);
248 else { return NULL;}
251 void* SqlStatement::fetchAndPrint(bool SQL)
253 if (! sqlCon->isConnectionOpen()) {
254 printError(ErrNotOpen, "Connection not open");
255 return NULL;
257 if (! isPrepared()) {
258 printError(ErrNotPrepared, "Statement Not Prepared");
259 return NULL;
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)
268 DbRetVal rv = OK;
269 rv = stmt->setParam(pos, value);
270 return rv;
273 DbRetVal SqlStatement::bindField(int pos, void* value)
275 DbRetVal rv = OK;
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() );
296 else { return 0;}
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();
323 else { return OK;}
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 ) );
343 else { return 0;}
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 ) );
368 else { return 0;}
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 ) );
381 else { return 0;}
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 ) );
393 else { return NULL;}
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();
406 else { return 0;}
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)
430 DbRetVal rv = OK;
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;}
439 return rv;
442 DbRetVal SqlStatement::getParamFldInfo (int parampos, FieldInfo *&fInfo)
444 DbRetVal rv = OK;
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);
454 return rv;
457 DbRetVal SqlStatement::free()
459 logFinest(Conf::logger,"FREE: %x", stmt);
460 if (isCachedStmt) {
461 stmt=NULL;
462 pData.init();
463 isPrepd = false;
464 return OK;
466 if(stmt) delete stmt;
467 stmt = NULL;
468 pData.reset();
469 isMgmtStatement = false;
470 isPrepd = false;
471 return OK;
474 void SqlStatement::setNull(int pos)
476 stmt->setNull(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;
533 List tbNmList;
534 dbMgr=sqlCon->getConnObject().getDatabaseManager();
535 int rv = ret;
536 if(dbMgr != NULL)
537 tbNmList = dbMgr->getAllTableNames(&rv);
538 ret = (DbRetVal) rv;
539 return tbNmList;
542 List SqlStatement::getAllUserNames(DbRetVal &ret)
544 UserManager *urMgr = NULL;
545 List urNmList;
546 urMgr=sqlCon->getConnObject().getUserManager();
547 int rv = ret;
548 if(urMgr != NULL)
549 urNmList = urMgr->getAllUserNames(&rv);
550 ret = (DbRetVal) rv;
551 return urNmList;
553 List SqlStatement::getFieldNameList(const char *tblName)
555 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
556 Table *table = dbMgr->openTable(tblName);
557 if (NULL == table) {
558 List dummyList;
559 printError(ErrLockTimeOut, "Unable to open table %s", tblName);
560 return dummyList;
562 List fldNameList = table->getFieldNameList();
563 dbMgr->closeTable(table);
564 return fldNameList;
566 DbRetVal SqlStatement::getFieldInfo(const char *tblName, const char *fldName, FieldInfo *&info)
568 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
569 Table *table = dbMgr->openTable(tblName);
570 if (NULL == table) {
571 printError(ErrLockTimeOut, "Unable to open table %s", tblName);
572 return ErrLockTimeOut;
574 DbRetVal rv = table->getFieldInfo(fldName, info);
575 dbMgr->closeTable(table);
576 return OK;
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);
587 return;
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;
624 delete node;
626 cachedStmts.reset();
627 return;
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",
642 node->sqlStmt);
643 node->hits++;
644 return node->sqlStmt;
648 return NULL;
650 void SqlConnection::addToCache(SqlStatement *sqlStmt, char* stmtString)
652 SqlStatement *stmt = new SqlStatement();
653 *stmt= *sqlStmt;
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())
661 removeLeastUsed();
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);
666 return ;
668 void SqlConnection::removeLeastUsed()
670 ListIterator iter = cachedStmts.getIterator();
671 CachedStmtNode *node = NULL, *toRemove =NULL;
672 int lowHits = 0;
673 bool firstCall = true;
674 while((node = (CachedStmtNode*) iter.nextElement()) != NULL)
676 if (firstCall) {
677 firstCall = false;
678 lowHits = node->hits;
679 toRemove = node; //if cache size is 1
680 continue;
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);
687 return;
689 SqlConnection::~SqlConnection()
691 innerConn = NULL;
692 flushCacheStmt();
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);
705 return;
707 void SqlConnection::initialize()
709 os::signal(SIGCSQL1, sigUsr1Handler);
710 isInit = true;