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>
20 #define SQL_STMT_LEN 1024
23 AbsSqlConnection
*conn
;
25 void addToHashTable(int stmtID
, AbsSqlStatement
* sHdl
)
27 int bucketNo
= stmtID
% STMT_BUCKET_SIZE
;
28 StmtBucket
*buck
= (StmtBucket
*) stmtBuckets
;
29 StmtBucket
*stmtBucket
= &buck
[bucketNo
];
30 StmtNode
*node
= new StmtNode();
31 node
->stmtId
= stmtID
;
33 stmtBucket
->bucketList
.append(node
);
36 void removeFromHashTable(int stmtID
)
38 int bucketNo
= stmtID
% STMT_BUCKET_SIZE
;
39 StmtBucket
*buck
= (StmtBucket
*) stmtBuckets
;
40 StmtBucket
*stmtBucket
= &buck
[bucketNo
];
41 StmtNode
*node
= NULL
;
42 ListIterator it
= stmtBucket
->bucketList
.getIterator();
43 while(it
.hasElement()) {
44 node
= (StmtNode
*) it
.nextElement();
45 if(stmtID
== node
->stmtId
) break;
48 stmtBucket
->bucketList
.remove(node
);
51 AbsSqlStatement
*getStmtFromHashTable(int stmtId
)
53 int bucketNo
= stmtId
% STMT_BUCKET_SIZE
;
54 StmtBucket
*buck
= (StmtBucket
*) stmtBuckets
;
55 StmtBucket
*stmtBucket
= &buck
[bucketNo
];
56 StmtNode
*node
= NULL
;
57 ListIterator it
= stmtBucket
->bucketList
.getIterator();
58 while(it
.hasElement()) {
59 node
= (StmtNode
*) it
.nextElement();
60 if(stmtId
== node
->stmtId
) {
66 void freeAllStmtHandles()
70 void setParam(AbsSqlStatement
*stmt
, int pos
, DataType type
, int length
, void *value
)
75 stmt
->setIntParam(pos
, *(int*)value
);
78 stmt
->setLongParam(pos
, *(long*) value
);
81 stmt
->setLongLongParam(pos
, *(long long*)value
);
84 stmt
->setShortParam(pos
, *(short*)value
);
87 stmt
->setByteIntParam(pos
, *(ByteInt
*)value
);
90 stmt
->setDoubleParam(pos
, *(double*)value
);
93 stmt
->setFloatParam(pos
, *(float*)value
);
96 stmt
->setDateParam(pos
, *(Date
*)value
);
99 stmt
->setTimeParam(pos
, *(Time
*)value
);
102 stmt
->setTimeStampParam(pos
, *(TimeStamp
*)value
);
105 stmt
->setStringParam(pos
, (char*)value
);
108 stmt
->setBinaryParam(pos
, value
, length
);
111 printf("unknown type\n");
117 int main(int argc
, char **argv
)
123 while ((c
= getopt(argc
, argv
, "ai?")) != EOF
) {
125 case '?' : { opt
= 1; break; } //print help
126 case 'a' : { opt
= 2; break; }
127 case 'i' : { interactive
= 1; break; }
128 default: printf("Wrong args\n"); exit(1);
133 printf("This is an internal csql command.");
136 Conf::config
.readAllValues(os::getenv("CSQL_CONFIG_FILE"));
137 sprintf(fileName
, "%s/csql.db.cur", Conf::config
.getDbFile());
138 printf("Redo log filename is :%s\n", fileName
);
139 int fd
= open(fileName
, O_RDONLY
);
140 if (-1 == fd
) { return OK
; }
141 if (fstat(fd
, &st
) == -1) {
142 printf("Unable to retrieve undo log file size\n");
146 if (st
.st_size
==0) {
147 printf("Nothing in redo log file\n");
151 conn
= SqlFactory::createConnection(CSqlDirect
);
152 DbRetVal rv
= conn
->connect(I_USER
, I_PASS
);
153 SqlConnection
*sCon
= (SqlConnection
*) conn
;
154 rv
= sCon
->getExclusiveLock();
161 void *startAddr
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
162 if (MAP_FAILED
== startAddr
) {
163 printf("Unable to read undo log file:mmap failed.\n");
168 stmtBuckets
= malloc (STMT_BUCKET_SIZE
* sizeof(StmtBucket
));
169 memset(stmtBuckets
, 0, STMT_BUCKET_SIZE
* sizeof(StmtBucket
));
171 char *iter
= (char*)startAddr
;
178 char stmtString
[1024];
179 //printf("size of file %d\n", st.st_size);
181 //printf("OFFSET HERE %d\n", iter - (char*)startAddr);
182 if (iter
- (char*)startAddr
>= st
.st_size
) break;
183 logType
= *(int*)iter
;
184 if (logType
== -1) { //prepare
185 iter
= iter
+ sizeof(int);
186 txnID
= *(int*) iter
; iter
+= sizeof(int);
187 loglen
= *(int*) iter
; iter
+= sizeof(int);
188 stmtID
= *(int*)iter
;
189 iter
= iter
+ sizeof(int);
191 iter
= iter
+ sizeof(int);
192 strncpy(stmtString
, iter
, len
);
194 //printf("PREPARE:%d %d %s\n", stmtID, len, stmtString);
195 AbsSqlStatement
*stmt
= SqlFactory::createStatement(CSqlDirect
);
196 stmt
->setConnection(conn
);
197 if (interactive
) printf("PREPARE %d : %s\n", stmtID
, stmtString
);
198 rv
= stmt
->prepare(stmtString
);
200 printf("unable to prepare\n");
204 stmt
->prepare(stmtString
);
205 SqlStatement
*sqlStmt
= (SqlStatement
*)stmt
;
206 sqlStmt
->setLoading(true);
207 addToHashTable(stmtID
, stmt
);
209 else if(logType
== -2) { //commit
211 iter
= iter
+ sizeof(int);
212 txnID
= *(int*) iter
; iter
+= sizeof(int);
213 loglen
= *(int*) iter
; iter
+= sizeof(int);
216 //printf("Iter length %d\n", iter - curPtr);
217 if (iter
- (char*)startAddr
>= st
.st_size
) {
219 //printf("Redo log file end\n");
221 freeAllStmtHandles();
223 munmap((char*)startAddr
, st
.st_size
);
228 stmtID
= *(int*)iter
;
229 //printf("stmtid %d\n", stmtID);
230 if (interactive
) printf("EXEC %d :\n", stmtID
);
231 iter
= iter
+ sizeof(int);
233 //printf("eType is %d\n", eType);
234 AbsSqlStatement
*stmt
= getStmtFromHashTable(stmtID
);
235 if (0 == eType
) { //execute type
236 iter
= iter
+ sizeof(int);
237 //printf("EXEC: %d\n", stmtID);
239 rv
= stmt
->execute(ret
);
241 //printf("execute failed\n");
246 printf("statement not found for %d\n",stmtID
);
248 if (*(int*)iter
<0) break;
249 } else if ( 1 == eType
) { //set type
250 iter
=iter
+sizeof(int);
251 int pos
= *(int*) iter
;
252 iter
=iter
+sizeof(int);
253 DataType type
= (DataType
)(*(int*)iter
);
254 iter
=iter
+sizeof(int);
255 int len
= *(int*) iter
;
256 iter
=iter
+sizeof(int);
258 //AllDataType::printVal(value, type, len);
260 //printf("SET: %d %d %d %d\n", stmtID, pos, type, len);
261 setParam(stmt
, pos
, type
, len
, value
);
262 if (*(int*)iter
<0) break;
267 else if(logType
== -3) { //free
268 iter
= iter
+ sizeof(int);
269 txnID
= *(int*) iter
; iter
+= sizeof(int);
270 loglen
= *(int*) iter
; iter
+= sizeof(int);
271 stmtID
= *(int*)iter
;
272 iter
= iter
+ sizeof(int);
273 if (interactive
) printf("FREE %d:\n", stmtID
);
274 AbsSqlStatement
*stmt
= getStmtFromHashTable(stmtID
);
277 removeFromHashTable(stmtID
);
278 } else { printf("statement not found for %d\n",stmtID
);}
280 else if(logType
== -4) { //prepare and execute
281 iter
= iter
+ sizeof(int);
282 txnID
= *(int*) iter
; iter
+= sizeof(int);
283 loglen
= *(int*) iter
; iter
+= sizeof(int);
284 stmtID
= *(int*)iter
;
285 iter
= iter
+ sizeof(int);
287 iter
= iter
+ sizeof(int);
288 strncpy(stmtString
, iter
, len
);
289 stmtString
[len
+1] ='\0';
291 //printf("CREATE:%d %d %s\n", stmtID, len, stmtString);
292 AbsSqlStatement
*stmt
= SqlFactory::createStatement(CSqlDirect
);
294 printf("unable to prepare\n");
298 stmt
->setConnection(conn
);
299 if (interactive
) printf("EXECDIRECT %d : %s\n", stmtID
, stmtString
);
300 rv
= stmt
->prepare(stmtString
);
302 printf("unable to prepare\n");
306 rv
= stmt
->execute(ret
);
308 if (strlen(stmtString
) > 6 &&
309 ( (strncasecmp(stmtString
,"CREATE", 6) == 0) ||
310 (strncasecmp(stmtString
,"DROP", 4) == 0)) ) {
311 // conn->disconnect();
315 printf("unable to execute\n");
322 munmap((char*)startAddr
, st
.st_size
);
324 freeAllStmtHandles();