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
;
29 bool SqlConnection::isInit
= false;
30 #if (defined MMDB && defined EMBED)
31 bool SqlConnection::firstThread
= false;
32 GlobalUniqueID
SqlConnection::UID
;
34 List
SqlConnection::connList
;
37 SqlStatement::~SqlStatement()
39 if (isPrepd
) { free(); isPrepd
= false; }
42 List
SqlStatement::getTableNameList()
44 return pData
.getTableNameList();
46 SqlStatement::SqlStatement()
53 isMgmtStatement
= false;
55 void SqlStatement::setConnection(AbsSqlConnection
*conn
)
57 sqlCon
= (SqlConnection
*)conn
;
61 void SqlStatement::setSqlConnection(SqlConnection
*conn
)
66 DbRetVal
SqlStatement::executeDirect(char *str
)
71 if (rv
!= OK
) return rv
;
73 if (rv
!= OK
) return rv
;
77 DbRetVal
SqlStatement::prepare(char *stmtstr
)
80 if (! sqlCon
->isConnectionOpen()) {
81 printError(ErrNotOpen
, "Connection not open");
84 SqlStatement
*cachedStmt
= sqlCon
->findInCache(stmtstr
);
88 this->stmt
->setParsedData(&this->pData
);
89 logFine(Conf::logger
,"GOT STMT FROM CACHE: %s %x", stmtstr
, cachedStmt
);
93 int ret
= ProcessManager::prepareMutex
.tryLock(10, 1000);
96 printError(ErrLockTimeOut
, "Unable to get prepare mutex");
97 return ErrLockTimeOut
;
100 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
101 if (isPrepared()) free();
105 yy_buffer_state
*yy_buffer
= yy_scan_string(stmtstr
);
107 if (yy_buffer
) yy_delete_buffer(yy_buffer
);
112 ProcessManager::prepareMutex
.releaseLock(-1, false);
113 return ErrSyntaxError
;
115 if( parsedData
->getStmtType() == MgmtStatement
)
119 isMgmtStatement
= true;
120 ProcessManager::prepareMutex
.releaseLock(-1, false);
121 logFine(Conf::logger
,"PREPARE: %s %x", stmtstr
, stmt
);
124 stmt
= StatementFactory::getStatement(parsedData
);
125 stmt
->setDbMgr(dbMgr
);
126 if( parsedData
->getStmtType() == UserStatement
)
128 UserManager
* userMgr
= sqlCon
->getConnObject().getUserManager();
129 UserTblStatement
*ustmt
= (UserTblStatement
*)stmt
;
130 ustmt
->setUserManager(userMgr
,sqlCon
->getConnObject().getUserName());
132 rv
= stmt
->resolve();
137 ProcessManager::prepareMutex
.releaseLock(-1, false);
141 if (Conf::config
.getStmtCacheSize()) {
142 if (stmt
->noOfParamFields() > 0) {
144 sqlCon
->addToCache(this, stmtstr
);
145 }else if (Conf::config
.useCacheNoParam())
147 if (parsedData
->getCacheWorthy())
150 sqlCon
->addToCache(this, stmtstr
);
155 ProcessManager::prepareMutex
.releaseLock(-1, false);
159 char* SqlStatement::getTableName()
161 return pData
.getTableName();
164 bool SqlStatement::isSelect()
166 if ((pData
.getStmtType() == SelectStatement
) || (pData
.getStmtType() == MetaStatement
)) return true;
170 bool SqlStatement::isPrepared() { return isPrepd
; }
172 DbRetVal
SqlStatement::execute(int &rowsAffected
)
175 if (! sqlCon
->isConnectionOpen()) {
176 printError(ErrNotOpen
, "Connection not open");
179 if (! isPrepared()) {
180 printError(ErrNotPrepared
, "Statement Not Prepared");
181 return ErrNotPrepared
;
183 if( isMgmtStatement
)
186 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
189 rv
= stmt
->execute(rowsAffected
);
190 if (rv
== ErrAlready
&& pData
.getStmtType() == SelectStatement
)
191 { //if previous scan is not closed, close it
192 SelStatement
*selStmt
= (SelStatement
*) stmt
;
194 rv
= stmt
->execute(rowsAffected
);
196 logFiner(Conf::logger
,"EXECUTE: %x", stmt
);
200 void* SqlStatement::fetch()
202 if (! sqlCon
->isConnectionOpen()) {
203 printError(ErrNotOpen
, "Connection not open");
206 if (! isPrepared()) {
207 printError(ErrNotPrepared
, "Statement Not Prepared");
210 if (pData
.getStmtType() == SelectStatement
) {
211 SelStatement
*selStmt
= (SelStatement
*) stmt
;
212 return selStmt
->fetch();
214 else if(pData
.getStmtType() == MetaStatement
){
215 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
216 return metaStmt
->fetch();
221 void* SqlStatement::fetch(DbRetVal
&rv
)
223 if (! sqlCon
->isConnectionOpen()) {
224 printError(ErrNotOpen
, "Connection not open");
225 rv
= ErrNoConnection
;
228 if (! isPrepared()) {
229 printError(ErrNotPrepared
, "Statement Not Prepared");
232 if (pData
.getStmtType() == SelectStatement
) {
233 SelStatement
*selStmt
= (SelStatement
*) stmt
;
234 return selStmt
->fetch(rv
);
236 else if(pData
.getStmtType() == MetaStatement
){
237 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
238 return metaStmt
->fetch(rv
);
243 void* SqlStatement::fetchAndPrint(bool SQL
)
245 if (! sqlCon
->isConnectionOpen()) {
246 printError(ErrNotOpen
, "Connection not open");
249 if (! isPrepared()) {
250 printError(ErrNotPrepared
, "Statement Not Prepared");
253 if (pData
.getStmtType() != SelectStatement
) return NULL
;
254 SelStatement
*selStmt
= (SelStatement
*) stmt
;
255 return selStmt
->fetchAndPrint(SQL
);
258 DbRetVal
SqlStatement::bindParam(int pos
, void* value
)
261 rv
= stmt
->setParam(pos
, value
);
265 DbRetVal
SqlStatement::bindField(int pos
, void* value
)
268 if (pData
.getStmtType() == SelectStatement
) {
269 SelStatement
*selStmt
= (SelStatement
*) stmt
;
270 return selStmt
->setBindField(pos
, value
);
272 else if(pData
.getStmtType() == MetaStatement
){
273 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
274 return metaStmt
->setBindField(pos
, value
);
276 else { return ErrBadCall
;}
278 void* SqlStatement::next()
280 if (pData
.getStmtType() == SelectStatement
) {
281 SelStatement
*selStmt
= (SelStatement
*) stmt
;
282 return( (void*) selStmt
->next() );
284 else if(pData
.getStmtType() == MetaStatement
){
285 MetadataStatement
*metaStmt
= (MetadataStatement
*) stmt
;
286 return( (void*) metaStmt
->next() );
291 bool SqlStatement::isFldNull(int pos
)
293 if (pData
.getStmtType() != SelectStatement
) return 0;
294 SelStatement
*selStmt
= (SelStatement
*) stmt
;
295 return (selStmt
->isFldNull(pos
));
297 bool SqlStatement::isFldNull(char *name
)
299 if (pData
.getStmtType() != SelectStatement
) return 0;
300 SelStatement
*selStmt
= (SelStatement
*) stmt
;
301 return (selStmt
->isFldNull(name
));
303 DbRetVal
SqlStatement::close()
305 if (pData
.getStmtType() == SelectStatement
) {
306 SelStatement
*selStmt
= (SelStatement
*) stmt
;
307 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
308 return selStmt
->close();
310 else if(pData
.getStmtType() == MetaStatement
){
311 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
312 logFinest(Conf::logger
,"CLOSE: %x", stmt
);
313 return selStmt
->close();
318 void* SqlStatement::getParamValuePtr( int pos
)
320 //if (pData.getStmtType() != SelectStatement) return 0;
321 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
322 return( (void*) dmlStmt
->getParamValuePtr( pos
) );
325 char* SqlStatement::getFieldName( int pos
)
327 if (pData
.getStmtType() == SelectStatement
) {
328 SelStatement
*selStmt
= (SelStatement
*) stmt
;
329 return( (char*) selStmt
->getFieldName( pos
) );
331 else if(pData
.getStmtType() == MetaStatement
){
332 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
333 return( (char*) selStmt
->getFieldName( pos
) );
338 DataType
SqlStatement::getFieldType( int pos
)
340 if (pData
.getStmtType() == SelectStatement
) {
341 SelStatement
*selStmt
= (SelStatement
*) stmt
;
342 return( (DataType
) selStmt
->getFieldType( pos
) );
344 else if(pData
.getStmtType() == MetaStatement
){
345 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
346 return( (DataType
) selStmt
->getFieldType( pos
) );
348 else { return typeUnknown
;}
350 int SqlStatement::getFieldLength( int pos
)
352 if (pData
.getStmtType() == SelectStatement
) {
353 SelStatement
*selStmt
= (SelStatement
*) stmt
;
354 return( (int) selStmt
->getFieldLength( pos
) );
356 else if(pData
.getStmtType() == MetaStatement
){
357 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
358 return( (int) selStmt
->getFieldLength( pos
) );
363 void* SqlStatement::getFieldValuePtr( int pos
)
365 if (pData
.getStmtType() == SelectStatement
) {
366 SelStatement
*selStmt
= (SelStatement
*) stmt
;
367 return( (void*) selStmt
->getFieldValuePtr( pos
) );
369 else if(pData
.getStmtType() == MetaStatement
){
370 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
371 return( (void*) selStmt
->getFieldValuePtr( pos
) );
375 void* SqlStatement::getFieldValuePtr( char *name
)
377 if (pData
.getStmtType() == SelectStatement
) {
378 SelStatement
*selStmt
= (SelStatement
*) stmt
;
379 return( (void*) selStmt
->getFieldValuePtr( name
) );
381 else if(pData
.getStmtType() == MetaStatement
){
382 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
383 return( (void*) selStmt
->getFieldValuePtr( name
) );
388 int SqlStatement::noOfProjFields()
390 if (pData
.getStmtType() == SelectStatement
) {
391 SelStatement
*selStmt
= (SelStatement
*) stmt
;
392 return selStmt
->noOfProjFields();
394 else if(pData
.getStmtType() == MetaStatement
){
395 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
396 return selStmt
->noOfProjFields();
401 void SqlStatement::getProjFieldType(int *data
)
403 if (pData
.getStmtType() == SelectStatement
) {
404 SelStatement
*selStmt
= (SelStatement
*) stmt
;
405 return( selStmt
->getProjFieldType(data
) );
407 else if(pData
.getStmtType() == MetaStatement
){
408 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
409 return( selStmt
->getProjFieldType(data
) );
415 int SqlStatement::noOfParamFields()
417 return stmt
->noOfParamFields();
420 DbRetVal
SqlStatement::getProjFldInfo (int projpos
, FieldInfo
*&fInfo
)
423 if (pData
.getStmtType() == SelectStatement
) {
424 SelStatement
*selStmt
= (SelStatement
*) stmt
;
425 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
427 else if(pData
.getStmtType() == MetaStatement
){
428 MetadataStatement
*selStmt
= (MetadataStatement
*) stmt
;
429 rv
= selStmt
->getProjFldInfo(projpos
, fInfo
);
430 } else { return ErrBadCall
;}
434 DbRetVal
SqlStatement::getParamFldInfo (int parampos
, FieldInfo
*&fInfo
)
437 if (pData
.getStmtType() ==SelectStatement
||
438 pData
.getStmtType() ==InsertStatement
||
439 pData
.getStmtType() ==UpdateStatement
||
440 pData
.getStmtType() ==DeleteStatement
)
443 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
444 rv
= dmlStmt
->getParamFldInfo(parampos
, fInfo
);
449 DbRetVal
SqlStatement::free()
451 logFinest(Conf::logger
,"FREE: %x", stmt
);
458 if(stmt
) delete stmt
;
461 isMgmtStatement
= false;
466 void SqlStatement::setNull(int pos
)
470 void SqlStatement::setShortParam(int paramPos
, short value
)
472 stmt
->setShortParam(paramPos
, value
);
474 void SqlStatement::setIntParam(int paramPos
, int value
)
476 stmt
->setIntParam(paramPos
, value
);
478 void SqlStatement::setLongParam(int paramPos
, long value
)
480 stmt
->setLongParam(paramPos
, value
);
482 void SqlStatement::setLongLongParam(int paramPos
, long long value
)
484 stmt
->setLongLongParam(paramPos
, value
);
486 void SqlStatement::setByteIntParam(int paramPos
, ByteInt value
)
488 stmt
->setByteIntParam(paramPos
, value
);
490 void SqlStatement::setFloatParam(int paramPos
, float value
)
492 stmt
->setFloatParam(paramPos
, value
);
494 void SqlStatement::setDoubleParam(int paramPos
, double value
)
496 stmt
->setDoubleParam(paramPos
, value
);
498 void SqlStatement::setStringParam(int paramPos
, char *value
)
500 stmt
->setStringParam(paramPos
, value
);
502 void SqlStatement::setDateParam(int paramPos
, Date value
)
504 stmt
->setDateParam(paramPos
, value
);
506 void SqlStatement::setTimeParam(int paramPos
, Time value
)
508 stmt
->setTimeParam(paramPos
, value
);
510 void SqlStatement::setTimeStampParam(int paramPos
, TimeStamp value
)
512 stmt
->setTimeStampParam(paramPos
, value
);
514 void SqlStatement::setBinaryParam(int paramPos
, void *value
, int length
)
516 stmt
->setBinaryParam(paramPos
, value
, length
);
518 int SqlStatement::getFldPos(char *name
)
520 return stmt
->getFldPos(name
);
522 long long SqlStatement::getLastInsertedVal(DbRetVal
&rv
)
524 return stmt
->getLastInsertedVal(rv
);
526 List
SqlStatement::getAllTableNames(DbRetVal
&ret
)
528 DatabaseManager
*dbMgr
= NULL
;
530 dbMgr
=sqlCon
->getConnObject().getDatabaseManager();
533 tbNmList
= dbMgr
->getAllTableNames(&rv
);
538 List
SqlStatement::getAllUserNames(DbRetVal
&ret
)
540 UserManager
*urMgr
= NULL
;
542 urMgr
=sqlCon
->getConnObject().getUserManager();
545 urNmList
= urMgr
->getAllUserNames(&rv
);
549 List
SqlStatement::getFieldNameList(const char *tblName
)
551 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
552 Table
*table
= dbMgr
->openTable(tblName
);
555 printError(ErrLockTimeOut
, "Unable to open table %s", 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
);
567 printError(ErrLockTimeOut
, "Unable to open table %s", tblName
);
568 return ErrLockTimeOut
;
570 DbRetVal rv
= table
->getFieldInfo(fldName
, info
);
571 dbMgr
->closeTable(table
);
574 void SqlStatement::setLoading(bool flag
)
576 if (pData
.getStmtType() == InsertStatement
||
577 pData
.getStmtType() == UpdateStatement
||
578 pData
.getStmtType() == DeleteStatement
)
580 DmlStatement
*dmlStmt
= (DmlStatement
*) stmt
;
581 dmlStmt
->setLoading(flag
);
586 int SqlStatement::getNoOfPagesForTable(char *tblName
)
588 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
589 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
590 return dbMgrImpl
->getNoOfPagesForTable(tblName
);
593 DbRetVal
SqlStatement::loadRecords(char *tblName
, void *buf
)
595 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
596 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
597 return dbMgrImpl
->loadRecords(tblName
, (char *) buf
);
600 DbRetVal
SqlStatement::pasteRecords(char *tblName
, void *buffer
)
602 DatabaseManager
*dbMgr
= sqlCon
->getConnObject().getDatabaseManager();
603 DatabaseManagerImpl
*dbMgrImpl
= (DatabaseManagerImpl
*)dbMgr
;
604 return dbMgrImpl
->pasteRecords(tblName
, buffer
);
606 void SqlStatement::flushCacheStmt()
608 return sqlCon
->flushCacheStmt();
610 //-------------------------------------------------------------------
612 static void sigTermHandler(int sig
)
614 ListIterator iter
= SqlConnection::connList
.getIterator();
615 SqlConnection
*conn
= NULL
;
616 while (iter
.hasElement())
618 conn
= (SqlConnection
*) iter
.nextElement();
619 conn
->flushCacheStmt();
620 if (conn
->isConnectionOpen()) conn
->disconnect();
625 DbRetVal
SqlConnection::connect (char *user
, char * pass
)
627 DbRetVal ret
= conn
.open(user
, pass
);
628 if (ret
!= OK
) return ret
;
629 if (ret
== OK
) isConnOpen
= true;
630 if (!isInit
) initialize();
631 connList
.append(this);
633 #if (defined MMDB && EMBED)
634 os::signal(SIGINT
, sigTermHandler
);
635 os::signal(SIGTERM
, sigTermHandler
);
636 if (Conf::config
.useDurability() && !firstThread
) {
637 rv
= recoverCsqlDB();
639 printError(ErrSysInternal
, "Recovery Failed");
644 rollback(); //for drop table execute in redo log
649 void SqlConnection::flushCacheStmt()
651 ListIterator iter
= cachedStmts
.getIterator();
652 while (iter
.hasElement()) {
653 CachedStmtNode
* node
= (CachedStmtNode
*) iter
.nextElement();
654 free(node
->sqlString
);
655 node
->sqlStmt
->setCachedStmt(false);
656 node
->sqlStmt
->free();
657 delete node
->sqlStmt
;
664 SqlStatement
* SqlConnection::findInCache(char *stmtstr
)
666 ListIterator iter
= cachedStmts
.getIterator();
667 int inputStmtLen
= strlen(stmtstr
);
668 CachedStmtNode
*node
= NULL
;
669 while ((node
= (CachedStmtNode
*)iter
.nextElement()) != NULL
)
671 if (node
->stmtLength
== inputStmtLen
)
673 if (0 == strcmp(node
->sqlString
, stmtstr
))
675 logFiner(Conf::logger
, "Statement Retrieved From Cache %x\n",
678 return node
->sqlStmt
;
684 void SqlConnection::addToCache(SqlStatement
*sqlStmt
, char* stmtString
)
686 SqlStatement
*stmt
= new SqlStatement();
688 CachedStmtNode
*node
= new CachedStmtNode();
689 node
->sqlStmt
= stmt
;
690 node
->stmtLength
= strlen(stmtString
);
691 node
->sqlString
= (char*)malloc(node
->stmtLength
+1);
692 strcpy(node
->sqlString
, stmtString
);
693 if (cachedStmts
.size() >= Conf::config
.getStmtCacheSize())
697 cachedStmts
.append(node
);
698 logFiner(Conf::logger
, "Statement added To Cache %x\n", node
->sqlStmt
);
699 logFinest(Conf::logger
, "Statement added To Cache %s\n", node
->sqlString
);
702 void SqlConnection::removeLeastUsed()
704 ListIterator iter
= cachedStmts
.getIterator();
705 CachedStmtNode
*node
= NULL
, *toRemove
=NULL
;
707 bool firstCall
= true;
708 while((node
= (CachedStmtNode
*) iter
.nextElement()) != NULL
)
712 lowHits
= node
->hits
;
713 toRemove
= node
; //if cache size is 1
716 if (lowHits
>= node
->hits
) toRemove
= node
;
718 cachedStmts
.remove(toRemove
);
719 logFiner(Conf::logger
, "Statement removed from Cache %x\n", toRemove
->sqlStmt
);
720 logFinest(Conf::logger
, "Statement removed from Cache %s\n", toRemove
->sqlString
);
723 SqlConnection::~SqlConnection()
727 if (isConnOpen
) disconnect();
729 static void sigUsr1Handler(int sig
)
731 ListIterator iter
= SqlConnection::connList
.getIterator();
732 SqlConnection
*conn
= NULL
;
733 while (iter
.hasElement())
735 conn
= (SqlConnection
*) iter
.nextElement();
736 conn
->flushCacheStmt();
738 os::signal(SIGCSQL1
, sigUsr1Handler
);
742 static void exithandler(void)
744 ListIterator iter
= SqlConnection::connList
.getIterator();
745 SqlConnection
*conn
= NULL
;
746 while (iter
.hasElement())
748 conn
= (SqlConnection
*) iter
.nextElement();
749 conn
->flushCacheStmt();
754 void SqlConnection::initialize()
756 os::signal(SIGCSQL1
, sigUsr1Handler
);
757 #if (defined MMDB && defined EMBED)
758 os::atexit(exithandler
);
763 #if (defined MMDB && defined EMBED)
764 DbRetVal
SqlConnection::recoverCsqlDB()
767 char dbRedoFileName
[MAX_FILE_LEN
];
768 char dbChkptSchema
[MAX_FILE_LEN
];
769 char dbChkptMap
[MAX_FILE_LEN
];
770 char dbChkptData
[MAX_FILE_LEN
];
771 char dbBackupFile
[MAX_FILE_LEN
];
772 char cmd
[IDENTIFIER_LENGTH
];
773 //check for check point file if present recover
774 sprintf(dbChkptSchema
, "%s/db.chkpt.schema1", Conf::config
.getDbFile());
775 if (FILE *file
= fopen(dbChkptSchema
, "r")) {
777 sprintf(cmd
, "cp -f %s %s/db.chkpt.schema", dbChkptSchema
,
778 Conf::config
.getDbFile());
779 int ret
= system(cmd
);
780 if (ret
!= 0) return ErrOS
;
782 sprintf(dbChkptMap
, "%s/db.chkpt.map1", Conf::config
.getDbFile());
783 if (FILE *file
= fopen(dbChkptMap
, "r")) {
785 sprintf(cmd
, "cp -f %s %s/db.chkpt.map", dbChkptMap
,
786 Conf::config
.getDbFile());
787 int ret
= system(cmd
);
788 if (ret
!= 0) return ErrOS
;
790 int chkptID
= Database::getCheckpointID();
791 sprintf(dbChkptData
, "%s/db.chkpt.data%d", Conf::config
.getDbFile(),
793 sprintf(dbBackupFile
, "%s/db.chkpt.data1", Conf::config
.getDbFile());
795 if (!Conf::config
.useMmap() && (fl
= fopen(dbBackupFile
, "r"))) {
797 sprintf(cmd
, "cp %s/db.chkpt.data1 %s", Conf::config
.getDbFile(),
799 int ret
= system(cmd
);
800 if (ret
!= 0) return ErrOS
;
802 if (FILE *file
= fopen(dbChkptData
, "r")) {
804 rv
= recoverSystemAndUserDB();
807 //check for redo log file if present apply redo logs
808 sprintf(dbRedoFileName
, "%s/csql.db.cur", Conf::config
.getDbFile());
809 if (FILE *file
= fopen(dbRedoFileName
, "r"))
812 applyRedoLogs(dbRedoFileName
);
813 DatabaseManager
*dbMgr
= getConnObject().getDatabaseManager();
814 rv
= dbMgr
->checkPoint();
817 printError(ErrSysInternal
, "checkpoint failed after redo log apply");
824 DbRetVal
SqlConnection::recoverSystemAndUserDB()
828 sprintf(schFile
, "%s/db.chkpt.schema", Conf::config
.getDbFile());
829 if (FILE *file
= fopen(schFile
, "r")) {
830 applySchemaFile(file
);
832 DatabaseManager
*dbMgr
= getConnObject().getDatabaseManager();
837 DbRetVal
SqlConnection::applySchemaFile(FILE *fp
)
841 SqlStatement
*stmt
= new SqlStatement();
842 while ((eof
= getQueryFromSchemaFile(fp
,buf
)) != EOF
) {
843 stmt
->setConnection(this);
852 char SqlConnection::getQueryFromSchemaFile(FILE *fp
, char *buf
)
854 char c
, *bufBegin
=buf
;
856 while( (c
=(char ) fgetc(fp
)) != EOF
&& c
!= ';')
858 *buf
++ = c
; charCnt
++;
859 if( charCnt
== SQL_STMT_LEN
) {
860 printf("SQL Statement length is greater than %d. "
861 "Ignoring the statement.\n", SQL_STMT_LEN
);
872 void SqlConnection::addToHashTable(int stmtID
, AbsSqlStatement
* sHdl
)
874 int bucketNo
= stmtID
% STMT_BUCKET_SIZE
;
875 StmtBucket
*buck
= (StmtBucket
*) stmtBuckets
;
876 StmtBucket
*stmtBucket
= &buck
[bucketNo
];
877 StmtNode
*node
= new StmtNode();
878 node
->stmtId
= stmtID
;
880 stmtBucket
->bucketList
.append(node
);
884 void SqlConnection::removeFromHashTable(int stmtID
)
886 int bucketNo
= stmtID
% STMT_BUCKET_SIZE
;
887 StmtBucket
*buck
= (StmtBucket
*) stmtBuckets
;
888 StmtBucket
*stmtBucket
= &buck
[bucketNo
];
889 StmtNode
*node
= NULL
;
890 ListIterator it
= stmtBucket
->bucketList
.getIterator();
891 while(it
.hasElement()) {
892 node
= (StmtNode
*) it
.nextElement();
893 if(stmtID
== node
->stmtId
) break;
896 stmtBucket
->bucketList
.remove(node
);
900 AbsSqlStatement
*SqlConnection::getStmtFromHashTable(int stmtId
)
902 int bucketNo
= stmtId
% STMT_BUCKET_SIZE
;
903 StmtBucket
*buck
= (StmtBucket
*) stmtBuckets
;
904 StmtBucket
*stmtBucket
= &buck
[bucketNo
];
905 StmtNode
*node
= NULL
;
906 ListIterator it
= stmtBucket
->bucketList
.getIterator();
907 while(it
.hasElement()) {
908 node
= (StmtNode
*) it
.nextElement();
909 if(stmtId
== node
->stmtId
) {
916 void setParam(AbsSqlStatement
*stmt
, int pos
, DataType type
, int length
, void *value
)
921 stmt
->setIntParam(pos
, *(int*)value
);
924 stmt
->setLongParam(pos
, *(long*) value
);
927 stmt
->setLongLongParam(pos
, *(long long*)value
);
930 stmt
->setShortParam(pos
, *(short*)value
);
933 stmt
->setByteIntParam(pos
, *(ByteInt
*)value
);
936 stmt
->setDoubleParam(pos
, *(double*)value
);
939 stmt
->setFloatParam(pos
, *(float*)value
);
942 stmt
->setDateParam(pos
, *(Date
*)value
);
945 stmt
->setTimeParam(pos
, *(Time
*)value
);
948 stmt
->setTimeStampParam(pos
, *(TimeStamp
*)value
);
952 stmt
->setStringParam(pos
, (char*)value
);
955 stmt
->setBinaryParam(pos
, value
, length
);
958 printf("unknown type\n");
964 int SqlConnection::applyRedoLogs(char *redoFile
)
968 int fd
= open(redoFile
, O_RDONLY
);
969 if (-1 == fd
) { return OK
; }
970 if (fstat(fd
, &st
) == -1) {
971 printError(ErrSysInternal
, "Unable to retrieve undo log file size");
975 if (st
.st_size
==0) {
979 void *startAddr
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
980 if (MAP_FAILED
== startAddr
) {
981 printf("Unable to read undo log file:mmap failed.\n");
984 stmtBuckets
= malloc (STMT_BUCKET_SIZE
* sizeof(StmtBucket
));
985 memset(stmtBuckets
, 0, STMT_BUCKET_SIZE
* sizeof(StmtBucket
));
987 char *iter
= (char*)startAddr
;
992 int len
, ret
, retVal
=0;
994 char stmtString
[SQL_STMT_LEN
];
995 //printf("size of file %d\n", st.st_size);
997 //printf("OFFSET HERE %d\n", iter - (char*)startAddr);
998 if (iter
- (char*)startAddr
>= st
.st_size
) break;
999 logType
= *(int*)iter
;
1000 if (logType
== -1) { //prepare
1001 iter
= iter
+ sizeof(int);
1002 txnID
= *(int*) iter
; iter
+= sizeof(int);
1003 loglen
= *(int*) iter
; iter
+= sizeof(int);
1004 stmtID
= *(int*)iter
;
1005 iter
= iter
+ sizeof(int);
1007 iter
= iter
+ sizeof(int);
1008 strncpy(stmtString
, iter
, len
);
1010 //printf("PREPARE:%d %d %s\n", stmtID, len, stmtString);
1011 AbsSqlStatement
*st
= SqlFactory::createStatement(CSqlDirect
);
1012 SqlStatement
*stmt
= (SqlStatement
*)st
;
1013 stmt
->setConnection(this);
1014 rv
= stmt
->prepare(stmtString
);
1016 printError(ErrSysInternal
, "unable to prepare stmt:%s", stmtString
);
1020 stmt
->prepare(stmtString
);
1021 SqlStatement
*sqlStmt
= (SqlStatement
*)stmt
;
1022 sqlStmt
->setLoading(true);
1023 addToHashTable(stmtID
, stmt
);
1025 else if(logType
== -2) { //commit
1027 iter
= iter
+ sizeof(int);
1028 txnID
= *(int*) iter
; iter
+= sizeof(int);
1029 loglen
= *(int*) iter
; iter
+= sizeof(int);
1030 char *curPtr
= iter
;
1032 //printf("Iter length %d\n", iter - curPtr);
1033 if (iter
- (char*)startAddr
>= st
.st_size
) {
1035 //printf("Redo log file end\n");
1039 stmtID
= *(int*)iter
;
1040 //printf("stmtid %d\n", stmtID);
1041 iter
= iter
+ sizeof(int);
1042 eType
= *(int*)iter
;
1043 //printf("eType is %d\n", eType);
1044 AbsSqlStatement
*stmt
= getStmtFromHashTable(stmtID
);
1045 if (0 == eType
) { //execute type
1046 iter
= iter
+ sizeof(int);
1047 //printf("EXEC: %d\n", stmtID);
1049 rv
= stmt
->execute(ret
);
1051 printError(ErrSysInternal
, "unable to execute");
1056 printError(ErrSysInternal
, "statement not found for %d\n",stmtID
);
1058 if (*(int*)iter
<0) break;
1059 } else if ( 1 == eType
) { //set type
1060 iter
=iter
+sizeof(int);
1061 int pos
= *(int*) iter
;
1062 iter
=iter
+sizeof(int);
1063 DataType type
= (DataType
)(*(int*)iter
);
1064 iter
=iter
+sizeof(int);
1065 int len
= *(int*) iter
;
1066 iter
=iter
+sizeof(int);
1068 //AllDataType::printVal(value, type, len);
1070 //printf("SET: %d %d %d %d\n", stmtID, pos, type, len);
1071 setParam(stmt
, pos
, type
, len
, value
);
1072 if (*(int*)iter
<0) break;
1077 else if(logType
== -3) { //free
1078 iter
= iter
+ sizeof(int);
1079 txnID
= *(int*) iter
; iter
+= sizeof(int);
1080 loglen
= *(int*) iter
; iter
+= sizeof(int);
1081 stmtID
= *(int*)iter
;
1082 iter
= iter
+ sizeof(int);
1083 AbsSqlStatement
*stmt
= getStmtFromHashTable(stmtID
);
1086 removeFromHashTable(stmtID
);
1087 } else { printError(ErrSysInternal
, "statement not found for %d\n",stmtID
);}
1089 else if(logType
== -4) { //prepare and execute
1090 iter
= iter
+ sizeof(int);
1091 txnID
= *(int*) iter
; iter
+= sizeof(int);
1092 loglen
= *(int*) iter
; iter
+= sizeof(int);
1093 stmtID
= *(int*)iter
;
1094 iter
= iter
+ sizeof(int);
1096 iter
= iter
+ sizeof(int);
1097 strncpy(stmtString
, iter
, len
);
1098 stmtString
[len
+1] ='\0';
1100 //printf("CREATE:%d %d %s\n", stmtID, len, stmtString);
1101 AbsSqlStatement
*stmt
= SqlFactory::createStatement(CSqlDirect
);
1102 if ( NULL
== stmt
) {
1103 printError(ErrSysInternal
, "unable to prepare:%s", stmtString
);
1107 stmt
->setConnection(this);
1108 rv
= stmt
->prepare(stmtString
);
1110 printError(ErrSysInternal
, "unable to prepare:%s", stmtString
);
1114 rv
= stmt
->execute(ret
);
1116 if (strlen(stmtString
) > 6 &&
1117 ( (strncasecmp(stmtString
,"CREATE", 6) == 0) ||
1118 (strncasecmp(stmtString
,"DROP", 4) == 0)) ) {
1119 // conn->disconnect();
1123 printError(ErrSysInternal
, "unable to execute %s", stmtString
);
1129 printError(ErrSysInternal
, "Redo log file corrupted: logType:%d", logType
);
1134 munmap((char*)startAddr
, st
.st_size
);
1136 //freeAllStmtHandles();