reverting back the changes. causes core dump
[csql.git] / src / tools / applyofflinelogs.cxx
blobeda4e8fff98f288076f1e759bc7220a912d3693c
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.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 ***************************************************************************/
16 #include <os.h>
17 #include <Statement.h>
18 #include <SqlFactory.h>
19 #include <SqlStatement.h>
20 #define DEBUG 1
22 AbsSqlConnection *conn;
23 void *stmtBuckets;
25 int applyOfflinelogs(char *fileName, bool interactive);
27 int main(int argc, char **argv)
29 struct stat st;
30 char fileName[MAX_FILE_LEN];
31 int c = 0, opt=0;
32 bool interactive=0;
33 while ((c = getopt(argc, argv, "ai?")) != EOF) {
34 switch (c) {
35 case '?' : { opt = 1; break; } //print help
36 case 'a' : { opt = 2; break; }
37 case 'i' : { interactive = 1; break; }
38 default: printf("Wrong args\n"); exit(1);
41 }//while options
42 if (2 !=opt) {
43 printf("This is an internal csql command.");
44 exit(1);
46 Conf::config.readAllValues(os::getenv("CSQL_CONFIG_FILE"));
47 conn = SqlFactory::createConnection(CSqlAdapter);
48 DbRetVal rv = conn->connect(I_USER, I_PASS);
49 stmtBuckets = malloc (STMT_BUCKET_SIZE * sizeof(StmtBucket));
50 memset(stmtBuckets, 0, STMT_BUCKET_SIZE * sizeof(StmtBucket));
51 int counter=0;
52 while (true) {
53 sprintf(fileName, "%s/offlineLogFile.%d", Conf::config.getDbFile(),
54 counter);
55 if (::access(fileName, F_OK) != 0) break;
56 int retval = applyOfflinelogs(fileName, interactive);
57 if (retval) { return retval; }
58 printf("Applied logs from file: %s\n", fileName);
59 counter++;
61 printf("All the offline log files have been successfully applied.\n");
62 counter = 0;
63 char cmd[128];
64 while (true) {
65 sprintf(fileName,"%s/offlineLogFile.%d",Conf::config.getDbFile(),
66 counter);
67 if (::access(fileName, F_OK) != 0) break;
68 sprintf(cmd, "rm -f %s", fileName);
69 int retval = system(cmd);
70 if (retval) return retval;
71 counter++;
73 printf("All the applied log files have been successfully removed.\n");
74 SqlStatement::freeAllStmtHandles(stmtBuckets);
75 conn->disconnect();
76 delete conn;
77 return 0;
80 int applyOfflinelogs(char *fileName, bool interactive)
82 struct stat st;
83 printf("offline log filename is :%s\n", fileName);
84 int fd = open(fileName, O_RDONLY);
85 if (-1 == fd) { return 0; }
86 if (fstat(fd, &st) == -1) {
87 printError(ErrSysInternal, "Unable to retrieve undo log file size");
88 close(fd);
89 return 1;
91 if (st.st_size ==0) {
92 printError(ErrNote, "No Redo logs found during recovery");
93 close(fd);
94 return 0;
96 void *startAddr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
97 if (MAP_FAILED == startAddr) {
98 printf("Unable to read undo log file:mmap failed.\n");
99 conn->disconnect();
100 delete conn;
101 return 2;
103 DbRetVal rv=OK;
104 char *iter = (char*)startAddr;
105 void *value = NULL;
106 int logType, eType;
107 int stmtID;
108 int txnID;
109 int len, ret, retVal =0;
110 int loglen;
111 char stmtString[SQL_STMT_LEN];
112 //printf("size of file %d\n", st.st_size);
113 while(true) {
114 //printf("OFFSET HERE %d\n", iter - (char*)startAddr);
115 if (iter - (char*)startAddr >= st.st_size) break;
116 logType = *(int*)iter;
117 if (logType == -1) { //prepare
118 iter = iter + sizeof(int);
119 txnID = *(int*) iter; iter += sizeof(int);
120 loglen = *(int*) iter; iter += sizeof(int);
121 stmtID = *(int*)iter;
122 iter = iter + sizeof(int);
123 len = *(int*)iter;
124 iter = iter + sizeof(int);
125 strncpy(stmtString, iter, len);
126 iter = iter + len;
127 //printf("PREPARE:%d %d %s\n", stmtID, len, stmtString);
128 AbsSqlStatement *stmt = SqlFactory::createStatement(CSqlAdapter);
129 stmt->setConnection(conn);
130 if (interactive) printf("PREPARE %d : %s\n", stmtID, stmtString);
131 rv = stmt->prepare(stmtString);
132 if (rv != OK) {
133 printError(ErrSysInternal, "unable to prepare stmt:%s", stmtString);
134 retVal=1;
135 break;
137 SqlStatement::addToHashTable(stmtID, stmt, stmtBuckets, stmtString);
139 else if(logType == -2) { //commit
140 conn->beginTrans();
141 iter = iter + sizeof(int);
142 txnID = *(int*) iter; iter += sizeof(int);
143 loglen = *(int*) iter; iter += sizeof(int);
144 char *curPtr = iter;
145 while(true) {
146 //printf("Iter length %d\n", iter - curPtr);
147 if (iter - (char*)startAddr >= st.st_size) {
148 //file end reached
149 //printf("Redo log file end\n");
150 retVal=0;
151 break;
153 stmtID = *(int*)iter;
154 //printf("stmtid %d\n", stmtID);
155 if (interactive) printf("EXEC %d :\n", stmtID);
156 iter = iter + sizeof(int);
157 eType = *(int*)iter;
158 //printf("eType is %d\n", eType);
159 AbsSqlStatement *stmt =
160 SqlStatement::getStmtFromHashTable(stmtID, stmtBuckets);
161 if (0 == eType) { //execute type
162 iter = iter + sizeof(int);
163 //printf("EXEC: %d\n", stmtID);
164 if (stmt) {
165 rv = stmt->execute(ret);
166 if (rv != OK) {
167 printError(ErrSysInternal, "unable to execute");
168 retVal=2;
169 break;
171 } else {
172 printError(ErrSysInternal, "statement not found for %d\n",stmtID);
174 if (*(int*)iter <0) break;
175 } else if ( 1 == eType) { //set type
176 iter=iter+sizeof(int);
177 int pos = *(int*) iter;
178 iter=iter+sizeof(int);
179 DataType type = (DataType)(*(int*)iter);
180 iter=iter+sizeof(int);
181 int len = *(int*) iter;
182 iter=iter+sizeof(int);
183 value = iter;
184 //AllDataType::printVal(value, type, len);
185 iter=iter+len;
186 //printf("SET: %d %d %d %d\n", stmtID, pos, type, len);
187 SqlStatement::setParamValues(stmt, pos, type, len, value);
188 if (*(int*)iter <0) break;
191 conn->commit();
193 else if(logType == -3) { //free
194 iter = iter + sizeof(int);
195 txnID = *(int*) iter; iter += sizeof(int);
196 loglen = *(int*) iter; iter += sizeof(int);
197 stmtID = *(int*)iter;
198 iter = iter + sizeof(int);
199 if (interactive) printf("FREE %d:\n", stmtID);
200 AbsSqlStatement *stmt = SqlStatement::getStmtFromHashTable(stmtID,
201 stmtBuckets);
202 if (stmt) {
203 stmt->free();
204 SqlStatement::removeFromHashTable(stmtID, stmtBuckets);
205 } else { printError(ErrSysInternal, "statement not found for %d\n",stmtID);}
207 else if(logType == -4) { //prepare and execute
208 iter = iter + sizeof(int);
209 txnID = *(int*) iter; iter += sizeof(int);
210 loglen = *(int*) iter; iter += sizeof(int);
211 stmtID = *(int*)iter;
212 iter = iter + sizeof(int);
213 len = *(int*)iter;
214 iter = iter + sizeof(int);
215 strncpy(stmtString, iter, len);
216 stmtString[len+1] ='\0';
217 iter = iter + len;
218 //printf("CREATE:%d %d %s\n", stmtID, len, stmtString);
219 AbsSqlStatement *stmt = SqlFactory::createStatement(CSqlAdapter);
220 if ( NULL == stmt) {
221 printError(ErrSysInternal, "unable to prepare:%s", stmtString);
222 retVal=3;
223 break;
225 stmt->setConnection(conn);
226 if (interactive) printf("EXECDIRECT %d : %s\n", stmtID, stmtString);
227 rv = stmt->prepare(stmtString);
228 if (rv != OK) {
229 printError(ErrSysInternal, "unable to prepare:%s", stmtString);
230 retVal=4;
231 break;
233 rv = stmt->execute(ret);
234 if (rv != OK) {
235 if (strlen(stmtString) > 6 &&
236 ( (strncasecmp(stmtString,"CREATE", 6) == 0) ||
237 (strncasecmp(stmtString,"DROP", 4) == 0)) ) {
238 // conn->disconnect();
239 // return OK;
240 continue;
242 printError(ErrSysInternal, "unable to execute %s", stmtString);
243 retVal=5;
244 break;
246 stmt->free();
247 }else{
248 printError(ErrSysInternal, "Redo log file corrupted: logType:%d", logType);
249 retVal=6;
250 break;
253 munmap((char*)startAddr, st.st_size);
254 close(fd);
255 return retVal;