First Version
[csql.git] / src / cache / CacheTableLoader.cxx
blobf9af92afab6b6d5bad844f769f6b1c23e23bf76f
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<CacheTableLoader.h>
17 #include<Util.h>
18 char *CacheTableLoader::getConditionVal(char *condition)
20 char str[124];
21 int i=0;
22 char *ptr, *ptr1 = str;
23 while(condition[i]!='\0')
25 if(condition[i] == ' ')
27 ptr = (condition+(i+1));
28 if(strncasecmp(ptr,"and ",4)==0) {
29 *ptr1='#';ptr1++; strncpy(ptr1,ptr,3); ptr1+=3;
30 *ptr1='#';ptr1++; i+=4;
32 else if(strncasecmp(ptr,"or ",3)==0) {
33 *ptr1='#';ptr1++;strncpy(ptr1,ptr,2); ptr1+=2;
34 *ptr1='#';ptr1++; i+=3;
36 else if(strncasecmp(ptr,"between ",8)==0) {
37 *ptr1='#';ptr1++;strncpy(ptr1,ptr,7); ptr1+=7;
38 *ptr1='#';ptr1++; i+=8;
40 else if(strncasecmp(ptr,"in ",3)==0) {
41 *ptr1='#'; ptr1++; strncpy(ptr1,ptr,2); ptr1+=2;
42 *ptr1='#';ptr1++; i+=3;
44 i++;
45 }else{
46 *ptr1 = condition[i++];
47 ptr1++;
50 *ptr1='\0';
51 strcpy(condition,str);
52 return condition;
54 char *CacheTableLoader::getRealConditionFromFile(char *condition)
56 char str[124];
57 int i=0;
58 char *ptr = str;
59 while(condition[i]!='\0')
61 if(condition[i]=='#'){
62 *ptr=' ';
63 ptr++;i++;
64 }else{
65 *ptr=condition[i];
66 ptr++;
67 i++;
70 *ptr='\0';
71 strcpy(condition,str);
72 // printf("Condition %s\n",condition);
73 return condition;
77 DbRetVal CacheTableLoader::addToCacheTableFile(bool isDirect)
79 FILE *fp;
80 fp = fopen(Conf::config.getTableConfigFile(),"a");
81 if( fp == NULL ) {
82 printError(ErrSysInit, "Invalid path/filename in TABLE_CONFIG_FILE.\nTable will not be"
83 "recovered in case of crash");
84 return ErrSysInit;
86 //TODO::if already table present in the file, it means that the
87 //table is replicated. in this case change mode from
88 //2 to 3 (repl to replcache)
89 if( strcmp(fieldName,"")==0 ){ strcpy(fieldName,"NULL"); }
90 if(isDirect)
92 if((strcmp(conditionVal,"")!=0)&&(strcmp(fieldlistVal,"")!=0))
94 fprintf(fp,"%d:%s %s %s %s\n",6,tableName,fieldName,getConditionVal(conditionVal),fieldlistVal);
96 else if((strcmp(conditionVal,"")!=0)&&(strcmp(fieldlistVal,"")==0))
98 strcpy(fieldlistVal,"NULL");
99 fprintf(fp,"%d:%s %s %s %s\n",6,tableName,fieldName,getConditionVal(conditionVal),fieldlistVal);
101 else if((strcmp(conditionVal,"")==0)&&(strcmp(fieldlistVal,"")!=0))
103 strcpy(conditionVal,"NULL");
104 fprintf(fp,"%d:%s %s %s %s\n",6,tableName,fieldName,conditionVal,fieldlistVal);
106 else
108 strcpy(fieldlistVal,"NULL");
109 strcpy(conditionVal,"NULL");
110 fprintf(fp,"%d:%s %s %s %s\n",5,tableName,fieldName,conditionVal,fieldlistVal);
113 else
115 if((strcmp(conditionVal,"")!=0)&&(strcmp(fieldlistVal,"")!=0))
117 fprintf(fp,"%d:%s %s %s %s\n",2,tableName,fieldName,getConditionVal(conditionVal),fieldlistVal);
119 else if((strcmp(conditionVal,"")!=0)&&(strcmp(fieldlistVal,"")==0))
121 strcpy(fieldlistVal,"NULL");
122 fprintf(fp,"%d:%s %s %s %s\n",2,tableName,fieldName,getConditionVal(conditionVal),fieldlistVal);
124 else if((strcmp(conditionVal,"")==0)&&(strcmp(fieldlistVal,"")!=0))
126 strcpy(conditionVal,"NULL");
127 fprintf(fp,"%d:%s %s %s %s\n",2,tableName,fieldName,conditionVal,fieldlistVal);
129 else
131 strcpy(fieldlistVal,"NULL");
132 strcpy(conditionVal,"NULL");
133 fprintf(fp,"%d:%s %s %s %s\n",1,tableName,fieldName,conditionVal,fieldlistVal);
137 fclose(fp);
138 return OK;
141 DbRetVal CacheTableLoader::removeFromCacheTableFile()
143 FILE *fp, *tmpfp;
144 char tmpFileName[MAX_FILE_PATH_LEN];
145 sprintf(tmpFileName, "%s.tmp", Conf::config.getTableConfigFile());
146 tmpfp = fopen(tmpFileName,"w");
147 if( tmpfp == NULL ) {
148 printError(ErrSysInit, "Invalid path/filename in TABLE_CONFIG_FILE.\n");
149 return ErrSysInit;
151 fp = fopen(Conf::config.getTableConfigFile(),"r");
152 if( fp == NULL ) {
153 printError(ErrSysInit, "csqltable.conf file does not exist");
154 return ErrSysInit;
156 char tablename[IDENTIFIER_LENGTH];
157 char fieldname[IDENTIFIER_LENGTH];
158 char condition[IDENTIFIER_LENGTH];
159 char field[IDENTIFIER_LENGTH];
160 int mode;
161 while(!feof(fp))
163 fscanf(fp, "%d:%s %s %s %s\n", &mode, tablename,fieldname,condition,field);
164 if (strcmp (tablename, tableName) == 0) continue;
165 fprintf(tmpfp, "%d:%s %s %s %s\n", mode, tablename,fieldname,condition,field);
167 fclose(tmpfp);
168 fclose(fp);
169 char sysCommand[MAX_FILE_PATH_LEN * 2];
170 sprintf(sysCommand, "mv %s %s", tmpFileName, Conf::config.getTableConfigFile());
171 int ret = system(sysCommand);
172 if (ret != 0)
174 printError(ErrSysInit, "Check csqltable.conf file permission. unable to remove %s from file", tableName);
175 return ErrSysInit;
177 return OK;
180 // new function is added by: Jitendra
181 DbRetVal CacheTableLoader :: isTablePresent()
183 DbRetVal rv = OK;
184 FILE *fp;
185 Connection conn;
186 rv = conn.open(userName,password);
187 if(rv !=OK) return ErrSysInit;
188 // check for CACHE_TABLE variable
191 fp = fopen(Conf :: config.getTableConfigFile(),"r");
192 if(fp == NULL)
194 printError(ErrSysInit, "cachetable.conf file does not exist");
195 return OK;
197 conn.close();
199 char tablename[IDENTIFIER_LENGTH];
200 char condition[IDENTIFIER_LENGTH];
201 char fieldname[IDENTIFIER_LENGTH];
202 char field[IDENTIFIER_LENGTH];
203 int mode;
205 while(!feof(fp))
207 tablename[0] = '\0'; condition[0] = '\0';
208 fscanf(fp,"%d:%s %s %s %s\n",&mode,tablename,fieldname,condition,field);
210 if(strcmp(tableName,tablename)==0)
212 fclose(fp);
213 return OK;
216 fclose(fp);
217 return ErrNotExists;
222 DbRetVal CacheTableLoader::load(bool tabDefinition)
224 Connection conn;
225 DbRetVal rv = conn.open(userName, password);
226 if (rv != OK) return ErrSysInit;
227 // check for CACHE_TABLE variable
230 DatabaseManager *dbMgr = (DatabaseManager*) conn.getDatabaseManager();
231 if (dbMgr == NULL) { printError(ErrSysInit, "Auth failed\n"); return ErrSysInit; }
232 if (tabDefinition == false) {
233 Table *tbl = dbMgr->openTable(tableName);
234 if (tbl == NULL) {
235 conn.close();
236 return ErrNotExists;
238 if (tbl->numTuples()) {
239 printError(ErrNotEmpty, "The table '\%s\' is not empty", tableName);
240 dbMgr->closeTable(tbl);
241 conn.close();
242 return ErrNotEmpty;
245 conn.startTransaction();
246 rv = load(&conn, tabDefinition);
247 conn.commit();
248 conn.close();
249 return rv;
252 DbRetVal CacheTableLoader::load(Connection *conn, bool tabDefinition)
254 char dsn[72];
255 DatabaseManager *dbMgr = (DatabaseManager *) conn->getDatabaseManager();
256 sprintf(dsn, "DSN=%s;", Conf::config.getDSN());
257 SQLCHAR outstr[1024];
258 SQLSMALLINT outstrlen;
259 DbRetVal rv = OK;
260 int retValue =0;
261 SQLHENV henv;
262 SQLHDBC hdbc;
263 SQLHSTMT hstmt;
264 retValue = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
265 if (retValue) {printError(ErrSysInit, "Unable to allocate ODBC handle \n"); return ErrSysInit; }
266 SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
267 retValue = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
268 if (retValue) {printError(ErrSysInit, "Unable to allocate ODBC handle \n"); return ErrSysInit; }
269 retValue = SQLDriverConnect(hdbc, NULL, (SQLCHAR*)dsn, SQL_NTS,
270 outstr, sizeof(outstr), &outstrlen,
271 SQL_DRIVER_NOPROMPT);
272 if (SQL_SUCCEEDED(retValue)) {
273 printDebug(DM_Gateway, "Connected to target database using dsn = %s\n", dsn);
274 } else {
275 fprintf(stderr, "Failed to connect to target database\n");
276 return ErrSysInit;
279 retValue=SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
280 if (retValue) {printError(ErrSysInit, "Unable to allocate ODBC handle \n"); return ErrSysInit; }
281 char stmtBuf[1024];
283 if(((strcmp(conditionVal,"")==0) || (strcmp(conditionVal,"NULL")==0)) && ((strcmp(fieldlistVal,"")==0) || (strcmp(fieldlistVal,"NULL")==0)))
285 sprintf(stmtBuf, "SELECT * FROM %s;", tableName);
287 else if(((strcmp(conditionVal,"")!=0) || (strcmp(conditionVal,"NULL")!=0)) && ((strcmp(fieldlistVal,"")==0) || (strcmp(fieldlistVal,"NULL")==0)))
289 sprintf(stmtBuf,"SELECT * FROM %s where %s;",tableName,conditionVal);
292 else if(((strcmp(conditionVal,"")==0) || (strcmp(conditionVal,"NULL")==0)) && ((strcmp(fieldlistVal,"")!=0) || (strcmp(fieldlistVal,"NULL")!=0)))
294 sprintf(stmtBuf,"SELECT %s FROM %s;",fieldlistVal,tableName);
296 else
297 sprintf(stmtBuf,"SELECT %s FROM %s where %s;",fieldlistVal,tableName,conditionVal);
299 retValue = SQLPrepare (hstmt, (unsigned char *) stmtBuf, SQL_NTS);
300 if (retValue) {printError(ErrSysInit, "Unable to Prepare ODBC statement \n"); return ErrSysInit; }
302 if (tabDefinition) {
303 short totalFields=0;
304 retValue = SQLNumResultCols (hstmt, &totalFields);
305 if (retValue) {printError(ErrSysInit, "Unable to retrieve ODBC total columns\n"); return ErrSysInit; }
306 UWORD icol;
307 UCHAR colName[IDENTIFIER_LENGTH];
308 SWORD colNameMax;
309 SWORD nameLength;
310 SWORD colType;
311 SQLULEN colLength;
312 SWORD scale;
313 SWORD nullable;
314 TableDef tabDef;
315 icol = 1; colNameMax = IDENTIFIER_LENGTH;
316 char columnname[IDENTIFIER_LENGTH];
317 char indexname[IDENTIFIER_LENGTH];
318 short type; short unique;
319 SQLHSTMT hstmtmeta;
320 retValue=SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmtmeta);
321 if (retValue)
323 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
324 return ErrSysInit;
326 retValue=SQLPrimaryKeys(hstmtmeta, NULL, SQL_NTS, NULL, SQL_NTS, (SQLCHAR*) tableName, SQL_NTS);
327 retValue = SQLBindCol(hstmtmeta, 4, SQL_C_CHAR,columnname, 129,NULL);
328 HashIndexInitInfo *inf = new HashIndexInitInfo();
329 bool isPriIndex=false;
330 char indname[IDENTIFIER_LENGTH];
331 if(SQLFetch( hstmtmeta ) == SQL_SUCCESS)
333 inf->list.append(columnname);
334 while( SQLFetch( hstmtmeta ) == SQL_SUCCESS )
336 inf->list.append(columnname);
338 inf->indType = hashIndex;
339 inf->bucketSize = 10007;
340 inf->isUnique = true; inf->isPrimary = true;
341 strcpy(inf->tableName, tableName);
342 strcpy(indexname,"PRIMARY");
343 sprintf(indname, "%s_%s", tableName, indexname);
344 isPriIndex=true;
346 char *name = NULL;
347 bool iskeyfieldExist=true;
348 if(isPriIndex && (strcmp(fieldlistVal,"")!=0) && (strcmp(fieldlistVal,"NULL")!=0))
350 inf->list.resetIter();
351 while ((name=inf->list.nextFieldName())!=NULL)
353 iskeyfieldExist=isFieldExist(name);
354 if(!iskeyfieldExist) { break; }
356 }else if(!isPriIndex){iskeyfieldExist = false;}
357 if(((strcmp(fieldName,"")!=0) && (strcmp(fieldName,"NULL")!=0)) && !(isFieldExist(fieldName)))
359 if(Conf::config.useTwoWayCache() && (strcmp(fieldlistVal,"")!=0) && (strcmp(fieldlistVal,"NULL")!=0))
361 printError(ErrSysInit, "Bidirectonal caching fail for no primary key in %s \n", tableName);
362 return ErrSysInit;
366 if(!iskeyfieldExist && ((strcmp(fieldName,"")==0) || (strcmp(fieldName,"NULL")==0)))
368 if(Conf::config.useTwoWayCache())
370 printError(ErrSysInit, "Bidirectonal caching fail for no primary key in %s \n", tableName);
371 return ErrSysInit;
374 bool isKeyFld=false;
375 bool isNullfld=false;
376 while (icol <= totalFields) {
377 retValue = SQLDescribeCol(hstmt, icol, colName, colNameMax,
378 &nameLength, &colType, &colLength,
379 &scale, &nullable);
380 if (retValue) {printError(ErrSysInit, "Unable to retrieve ODBC column info\n"); return ErrSysInit; }
382 printDebug(DM_Gateway, "Describe Column %s %d %d \n", colName, colType, colLength);
383 icol++;
384 if(strcmp((char*)colName,fieldName)== 0)
386 isKeyFld=true;
387 isNullfld=true;
389 bool isPriFld=false;
390 if (nullable) {
391 inf->list.resetIter();
392 while ((name=inf->list.nextFieldName())!=NULL)
394 if(0==strcmp((char*)colName,name))
396 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType), colLength +1, NULL, true);
397 isPriFld=true;
398 break;
401 if(!isPriFld) {
402 if(!isNullfld)
403 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType), colLength +1);
404 else{
405 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType), colLength +1, NULL, true);
406 isNullfld=false;
410 else
411 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType), colLength +1, NULL, true);
413 if(((strcmp(fieldName,"")!=0) && (strcmp(fieldName,"NULL")!=0))&& !isKeyFld)
415 printError(ErrSysInit, "Unable to cache Table for %s with key field %s\n", tableName,fieldName);
416 SQLDisconnect(hdbc);
417 return ErrSysInit;
419 rv = dbMgr->createTable(tableName, tabDef);
420 if (rv != OK)
422 printError(ErrSysInit, "Table creation failed in csql for %s\n", tableName);
423 SQLDisconnect(hdbc);
424 return ErrSysInit;
426 if(isPriIndex ){
427 rv = dbMgr->createIndex(indname, inf);
428 if (rv != OK)
430 printError(ErrSysInit, "Index creation failed in csql for %s\n", tableName);
431 SQLDisconnect(hdbc);
432 return ErrSysInit;
435 else
437 if(Conf::config.useTwoWayCache() && iskeyfieldExist)
439 printError(ErrSysInit, "Bidirectonal caching fail for no primary key in %s \n", tableName);
440 return ErrSysInit;
443 retValue = SQLCloseCursor(hstmtmeta);
444 isKeyFld= false;
445 retValue = SQLStatistics(hstmtmeta, NULL, 0, NULL, SQL_NTS,
446 (SQLCHAR*) tableName, SQL_NTS, SQL_INDEX_ALL, SQL_QUICK);
447 retValue = SQLBindCol(hstmtmeta, 4, SQL_C_SHORT,
448 &unique, 2, NULL);
449 retValue = SQLBindCol(hstmtmeta, 6, SQL_C_CHAR,
450 indexname, 129, NULL);
451 retValue = SQLBindCol(hstmtmeta, 7, SQL_C_SHORT,
452 &type, 2, NULL);
453 retValue = SQLBindCol(hstmtmeta, 9, SQL_C_CHAR,
454 columnname, 129,NULL);
455 while ((retValue = SQLFetch(hstmtmeta)) == SQL_SUCCESS)
456 { //if (type != SQL_TABLE_STAT)
458 printDebug(DM_Gateway, "Column: %-18s Index Name: %-18s unique:%hd type:%hd\n",
459 columnname, indexname, unique, type);
461 if(0 == strcmp(columnname,fieldName)){isKeyFld=true;}
462 bool isPrimary=false;
463 inf->list.resetIter();
464 while ((name=inf->list.nextFieldName())!=NULL)
466 if(0==strcmp(columnname,name))
468 isPrimary=true;
469 break;
472 if(isPrimary){continue;}
473 if (type == 3) {
474 HashIndexInitInfo *info = new HashIndexInitInfo();
475 info->indType = hashIndex;
476 info->bucketSize = 10007;
477 info->list.append(columnname);
478 if (!unique) {info->isUnique = true; info->isPrimary = false;}
479 strcpy(info->tableName, tableName);
480 char indname[128];
481 sprintf(indname, "%s_%s", tableName, indexname);
482 rv = dbMgr->createIndex(indname, info);
483 if (rv != OK)
485 printError(ErrSysInit, "Index creation failed in csql for %s\n", tableName);
486 SQLDisconnect(hdbc);
487 return ErrSysInit;
489 delete info;
490 } else {
491 printError(ErrSysInit,"CSQL does not support this index type\n");
492 SQLDisconnect(hdbc);
493 return ErrSysInit;
495 }// while meta data fetch for index creation
496 SQLCloseCursor (hstmtmeta);
497 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
498 if( !isKeyFld && ((strcmp(fieldName,"")!=0) && (strcmp(fieldName,"NULL")!=0)))
500 printError(ErrSysInit, "Unable to cache Table for %s with key field %s\n", tableName,fieldName);
501 dbMgr->dropTable(tableName);
502 SQLDisconnect(hdbc);
503 return ErrSysInit;
506 Table *table = dbMgr->openTable(tableName);
507 if (table == NULL) {
508 printError(ErrSysInit,"unable to open table %s\n", tableName);
509 dbMgr->closeTable(table);
510 if (tabDefinition) dbMgr->dropTable(tableName);
511 SQLDisconnect(hdbc);
512 return ErrSysInit;
514 table->setUndoLogging(false);
515 //rv = table->lock(false); //no need to release this lock as it is upgrade from S to X
516 if (rv != OK)
518 dbMgr->closeTable(table);
519 if (tabDefinition) dbMgr->dropTable(tableName);
520 SQLDisconnect(hdbc);
521 return ErrSysInit;
523 List fNameList = table->getFieldNameList();
524 ListIterator fNameIter = fNameList.getIterator();
525 FieldInfo *info = new FieldInfo();
526 int fcount =1; void *valBuf; int fieldsize=0;
527 Identifier *elem = NULL;
529 BindBuffer *bBuf;
530 List valBufList;
531 SQLINTEGER len[IDENTIFIER_LENGTH];
532 while (fNameIter.hasElement()) {
533 elem = (Identifier*) fNameIter.nextElement();
534 table->getFieldInfo((const char*)elem->name, info);
535 valBuf = AllDataType::alloc(info->type, info->length);
536 table->bindFld(elem->name, valBuf);
537 fieldsize=0;
538 switch( info->type)
540 case typeString:
541 fieldsize = info->length;
542 break;
543 case typeDate:
544 bBuf = new BindBuffer();
545 bBuf->csql = valBuf;
546 bBuf->type = typeDate;
547 fieldsize = sizeof(DATE_STRUCT);
548 bBuf->targetdb = malloc(fieldsize);
549 valBuf = bBuf->targetdb;
550 valBufList.append(bBuf);
551 break;
552 case typeTime:
553 bBuf = new BindBuffer();
554 bBuf->csql = valBuf;
555 bBuf->type = typeTime;
556 fieldsize = sizeof(TIME_STRUCT);
557 bBuf->targetdb = malloc(fieldsize);
558 valBuf = bBuf->targetdb;
559 valBufList.append(bBuf);
560 break;
561 case typeTimeStamp:
562 bBuf = new BindBuffer();
563 bBuf->csql = valBuf;
564 bBuf->type = typeTimeStamp;
565 fieldsize = sizeof(TIMESTAMP_STRUCT);
566 bBuf->targetdb = malloc(fieldsize);
567 valBuf = bBuf->targetdb;
568 valBufList.append(bBuf);
569 break;
571 retValue = SQLBindCol (hstmt, fcount, AllDataType::convertToSQLType(info->type),
572 valBuf, fieldsize, &len[fcount]);
573 fcount++;
574 if (retValue) {printError(ErrSysInit, "Unable to bind columns in ODBC\n"); return ErrSysInit; }
576 delete info;
577 retValue = SQLExecute (hstmt);
578 if (retValue) {printError(ErrSysInit, "Unable to execute ODBC statement\n"); return ErrSysInit; }
579 int fldpos=0;
580 int countForCommit = 0;
581 while(true)
583 retValue = SQLFetch (hstmt);
584 if (retValue) break;
585 ListIterator bindIter = valBufList.getIterator();
586 while (bindIter.hasElement()) {
587 bBuf = (BindBuffer*) bindIter.nextElement();
588 switch (bBuf->type) {
589 case typeDate: {
590 Date *dtCSQL = (Date*) bBuf->csql;
591 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bBuf->targetdb;
592 dtCSQL->set(dtTarget->year,dtTarget->month,dtTarget->day);
593 break;
595 case typeTime: {
596 Time *dtCSQL = (Time*) bBuf->csql;
597 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bBuf->targetdb;
598 dtCSQL->set(dtTarget->hour,dtTarget->minute,dtTarget->second);
599 break;
601 case typeTimeStamp: {
602 TimeStamp *dtCSQL = (TimeStamp*) bBuf->csql;
603 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bBuf->targetdb;
604 dtCSQL->setDate(dtTarget->year,dtTarget->month,dtTarget->day);
605 dtCSQL->setTime(dtTarget->hour,dtTarget->minute,dtTarget->second, dtTarget->fraction);
606 break;
610 fldpos=0;
611 table->resetNullinfo();
612 while(fldpos < fcount-1)
614 if(len[++fldpos] == SQL_NULL_DATA){
615 table->markFldNull(fldpos);
619 table->insertTuple();
620 if (rv != OK)
622 dbMgr->closeTable(table);
623 dbMgr->dropTable(tableName);
624 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
625 SQLDisconnect (hdbc);
626 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
627 SQLFreeHandle (SQL_HANDLE_ENV, henv);
628 printError(rv, "Unable to load record to target for table %s\n",tableName);
629 return rv;
631 countForCommit++;
632 if (countForCommit == 1000) {
633 countForCommit = 0;
634 conn->commit();
635 conn->startTransaction();
638 //TODO::leak:: valBufList and its targetdb buffer
639 valBufList.reset();
640 dbMgr->closeTable(table);
641 SQLCloseCursor (hstmt);
642 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
643 SQLDisconnect (hdbc);
644 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
645 SQLFreeHandle (SQL_HANDLE_ENV, henv);
646 return OK;
649 DbRetVal CacheTableLoader::reload()
651 DbRetVal rv = unload(false);
652 if (rv != OK) return rv;
653 rv = load(false);
654 return rv;
657 DbRetVal CacheTableLoader::unload(bool tabDefinition)
659 Connection conn;
660 DbRetVal rv = conn.open(userName, password);
661 if (rv != OK) return ErrSysInit;
663 if (CacheTableLoader::isTableCached(tableName) != OK) {
664 printError(ErrNotCached, "The table \'%s\' is not cached", tableName);
665 return ErrNotCached;
667 DatabaseManager *dbMgr = (DatabaseManager*) conn.getDatabaseManager();
668 if (dbMgr == NULL) { printError(ErrSysInit, "Auth failed\n"); return ErrSysInit; }
669 if (!tabDefinition)
671 Table *table = dbMgr->openTable(tableName);
672 if (table == NULL) { conn.close(); return ErrBadCall; }
673 rv = conn.startTransaction();
674 if (rv != OK) { dbMgr->closeTable(table); conn.close(); return ErrBadCall; }
675 table->truncate();
676 conn.commit();
677 dbMgr->closeTable(table);
679 else
681 rv = dbMgr->dropTable(tableName);
683 conn.close();
685 return rv;
688 DbRetVal CacheTableLoader::refresh()
690 return OK;
693 DbRetVal CacheTableLoader::recoverAllCachedTables()
695 FILE *fp;
696 Connection conn;
697 DbRetVal rv = conn.open(userName, password);
698 if(rv !=OK) return ErrSysInit;
700 //Note: if connection is not open, configuration veriables may be incorrect
702 fp = fopen(Conf::config.getTableConfigFile(),"r");
703 if( fp == NULL ) {
704 printError(ErrSysInit, "cachetable.conf file does not exist");
705 return OK;
707 conn.close();
708 //TODO::take exclusive lock on database
709 char tablename[IDENTIFIER_LENGTH];
710 char fieldname[IDENTIFIER_LENGTH];
711 char condition[IDENTIFIER_LENGTH];
712 char field[IDENTIFIER_LENGTH];
713 int mode;
714 rv = OK;
715 while(!feof(fp))
717 fscanf(fp, "%d:%s %s %s %s\n", &mode, tablename,fieldname,condition,field);
718 //if (mode ==2 ) //just replicated table and not cached
719 //continue;
720 printDebug(DM_Gateway, "Recovering Table from target db: %s\n", tablename);
721 setCondition(getRealConditionFromFile(condition));
722 setTable(tablename);
723 setFieldName(fieldname);
724 setFieldListVal(field);
725 printf("Recovering table %s %s %s\n", tablename,condition,field);
726 rv = load();
727 if (rv != OK) return rv;
729 fclose(fp);
730 return OK;
733 DbRetVal CacheTableLoader::isTableCached(char *tabName)
735 FILE *fp;
736 char tmpFileName[MAX_FILE_PATH_LEN];
737 fp = fopen(Conf::config.getTableConfigFile(),"r");
738 if( fp == NULL ) {
739 printError(ErrSysInit, "csqltable.conf file does not exist");
740 return ErrSysInit;
742 char tablename[IDENTIFIER_LENGTH];
743 char fieldname[IDENTIFIER_LENGTH];
744 char condition[IDENTIFIER_LENGTH];
745 char field[IDENTIFIER_LENGTH];
746 int mode;
747 while(!feof(fp))
749 fscanf(fp, "%d:%s %s %s %s\n", &mode, tablename,fieldname,condition,field);
750 if (strcmp (tablename, tabName) == 0) {
751 fclose(fp);
752 return OK;
755 fclose(fp);
756 return ErrNotExists;
759 int CacheTableLoader::getTableMode(char *tabname)
761 FILE *fp;
762 fp = fopen(Conf::config.getTableConfigFile(),"r");
763 if( fp == NULL ) {
764 printError(ErrSysInit, "cachetable.conf file does not exist");
765 fclose(fp);
766 return 0;
768 char tablename[IDENTIFIER_LENGTH];
769 char fieldname[IDENTIFIER_LENGTH];
770 char condition[IDENTIFIER_LENGTH];
771 char field[IDENTIFIER_LENGTH];
772 int mode;
773 while(!feof(fp))
775 fscanf(fp,"%d:%s %s %s %s\n",&mode,tablename,fieldname,fieldname,condition);
776 if(0==strcmp(tabname,tablename)){
777 fclose(fp);
778 return mode;
781 fclose(fp);
782 return 0;
786 bool CacheTableLoader::isFieldExist(char *fieldname)
788 char tmpfieldname[IDENTIFIER_LENGTH];
789 int i=0,j=0;
790 while(fieldlistVal[j]!=0)
792 if(fieldlistVal[j] != ',')
793 tmpfieldname[i++]=fieldlistVal[j++];
794 else
796 tmpfieldname[i]='\0';
797 if(strcmp(fieldname,tmpfieldname)==0)
798 return true;
799 else { i=0; j++; }
802 tmpfieldname[i]='\0';
803 if(strcmp(fieldname,tmpfieldname)==0)
804 return true;
805 else
806 return false;
809 DbRetVal CacheTableLoader::CacheInfo(bool isTabPresent) /* Cacheh Description using "-S" option */
811 FILE *fp;
812 fp = fopen(Conf::config.getTableConfigFile(),"r");
813 if( fp == NULL ) {
814 printError(ErrSysInit, "cachetable.conf file does not exist");
815 fclose(fp);
816 return OK;
819 char tablename[IDENTIFIER_LENGTH];
820 char pkfield[IDENTIFIER_LENGTH];
821 char condition[IDENTIFIER_LENGTH];
822 char field[IDENTIFIER_LENGTH];
823 int mode;
824 printf("\n=================================================================================================================\n");
825 printf("|\tMode\t|\tTable Name\t|\tPrimary Key\t|\tCondition\t|\tField List\t|\n");
826 printf("=================================================================================================================\n");
828 while(!feof(fp))
830 fscanf(fp,"%d:%s %s %s %s\n",&mode,tablename,pkfield,condition,field);
831 if((mode<1) || (mode >6))
832 {return ErrNotFound;}
834 if(isTabPresent)
836 if(strcmp(tableName,tablename)==0)
838 printf("|%8d\t|%16s\t|%16s\t|%16s\t|%16s\t|\n",mode,tablename,pkfield,getRealConditionFromFile(condition),field);
839 printf("-----------------------------------------------------------------------------------------------------------------\n\n");
840 fclose(fp);
841 return OK;
844 else
846 printf("|%8d\t|%16s\t|%16s\t|%16s\t|%16s\t|\n",mode,tablename,pkfield,getRealConditionFromFile(condition),field);
847 printf("-----------------------------------------------------------------------------------------------------------------\n");
850 printf("\n");
851 fclose(fp);
852 return OK;