Removing dependency for Cache module in MMDB build
[csql.git] / src / sql / SqlStatement.cxx
blob96af9b2218a3dda3d4ea181f4578b52941dd4bef
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 ();
30 SqlStatement::~SqlStatement()
32 if (isPrepd) { free(); isPrepd = false; }
35 List SqlStatement::getTableNameList()
37 return pData.getTableNameList();
39 SqlStatement::SqlStatement()
41 innerStmt = NULL;
42 sqlCon = NULL;
43 stmt = NULL;
44 isPrepd = false;
45 isCachedStmt=false;
46 isMgmtStatement = false;
48 void SqlStatement::setConnection(AbsSqlConnection *conn)
50 sqlCon = (SqlConnection*)conn;
51 con = conn;
54 void SqlStatement::setSqlConnection(SqlConnection *conn)
56 sqlCon = conn;
59 DbRetVal SqlStatement::executeDirect(char *str)
61 DbRetVal rv = OK;
62 int rows = 0;
63 rv = prepare(str);
64 if (rv != OK) return rv;
65 rv = execute(rows);
66 if (rv != OK) return rv;
67 return rv;
70 DbRetVal SqlStatement::prepare(char *stmtstr)
72 DbRetVal rv = OK;
73 if (! sqlCon->isConnectionOpen()) {
74 printError(ErrNotOpen, "Connection not open");
75 return ErrNotOpen;
77 SqlStatement *cachedStmt = sqlCon->findInCache(stmtstr);
78 if (cachedStmt)
80 *this = *cachedStmt;
81 this->stmt->setParsedData(&this->pData);
82 logFine(Conf::logger,"GOT STMT FROM CACHE: %s %x", stmtstr, cachedStmt);
83 return OK;
85 // take mutex here
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();
93 while (true) {
94 rv = sysdb->getPrepareStmtMutex();
95 if (rv == OK) break;
96 tries--;
97 if (tries == 0) {
98 printError(rv,
99 "Unable to get prepare statement mutex after %d tries", Conf::config.getMutexRetries());
100 return rv;
102 os::select(0, 0, 0, 0, &timeout);
105 if (isPrepared()) free();
106 lexInput = stmtstr;
107 parsedData = &pData;
109 yy_buffer_state *yy_buffer= yy_scan_string(stmtstr);
110 int rc = yyparse();
111 if (yy_buffer) yy_delete_buffer(yy_buffer);
112 if (rc != 0)
114 free();
115 parsedData = NULL;
116 //yyrestart(yyin);
117 sysdb->releasePrepareStmtMutex();
118 return ErrSyntaxError;
120 if( parsedData->getStmtType() == MgmtStatement)
122 isPrepd = true;
123 parsedData = NULL;
124 isMgmtStatement = true;
125 sysdb->releasePrepareStmtMutex();
126 logFine(Conf::logger,"PREPARE: %s %x", stmtstr, stmt);
127 return OK;
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();
138 if (rv != OK)
140 free();
141 parsedData = NULL;
142 //yyrestart(yyin);
143 sysdb->releasePrepareStmtMutex();
144 return rv;
146 parsedData = NULL;
147 //yyrestart(yyin);
148 sysdb->releasePrepareStmtMutex();
149 isPrepd = true;
150 if (stmt->noOfParamFields()>0) {
151 isCachedStmt = true;
152 sqlCon->addToCache(this, stmtstr);
153 return OK;
155 return OK;
158 char* SqlStatement::getTableName()
160 return pData.getTableName();
163 bool SqlStatement::isSelect()
165 if ((pData.getStmtType() == SelectStatement) || (pData.getStmtType() == MetaStatement)) return true;
166 return false;
169 bool SqlStatement::isPrepared() { return isPrepd; }
171 DbRetVal SqlStatement::execute(int &rowsAffected)
173 DbRetVal rv = OK;
174 if (! sqlCon->isConnectionOpen()) {
175 printError(ErrNotOpen, "Connection not open");
176 return ErrNotOpen;
178 if (! isPrepared()) {
179 printError(ErrNotPrepared, "Statement Not Prepared");
180 return ErrNotPrepared;
182 if( isMgmtStatement )
184 flushCacheStmt();
185 logFiner(Conf::logger,"EXECUTE: %x", stmt);
186 return OK;
188 rv = stmt->execute(rowsAffected);
189 if (rv == ErrAlready && pData.getStmtType() == SelectStatement )
190 { //if previous scan is not closed, close it
191 SelStatement *selStmt = (SelStatement*) stmt;
192 selStmt->close();
193 rv = stmt->execute(rowsAffected);
195 logFiner(Conf::logger,"EXECUTE: %x", stmt);
196 return rv;
199 void* SqlStatement::fetch()
201 if (! sqlCon->isConnectionOpen()) {
202 printError(ErrNotOpen, "Connection not open");
203 return NULL;
205 if (! isPrepared()) {
206 printError(ErrNotPrepared, "Statement Not Prepared");
207 return NULL;
209 if (pData.getStmtType() == SelectStatement ) {
210 SelStatement *selStmt = (SelStatement*) stmt;
211 return selStmt->fetch();
213 else if(pData.getStmtType() == MetaStatement){
214 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
215 return metaStmt->fetch();
217 else { return NULL;}
220 void* SqlStatement::fetch(DbRetVal &rv)
222 if (! sqlCon->isConnectionOpen()) {
223 printError(ErrNotOpen, "Connection not open");
224 return NULL;
226 if (! isPrepared()) {
227 printError(ErrNotPrepared, "Statement Not Prepared");
228 return NULL;
230 if (pData.getStmtType() == SelectStatement ) {
231 SelStatement *selStmt = (SelStatement*) stmt;
232 return selStmt->fetch(rv);
234 else if(pData.getStmtType() == MetaStatement){
235 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
236 return metaStmt->fetch(rv);
238 else { return NULL;}
241 void* SqlStatement::fetchAndPrint(bool SQL)
243 if (! sqlCon->isConnectionOpen()) {
244 printError(ErrNotOpen, "Connection not open");
245 return NULL;
247 if (! isPrepared()) {
248 printError(ErrNotPrepared, "Statement Not Prepared");
249 return NULL;
251 if (pData.getStmtType() != SelectStatement) return NULL;
252 SelStatement *selStmt = (SelStatement*) stmt;
253 return selStmt->fetchAndPrint(SQL);
256 DbRetVal SqlStatement::bindParam(int pos, void* value)
258 DbRetVal rv = OK;
259 rv = stmt->setParam(pos, value);
260 return rv;
263 DbRetVal SqlStatement::bindField(int pos, void* value)
265 DbRetVal rv = OK;
266 if (pData.getStmtType() == SelectStatement ) {
267 SelStatement *selStmt = (SelStatement*) stmt;
268 return selStmt->setBindField(pos, value);
270 else if(pData.getStmtType() == MetaStatement){
271 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
272 return metaStmt->setBindField(pos, value);
274 else { return ErrBadCall;}
276 void* SqlStatement::next()
278 if (pData.getStmtType() == SelectStatement ) {
279 SelStatement *selStmt = (SelStatement*) stmt;
280 return( (void*) selStmt->next() );
282 else if(pData.getStmtType() == MetaStatement){
283 MetadataStatement *metaStmt = (MetadataStatement*) stmt;
284 return( (void*) metaStmt->next() );
286 else { return 0;}
289 bool SqlStatement::isFldNull(int pos)
291 if (pData.getStmtType() != SelectStatement) return 0;
292 SelStatement *selStmt = (SelStatement*) stmt;
293 return (selStmt->isFldNull(pos));
295 bool SqlStatement::isFldNull(char *name)
297 if (pData.getStmtType() != SelectStatement) return 0;
298 SelStatement *selStmt = (SelStatement*) stmt;
299 return (selStmt->isFldNull(name));
301 DbRetVal SqlStatement::close()
303 if (pData.getStmtType() == SelectStatement ) {
304 SelStatement *selStmt = (SelStatement*) stmt;
305 logFinest(Conf::logger,"CLOSE: %x", stmt);
306 return selStmt->close();
308 else if(pData.getStmtType() == MetaStatement){
309 MetadataStatement *selStmt = (MetadataStatement*) stmt;
310 logFinest(Conf::logger,"CLOSE: %x", stmt);
311 return selStmt->close();
313 else { return OK;}
316 void* SqlStatement::getParamValuePtr( int pos )
318 //if (pData.getStmtType() != SelectStatement) return 0;
319 DmlStatement *dmlStmt = (DmlStatement*) stmt;
320 return( (void*) dmlStmt->getParamValuePtr( pos ) );
323 char* SqlStatement::getFieldName( int pos )
325 if (pData.getStmtType() == SelectStatement ) {
326 SelStatement *selStmt = (SelStatement*) stmt;
327 return( (char*) selStmt->getFieldName( pos ) );
329 else if(pData.getStmtType() == MetaStatement){
330 MetadataStatement *selStmt = (MetadataStatement*) stmt;
331 return( (char*) selStmt->getFieldName( pos ) );
333 else { return 0;}
336 DataType SqlStatement::getFieldType( int pos )
338 if (pData.getStmtType() == SelectStatement ) {
339 SelStatement *selStmt = (SelStatement*) stmt;
340 return( (DataType) selStmt->getFieldType( pos ) );
342 else if(pData.getStmtType() == MetaStatement){
343 MetadataStatement *selStmt = (MetadataStatement*) stmt;
344 return( (DataType) selStmt->getFieldType( pos ) );
346 else { return typeUnknown;}
348 int SqlStatement::getFieldLength( int pos )
350 if (pData.getStmtType() == SelectStatement ) {
351 SelStatement *selStmt = (SelStatement*) stmt;
352 return( (int) selStmt->getFieldLength( pos ) );
354 else if(pData.getStmtType() == MetaStatement){
355 MetadataStatement *selStmt = (MetadataStatement*) stmt;
356 return( (int) selStmt->getFieldLength( pos ) );
358 else { return 0;}
361 void* SqlStatement::getFieldValuePtr( int pos )
363 if (pData.getStmtType() == SelectStatement ) {
364 SelStatement *selStmt = (SelStatement*) stmt;
365 return( (void*) selStmt->getFieldValuePtr( pos ) );
367 else if(pData.getStmtType() == MetaStatement){
368 MetadataStatement *selStmt = (MetadataStatement*) stmt;
369 return( (void*) selStmt->getFieldValuePtr( pos ) );
371 else { return 0;}
373 void* SqlStatement::getFieldValuePtr( char *name )
375 if (pData.getStmtType() == SelectStatement ) {
376 SelStatement *selStmt = (SelStatement*) stmt;
377 return( (void*) selStmt->getFieldValuePtr( name ) );
379 else if(pData.getStmtType() == MetaStatement){
380 MetadataStatement *selStmt = (MetadataStatement*) stmt;
381 return( (void*) selStmt->getFieldValuePtr( name ) );
383 else { return NULL;}
386 int SqlStatement::noOfProjFields()
388 if (pData.getStmtType() == SelectStatement ) {
389 SelStatement *selStmt = (SelStatement*) stmt;
390 return selStmt->noOfProjFields();
392 else if(pData.getStmtType() == MetaStatement){
393 MetadataStatement *selStmt = (MetadataStatement*) stmt;
394 return selStmt->noOfProjFields();
396 else { return 0;}
399 void SqlStatement::getProjFieldType(int *data)
401 if (pData.getStmtType() == SelectStatement ) {
402 SelStatement *selStmt = (SelStatement*) stmt;
403 return( selStmt->getProjFieldType(data) );
405 else if(pData.getStmtType() == MetaStatement){
406 MetadataStatement *selStmt = (MetadataStatement*) stmt;
407 return( selStmt->getProjFieldType(data) );
413 int SqlStatement::noOfParamFields()
415 return stmt->noOfParamFields();
418 DbRetVal SqlStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
420 DbRetVal rv = OK;
421 if (pData.getStmtType() == SelectStatement ) {
422 SelStatement *selStmt = (SelStatement*) stmt;
423 rv = selStmt->getProjFldInfo(projpos, fInfo);
425 else if(pData.getStmtType() == MetaStatement){
426 MetadataStatement *selStmt = (MetadataStatement*) stmt;
427 rv = selStmt->getProjFldInfo(projpos, fInfo);
428 } else { return ErrBadCall;}
429 return rv;
432 DbRetVal SqlStatement::getParamFldInfo (int parampos, FieldInfo *&fInfo)
434 DbRetVal rv = OK;
435 if (pData.getStmtType() ==SelectStatement ||
436 pData.getStmtType() ==InsertStatement ||
437 pData.getStmtType() ==UpdateStatement ||
438 pData.getStmtType() ==DeleteStatement)
441 DmlStatement *dmlStmt = (DmlStatement*) stmt;
442 rv = dmlStmt->getParamFldInfo(parampos, fInfo);
444 return rv;
447 DbRetVal SqlStatement::free()
449 logFinest(Conf::logger,"FREE: %x", stmt);
450 if (isCachedStmt) {
451 stmt=NULL;
452 pData.init();
453 isPrepd = false;
454 return OK;
456 if(stmt) delete stmt;
457 stmt = NULL;
458 pData.reset();
459 isMgmtStatement = false;
460 isPrepd = false;
461 return OK;
464 void SqlStatement::setNull(int pos)
466 stmt->setNull(pos);
468 void SqlStatement::setShortParam(int paramPos, short value)
470 stmt->setShortParam(paramPos, value);
472 void SqlStatement::setIntParam(int paramPos, int value)
474 stmt->setIntParam(paramPos, value);
476 void SqlStatement::setLongParam(int paramPos, long value)
478 stmt->setLongParam(paramPos, value);
480 void SqlStatement::setLongLongParam(int paramPos, long long value)
482 stmt->setLongLongParam(paramPos, value);
484 void SqlStatement::setByteIntParam(int paramPos, ByteInt value)
486 stmt->setByteIntParam(paramPos, value);
488 void SqlStatement::setFloatParam(int paramPos, float value)
490 stmt->setFloatParam(paramPos, value);
492 void SqlStatement::setDoubleParam(int paramPos, double value)
494 stmt->setDoubleParam(paramPos, value);
496 void SqlStatement::setStringParam(int paramPos, char *value)
498 stmt->setStringParam(paramPos, value);
500 void SqlStatement::setDateParam(int paramPos, Date value)
502 stmt->setDateParam(paramPos, value);
504 void SqlStatement::setTimeParam(int paramPos, Time value)
506 stmt->setTimeParam(paramPos, value);
508 void SqlStatement::setTimeStampParam(int paramPos, TimeStamp value)
510 stmt->setTimeStampParam(paramPos, value);
512 void SqlStatement::setBinaryParam(int paramPos, void *value, int length)
514 stmt->setBinaryParam(paramPos, value, length);
516 int SqlStatement::getFldPos(char *name)
518 return stmt->getFldPos(name);
520 List SqlStatement::getAllTableNames(DbRetVal &ret)
522 DatabaseManager *dbMgr = NULL;
523 List tbNmList;
524 dbMgr=sqlCon->getConnObject().getDatabaseManager();
525 int rv = ret;
526 if(dbMgr != NULL)
527 tbNmList = dbMgr->getAllTableNames(&rv);
528 ret = (DbRetVal) rv;
529 return tbNmList;
532 List SqlStatement::getAllUserNames(DbRetVal &ret)
534 UserManager *urMgr = NULL;
535 List urNmList;
536 urMgr=sqlCon->getConnObject().getUserManager();
537 int rv = ret;
538 if(urMgr != NULL)
539 urNmList = urMgr->getAllUserNames(&rv);
540 ret = (DbRetVal) rv;
541 return urNmList;
543 List SqlStatement::getFieldNameList(const char *tblName)
545 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
546 Table *table = dbMgr->openTable(tblName);
547 List fldNameList = table->getFieldNameList();
548 dbMgr->closeTable(table);
549 return fldNameList;
551 DbRetVal SqlStatement::getFieldInfo(const char *tblName, const char *fldName, FieldInfo *&info)
553 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
554 Table *table = dbMgr->openTable(tblName);
555 DbRetVal rv = table->getFieldInfo(fldName, info);
556 dbMgr->closeTable(table);
557 return OK;
559 void SqlStatement::setLoading(bool flag)
561 if (pData.getStmtType() == InsertStatement||
562 pData.getStmtType() == UpdateStatement||
563 pData.getStmtType() == DeleteStatement)
565 DmlStatement *dmlStmt = (DmlStatement*) stmt;
566 dmlStmt->setLoading(flag);
568 return;
571 int SqlStatement::getNoOfPagesForTable(char *tblName)
573 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
574 DatabaseManagerImpl *dbMgrImpl = (DatabaseManagerImpl *)dbMgr;
575 return dbMgrImpl->getNoOfPagesForTable(tblName);
578 DbRetVal SqlStatement::loadRecords(char *tblName, void *buf)
580 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
581 DatabaseManagerImpl *dbMgrImpl = (DatabaseManagerImpl *)dbMgr;
582 return dbMgrImpl->loadRecords(tblName, (char *) buf);
585 DbRetVal SqlStatement::pasteRecords(char *tblName, void *buffer)
587 DatabaseManager *dbMgr = sqlCon->getConnObject().getDatabaseManager();
588 DatabaseManagerImpl *dbMgrImpl = (DatabaseManagerImpl *)dbMgr;
589 return dbMgrImpl->pasteRecords(tblName, buffer);
591 void SqlStatement::flushCacheStmt()
593 return sqlCon->flushCacheStmt();
595 //-------------------------------------------------------------------
596 void SqlConnection::flushCacheStmt()
598 ListIterator iter = cachedStmts.getIterator();
599 while (iter.hasElement()) {
600 CachedStmtNode* node = (CachedStmtNode*) iter.nextElement();
601 free(node->sqlString);
602 node->sqlStmt->setCachedStmt(false);
603 node->sqlStmt->free();
604 delete node->sqlStmt;
605 delete node;
607 cachedStmts.reset();
608 return;
611 SqlStatement* SqlConnection::findInCache(char *stmtstr)
613 ListIterator iter = cachedStmts.getIterator();
614 int inputStmtLen = strlen(stmtstr);
615 CachedStmtNode *node = NULL;
616 while ((node = (CachedStmtNode*)iter.nextElement()) != NULL)
618 if (node->stmtLength == inputStmtLen)
620 if (0 == strcmp(node->sqlString, stmtstr))
622 logFiner(Conf::logger, "Statement Retrieved From Cache %x\n",
623 node->sqlStmt);
624 return node->sqlStmt;
628 return NULL;
630 void SqlConnection::addToCache(SqlStatement *sqlStmt, char* stmtString)
632 SqlStatement *stmt = new SqlStatement();
633 *stmt= *sqlStmt;
634 CachedStmtNode *node = new CachedStmtNode();
635 node->sqlStmt = stmt;
636 node->stmtLength = strlen(stmtString);
637 node->sqlString = (char*)malloc(node->stmtLength+1);
638 strcpy(node->sqlString, stmtString);
639 cachedStmts.append(node);
640 logFiner(Conf::logger, "Statement added To Cache %x\n", node->sqlStmt);
641 return ;
643 SqlConnection::~SqlConnection()
645 innerConn = NULL;
646 flushCacheStmt();
647 if (isConnOpen) disconnect();