1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.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 ***************************************************************************/
17 #include <Statement.h>
18 #include <SqlFactory.h>
19 #include <SqlStatement.h>
21 AbsSqlConnection
*conn
;
22 void *stmtBuckets
= NULL
;
24 bool interactive
=false;
25 char fileName
[MAX_FILE_LEN
];
27 int main(int argc
, char **argv
)
32 while ((c
= getopt(argc
, argv
, "f:ail?")) != EOF
) {
34 case '?' : { opt
= 1; break; } //print help
35 case 'a' : { opt
= 2; break; }
36 case 'i' : { interactive
= true; break; }
37 case 'l' : { list
= true; break; }
38 case 'f' : {strcpy(fileName
, argv
[optind
- 1]); break;}
39 default: printf("Wrong args\n"); exit(1);
44 printf("This is an internal csql command with i and f <filename> options.");
47 char *verbose
= os::getenv("CSQL_INTERACTIVE");
48 if (verbose
!=NULL
&& strcmp(verbose
, "true") == 0)
50 printf("VERBOSE ON %s\n", verbose
);
54 conn
= SqlFactory::createConnection(CSqlDirect
);
55 DbRetVal rv
= conn
->connect(I_USER
, I_PASS
);
57 printError(ErrNoConnection
, "REDO: could not connect to DB.");
62 if (strcmp(fileName
, "") ==0) {
63 sprintf(fileName
, "%s/csql.db.cur", Conf::config
.getDbFile());
65 int fd
= open(fileName
, O_RDONLY
);
66 if (-1 == fd
) { conn
->disconnect(); delete conn
; return OK
; }
67 if (fstat(fd
, &st
) == -1) {
68 printError(ErrSysInternal
, "Unable to retrieve undo log file size");
75 printError(ErrNote
, "No Redo logs found during recovery");
76 SqlStatement::readAndPopulateStmts(conn
, stmtBuckets
, list
, interactive
);
82 SqlConnection
*sCon
= (SqlConnection
*) conn
;
83 if(!list
) rv
= sCon
->getExclusiveLock();
84 //during connection close, this exclusive lock will be automatically released
91 void *startAddr
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
92 if (MAP_FAILED
== startAddr
) {
93 printf("Unable to read undo log file:mmap failed.\n");
98 rv
= SqlStatement::readAndPopulateStmts(conn
, stmtBuckets
, list
, interactive
);
101 printf("Unable to read stmt log file\n");
107 printf("Redo log filename is :%s\n", fileName
);
108 char *iter
= (char*)startAddr
;
113 int len
, ret
, retVal
=0;
115 char stmtString
[SQL_STMT_LEN
];
116 //printf("size of file %d\n", st.st_size);
118 //printf("OFFSET HERE %d\n", iter - (char*)startAddr);
119 if (iter
- (char*)startAddr
>= st
.st_size
) break;
120 logType
= *(int*)iter
;
121 if (logType
== -1) { //prepare
122 iter
= iter
+ sizeof(int);
123 txnID
= *(int*) iter
; iter
+= sizeof(int);
124 loglen
= *(int*) iter
; iter
+= sizeof(int);
125 stmtID
= *(int*)iter
;
126 iter
= iter
+ sizeof(int);
128 iter
= iter
+ sizeof(int);
129 strncpy(stmtString
, iter
, len
);
132 printf("PREPARE: SID:%d %s\n", stmtID
, stmtString
);
135 AbsSqlStatement
*stmt
= SqlFactory::createStatement(CSqlDirect
);
136 stmt
->setConnection(conn
);
137 if (interactive
) printf("PREPARE %d : %s\n", stmtID
, stmtString
);
138 rv
= stmt
->prepare(stmtString
);
140 printError(ErrSysInternal
, "unable to prepare stmt:%s", stmtString
);
144 SqlStatement
*sqlStmt
= (SqlStatement
*)stmt
;
145 sqlStmt
->setLoading(true);
146 SqlStatement::addToHashTable(stmtID
, stmt
,stmtBuckets
, stmtString
);
148 else if(logType
== -2) { //commit
150 iter
= iter
+ sizeof(int);
151 txnID
= *(int*) iter
; iter
+= sizeof(int);
152 loglen
= *(int*) iter
; iter
+= sizeof(int);
155 //printf("Iter length %d\n", iter - curPtr);
156 if (iter
- (char*)startAddr
>= st
.st_size
) {
158 //printf("Redo log file end\n");
162 stmtID
= *(int*)iter
;
163 //printf("stmtid %d\n", stmtID);
164 if (interactive
) printf("EXEC %d :\n", stmtID
);
165 iter
= iter
+ sizeof(int);
167 //printf("eType is %d\n", eType);
168 AbsSqlStatement
*stmt
= NULL
;
170 stmt
= SqlStatement::getStmtFromHashTable(stmtID
,stmtBuckets
);
172 printError(ErrSysInternal
, "Unable to find in stmt hashtable");
177 if (0 == eType
) { //execute type
178 iter
= iter
+ sizeof(int);
180 printf("EXEC SID:%d TID:%d\n", stmtID
, txnID
);
181 if (*(int*)iter
<0) break;
185 rv
= stmt
->execute(ret
);
187 printError(ErrSysInternal
, "unable to execute");
192 printError(ErrSysInternal
, "statement not found for %d\n",stmtID
);
194 if (*(int*)iter
<0) break;
195 } else if ( 1 == eType
) { //set type
196 iter
=iter
+sizeof(int);
197 int pos
= *(int*) iter
;
198 iter
=iter
+sizeof(int);
199 int isNull
= *(int *) iter
;
200 iter
=iter
+sizeof(int);
202 DataType type
= (DataType
)(*(int*)iter
);
203 iter
=iter
+sizeof(int);
204 int len
= *(int*) iter
;
205 iter
=iter
+sizeof(int);
209 printf("SET SID:%d POS:%d ISNULL:FALSE TYPE:%d LEN:%d Value:", stmtID
, pos
, type
, len
);
210 AllDataType::printVal(value
, type
, len
);
212 if (*(int*)iter
<0) break;
215 SqlStatement::setParamValues(stmt
, pos
, type
, len
, value
);
218 printf("SET SID:%d POS:%d ISNULL:TRUE\n", stmtID
, pos
);
223 if (*(int*)iter
<0) break;
228 else if(logType
== -3) { //free
229 iter
= iter
+ sizeof(int);
230 txnID
= *(int*) iter
; iter
+= sizeof(int);
231 loglen
= *(int*) iter
; iter
+= sizeof(int);
232 stmtID
= *(int*)iter
;
233 iter
= iter
+ sizeof(int);
235 printf("FREE SID:%d \n", stmtID
);
238 if (interactive
) printf("FREE %d:\n", stmtID
);
239 AbsSqlStatement
*stmt
= SqlStatement::getStmtFromHashTable(stmtID
,
244 SqlStatement::removeFromHashTable(stmtID
,stmtBuckets
);
245 } else { printError(ErrSysInternal
, "statement not found for %d\n",stmtID
);}
247 else if(logType
== -4) { //prepare and execute
248 iter
= iter
+ sizeof(int);
249 txnID
= *(int*) iter
; iter
+= sizeof(int);
250 loglen
= *(int*) iter
; iter
+= sizeof(int);
251 stmtID
= *(int*)iter
;
252 iter
= iter
+ sizeof(int);
254 iter
= iter
+ sizeof(int);
255 strncpy(stmtString
, iter
, len
);
258 printf("EXECDIRECT SID:%d TID:%d STMT:%s\n", stmtID
, txnID
, stmtString
);
261 AbsSqlStatement
*stmt
= SqlFactory::createStatement(CSqlDirect
);
263 printError(ErrSysInternal
, "unable to prepare:%s", stmtString
);
267 stmt
->setConnection(conn
);
268 if (interactive
) printf("EXECDIRECT %d : %s\n", stmtID
, stmtString
);
269 rv
= stmt
->prepare(stmtString
);
271 printError(ErrSysInternal
, "unable to prepare:%s", stmtString
);
277 rv
= stmt
->execute(ret
);
279 if (strlen(stmtString
) > 6 &&
280 ( (strncasecmp(stmtString
,"CREATE", 6) == 0) ||
281 (strncasecmp(stmtString
,"DROP", 4) == 0) ||
282 (strncasecmp(stmtString
,"RENAME", 6) == 0) ||
283 (strncasecmp(stmtString
,"ALTER", 5) == 0)) ) {
285 // conn->disconnect();
289 printError(ErrSysInternal
, "unable to execute %s", stmtString
);
297 printError(ErrSysInternal
, "Redo log file corrupted: logType:%d", logType
);
302 munmap((char*)startAddr
, st
.st_size
);
305 SqlStatement::filterAndWriteStmtLogs(stmtBuckets
);
306 SqlStatement::freeAllStmtHandles(stmtBuckets
);