changing old cachetable.conf file to csqltable.conf in error messages
[csql.git] / src / cache / CacheTableLoader.cxx
blobbaa3d4ff0f61e7234213bd0a34c195cbc6001924
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<CacheTableLoader.h>
18 #include<TableConfig.h>
19 #include<Util.h>
20 #include<SqlConnection.h>
21 #include<SqlLogConnection.h>
22 #include<SqlStatement.h>
23 #include<SqlFactory.h>
27 DbRetVal CacheTableLoader::checkSecondTimeSqlPrimaryKeys(SQLHSTMT hstmtmeta,char *tableName,char *ptr,HashIndexInitInfo *inf,bool &isPriIndex)
29 int retValue =0;
30 char columnname[IDENTIFIER_LENGTH];
31 retValue=SQLPrimaryKeys(hstmtmeta, NULL, SQL_NTS, NULL, SQL_NTS, (SQLCHAR*) tableName, SQL_NTS);
32 retValue = SQLBindCol(hstmtmeta, 4, SQL_C_CHAR,columnname, 129,NULL);
33 char indname[IDENTIFIER_LENGTH];
34 if(SQLFetch( hstmtmeta ) == SQL_SUCCESS)
36 Util::str_tolower(columnname);
37 inf->list.append(columnname);
38 sprintf(ptr, "%s ", columnname);
39 ptr += strlen(ptr);
40 while ( SQLFetch( hstmtmeta ) == SQL_SUCCESS ) {
41 Util::str_tolower(columnname);
42 inf->list.append(columnname);
43 sprintf(ptr, ", %s ", columnname);
44 ptr += strlen(ptr);
46 sprintf(ptr, ") PRIMARY SIZE 10007;");
47 isPriIndex=true;
49 return OK;
52 DbRetVal CacheTableLoader::load(bool tabDefinition)
54 AbsSqlConnection *conn = SqlFactory::createConnection(CSqlLog);
55 DbRetVal rv = conn->connect(userName, password);
56 if (rv != OK) { delete conn; return ErrSysInit; }
57 AbsSqlStatement *stmt = SqlFactory::createStatement(CSqlLog);
58 stmt->setConnection(conn);
59 SqlLogConnection *logConn = (SqlLogConnection *) conn;
60 logConn->setNoMsgLog(true);
61 SqlConnection *con = (SqlConnection *) conn->getInnerConnection();
62 DatabaseManager *dbMgr = con->getConnObject().getDatabaseManager();
63 if (tabDefinition == false) {
64 Table *tbl = dbMgr->openTable(tableName);
65 if (tbl == NULL) {
66 conn->disconnect();
67 delete stmt;
68 delete conn;
69 return ErrNotExists;
71 if (tbl->numTuples()) {
72 printError(ErrNotEmpty, "The table '\%s\' is not empty", tableName);
73 dbMgr->closeTable(tbl);
74 conn->disconnect();
75 delete stmt;
76 delete conn;
77 return ErrNotEmpty;
79 dbMgr->closeTable(tbl);
81 conn->beginTrans();
82 rv = load(conn, stmt, tabDefinition);
83 conn->commit();
84 stmt->free();
85 conn->disconnect();
86 delete stmt;
87 delete conn;
88 return rv;
91 DbRetVal CacheTableLoader::load(AbsSqlConnection *conn, AbsSqlStatement *stmt, bool tabDefinition)
93 char dsn[72];
94 DbRetVal rv = OK;
95 FILE *fp;
96 fp = fopen(Conf :: config.getDsConfigFile(),"r");
97 if(fp==NULL) {
98 printError(ErrSysInit, "csqlds.conf file does not exist");
99 return ErrSysInit;
101 char dsnId[IDENTIFIER_LENGTH]; dsnId[0]='\0';
102 char user[IDENTIFIER_LENGTH]; user[0] = '\0';
103 char passwd[IDENTIFIER_LENGTH]; passwd[0] = '\0';
104 char tdb[IDENTIFIER_LENGTH]; tdb[0]='\0';
106 // STARTs Here:
107 // DSN, user and password value is read here from csql.conf fiel and csqlds.conf file.
109 if(strcmp(dsnName,"")==0) { // it's true if -d option is specified and the DSN value not matched with csql.conf's DSN.
110 strcpy(dsnName, Conf::config.getDSN());
112 bool isDSNExist=false;
113 while(!feof(fp)) {
114 fscanf(fp,"%s %s %s %s\n",dsnId,user,passwd,tdb);
115 if(strcmp(dsnId,dsnName)==0) { // Both the DSN is matched here
116 if( strcmp(user,"NULL")!=0 && strcmp(passwd,"NULL")!=0) {
117 sprintf(dsn,"DSN=%s;UID=%s;PWD=%s;",dsnName,user,passwd);
118 isDSNExist=true;
119 break;
120 } else {
121 sprintf(dsn,"DSN=%s;",dsnName);
122 isDSNExist=true;
123 break;
127 if(!isDSNExist) {
128 printError(ErrNotExists,"Entries is not present in the csqlds.conf file\n");
129 fclose(fp);
130 return ErrNotExists;
132 fclose(fp);
133 TDBInfo tdbName=mysql;
134 if (strcasecmp(tdb,"postgres")==0) tdbName=postgres;
135 else if (strcasecmp(tdb,"postgres")==0) tdbName=mysql;
136 else printError(ErrNotFound,"Target Database Name is not properly set.Tdb name could be mysql, postgres, sybase, db2, oracle\n");
138 logFine(Conf::logger, "TDB Name:%s\n", tdb);
140 //DatabaseManager *dbMgr = (DatabaseManager *) conn->getDatabaseManager();
141 //char dsn[72];
142 SqlConnection *con = (SqlConnection *) conn->getInnerConnection();
143 DatabaseManager *dbMgr = con->getConnObject().getDatabaseManager();
145 SQLCHAR outstr[1024];
146 SQLSMALLINT outstrlen;
147 int retValue =0;
148 SQLHENV henv;
149 SQLHDBC hdbc;
150 SQLHSTMT hstmt;
151 retValue = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
152 if (retValue) {
153 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
154 return ErrSysInit;
156 SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
157 retValue = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
158 if (retValue) {
159 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
160 return ErrSysInit;
162 retValue = SQLDriverConnect(hdbc, NULL, (SQLCHAR*)dsn, SQL_NTS,
163 outstr, sizeof(outstr), &outstrlen,
164 SQL_DRIVER_NOPROMPT);
165 if (SQL_SUCCEEDED(retValue)) {
166 printDebug(DM_Gateway, "Connected to target database using dsn = %s\n", dsn);
167 } else {
168 printError(ErrSysInit, "Failed to connect to target database\n");
169 return ErrSysInit;
172 retValue=SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
173 if (retValue) {
174 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
175 return ErrSysInit;
177 char stmtBuf[1024];
179 if(((strcmp(conditionVal,"")==0) || (strcmp(conditionVal,"NULL")==0)) && ((strcmp(fieldlistVal,"")==0) || (strcmp(fieldlistVal,"NULL")==0)))
181 sprintf(stmtBuf, "SELECT * FROM %s;", tableName);
183 else if(((strcmp(conditionVal,"")!=0) || (strcmp(conditionVal,"NULL")!=0)) && ((strcmp(fieldlistVal,"")==0) || (strcmp(fieldlistVal,"NULL")==0)))
185 sprintf(stmtBuf,"SELECT * FROM %s where %s;",tableName,conditionVal);
188 else if(((strcmp(conditionVal,"")==0) || (strcmp(conditionVal,"NULL")==0)) && ((strcmp(fieldlistVal,"")!=0) || (strcmp(fieldlistVal,"NULL")!=0)))
190 sprintf(stmtBuf,"SELECT %s FROM %s;",fieldlistVal,tableName);
192 else
193 sprintf(stmtBuf,"SELECT %s FROM %s where %s;",fieldlistVal,tableName,conditionVal);
195 retValue = SQLPrepare (hstmt, (unsigned char *) stmtBuf, SQL_NTS);
196 if (retValue) {
197 printError(ErrSysInit, "Unable to Prepare ODBC statement \n");
198 return ErrSysInit;
200 logFinest(Conf::logger, "Cache Table Stmt %s", stmtBuf);
201 if (tabDefinition) {
202 short totalFields=0;
203 retValue = SQLNumResultCols (hstmt, &totalFields);
204 if (retValue) {
205 printError(ErrSysInit, "Unable to retrieve ODBC total columns\n");
206 return ErrSysInit;
208 UWORD icol;
209 UCHAR colName[IDENTIFIER_LENGTH];
210 SWORD colNameMax;
211 SWORD nameLength;
212 SWORD colType;
213 SQLULEN colLength = 0;
214 SWORD scale;
215 SWORD nullable;
216 TableDef tabDef;
217 icol = 1;
218 colNameMax = IDENTIFIER_LENGTH;
219 char columnname[IDENTIFIER_LENGTH];
220 char indexname[IDENTIFIER_LENGTH];
221 short type; short unique;
222 SQLHSTMT hstmtmeta;
223 retValue=SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmtmeta);
224 if (retValue)
226 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
227 return ErrSysInit;
230 retValue=SQLPrimaryKeys(hstmtmeta, NULL, SQL_NTS, NULL, SQL_NTS, (SQLCHAR*) tableName, SQL_NTS);
231 retValue = SQLBindCol(hstmtmeta, 4, SQL_C_CHAR,columnname, 129,NULL);
232 HashIndexInitInfo *inf = new HashIndexInitInfo();
233 char crtIdxStmt[1024];
234 char *name = NULL;
235 char *ptr=crtIdxStmt;
236 sprintf(ptr, "CREATE INDEX %s_PRIMARY on %s ( ", tableName, tableName);
237 ptr += strlen(ptr);
238 bool isPriIndex=false;
239 char indname[IDENTIFIER_LENGTH];
240 if(SQLFetch( hstmtmeta ) == SQL_SUCCESS)
242 Util::str_tolower(columnname);
243 inf->list.append(columnname);
244 sprintf(ptr, "%s ", columnname);
245 ptr += strlen(ptr);
246 while ( SQLFetch( hstmtmeta ) == SQL_SUCCESS ) {
247 Util::str_tolower(columnname);
248 inf->list.append(columnname);
249 sprintf(ptr, ", %s ", columnname);
250 ptr += strlen(ptr);
252 sprintf(ptr, ") PRIMARY SIZE 10007;");
253 inf->indType = hashIndex;
254 inf->bucketSize = 10007;
255 inf->isUnique = true; inf->isPrimary = true;
256 strcpy(inf->tableName, tableName);
257 strcpy(indexname,"PRIMARY");
258 sprintf(indname, "%s_%s", tableName, indexname);
259 isPriIndex=true;
261 bool iskeyfieldExist=false;
262 bool isPKFieldSpecified = false;
263 if((strcmp(fieldName,"")!=0) && (strcmp(fieldName,"NULL")!=0) )
265 isPKFieldSpecified = true;
267 if ( isPriIndex && ( strcmp(fieldlistVal,"")!=0 ) &&
268 ( strcmp(fieldlistVal,"NULL") != 0 )) {
269 inf->list.resetIter();
270 while ( (name=inf->list.nextFieldName()) != NULL) {
271 iskeyfieldExist = TableConf::config.isFieldExist(name);
272 if(!iskeyfieldExist) { break; }
274 } else if (isPriIndex) { iskeyfieldExist = true; }
275 if ( isPKFieldSpecified && !(TableConf::config.isFieldExist(fieldName)) )
277 if ( Conf::config.useTwoWayCache() &&
278 (strcmp(fieldlistVal,"")!=0) &&
279 (strcmp(fieldlistVal,"NULL")!=0))
281 printError(ErrSysInit, "Bidirectional caching should have primary key in %s \n", tableName);
282 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
283 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
284 SQLDisconnect (hdbc);
285 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
286 SQLFreeHandle (SQL_HANDLE_ENV, henv);
287 delete inf;
288 return ErrSysInit;
291 if (!iskeyfieldExist && !isPKFieldSpecified )
293 if(Conf::config.useTwoWayCache())
295 printError(ErrSysInit, "Bidirectional caching fail for no primary key in %s \n", tableName);
296 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
297 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
298 SQLDisconnect (hdbc);
299 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
300 SQLFreeHandle (SQL_HANDLE_ENV, henv);
301 delete inf;
302 return ErrSysInit;
306 /* if(isPriIndex) ;
307 else if (Conf::config.useTwoWayCache() && !iskeyfieldExist) {
308 printError(ErrSysInit, "Bidirectonal caching fail for no primary key in %s \n", tableName);
309 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
310 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
311 SQLDisconnect (hdbc);
312 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
313 SQLFreeHandle (SQL_HANDLE_ENV, henv);
314 return ErrSysInit;
317 bool isKeyFld=false;
318 bool isNullfld=false;
319 bool firstFld = true;
320 char crtTblStmt[1024];
321 ptr = crtTblStmt;
322 sprintf(ptr, "CREATE TABLE %s ( ", tableName);
323 ptr += strlen(ptr);
324 while (icol <= totalFields) {
325 retValue = SQLDescribeCol(hstmt, icol, colName, colNameMax,
326 &nameLength, &colType, &colLength,
327 &scale, &nullable);
328 if (retValue) {
329 printError(ErrSysInit, "Unable to retrieve ODBC column info\n");
330 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
331 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
332 SQLDisconnect (hdbc);
333 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
334 SQLFreeHandle (SQL_HANDLE_ENV, henv);
335 delete inf;
336 return ErrSysInit;
338 Util::str_tolower((char*)colName);
339 printDebug(DM_Gateway, "Describe Column %s %d %d %d %d \n", colName, colType, colLength, scale, nullable);
340 logFinest(Conf::logger, "Describe Column colName:%s colType:%d colLen:%d scale:%d nullable:%d\n", colName, colType, colLength, scale, nullable);
342 icol++;
343 if(strcmp((char*)colName,fieldName)== 0)
345 isKeyFld=true;
346 isNullfld=true;
348 bool isPriFld=false;
349 if (nullable) {
350 inf->list.resetIter();
351 while ((name=inf->list.nextFieldName())!=NULL) {
352 if(0==strcmp((char*)colName,name)) {
353 if (firstFld) {
354 firstFld = false;
355 sprintf(ptr, "%s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
356 ptr += strlen(ptr);
357 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY)
359 sprintf(ptr, "(%d) NOT NULL",colLength);
360 } else { sprintf(ptr, " NOT NULL"); }
361 ptr += strlen(ptr);
362 } else {
363 sprintf(ptr, ", %s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
364 ptr += strlen(ptr);
365 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY)
367 sprintf(ptr, "(%d) NOT NULL",colLength);
368 } else { sprintf(ptr, " NOT NULL"); }
369 ptr += strlen(ptr);
371 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType,colLength,scale,tdbName), colLength +1, NULL, true);
372 isPriFld=true;
373 break;
376 if(!isPriFld) {
377 if(!isNullfld) {
378 if (firstFld) {
379 firstFld = false;
380 sprintf(ptr, "%s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
381 ptr += strlen(ptr);
382 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY) {
383 sprintf(ptr, "(%d)",colLength);
384 ptr += strlen(ptr);
386 } else {
387 sprintf(ptr, ", %s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
388 ptr += strlen(ptr);
389 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY) {
390 sprintf(ptr, "(%d)",colLength);
391 ptr += strlen(ptr);
394 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType,colLength,scale,tdbName), colLength+1);
395 } else {
396 if (firstFld) {
397 firstFld = false;
398 sprintf(ptr, "%s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
399 ptr += strlen(ptr);
400 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY) {
401 sprintf(ptr, "(%d) NOT NULL",colLength);
402 } else { sprintf(ptr, " NOT NULL",colLength); }
403 ptr += strlen(ptr);
404 } else {
405 sprintf(ptr, ", %s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
406 ptr += strlen(ptr);
407 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY) {
408 sprintf(ptr, "(%d) NOT NULL",colLength);
409 } else { sprintf(ptr, " NOT NULL",colLength); }
410 ptr += strlen(ptr);
412 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType,colLength,scale,tdbName), colLength+1, NULL, true);
413 isNullfld=false;
416 } else {
417 if (firstFld) {
418 firstFld = false;
419 sprintf(ptr, "%s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength,scale,tdbName)));
420 ptr += strlen(ptr);
421 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY) {
422 sprintf(ptr, "(%d) NOT NULL",colLength);
423 } else { sprintf(ptr, " NOT NULL",colLength); }
424 ptr += strlen(ptr);
425 } else {
426 sprintf(ptr, ", %s %s", colName, AllDataType::getSQLString(AllDataType::convertFromSQLType(colType,colLength, scale, tdbName)));
427 ptr += strlen(ptr);
428 if (colType == SQL_CHAR || colType == SQL_VARCHAR || colType == SQL_BINARY) {
429 sprintf(ptr, "(%d) NOT NULL",colLength);
430 } else { sprintf(ptr, " NOT NULL",colLength); }
431 ptr += strlen(ptr);
433 tabDef.addField((char*)colName, AllDataType::convertFromSQLType(colType,colLength,scale, tdbName), colLength +1, NULL, true);
436 sprintf(ptr, ");");
437 ptr += strlen(ptr);
438 //printf("table stmt '%s'\n", crtTblStmt);
439 if(((strcmp(fieldName,"")!=0) && (strcmp(fieldName,"NULL")!=0))
440 && !isKeyFld) {
441 printError(ErrSysInit, "Unable to cache Table for %s with key field %s\n", tableName,fieldName);
442 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
443 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
444 SQLDisconnect (hdbc);
445 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
446 SQLFreeHandle (SQL_HANDLE_ENV, henv);
447 delete inf;
448 return ErrSysInit;
450 rv = stmt->prepare(crtTblStmt);
451 if (rv != OK) {
452 printError(ErrSysInit, "Unable to prepare create table stmt\n");
453 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
454 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
455 SQLDisconnect (hdbc);
456 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
457 SQLFreeHandle (SQL_HANDLE_ENV, henv);
458 delete inf;
459 return ErrSysInit;
461 int rows = 0;
462 rv = stmt->execute(rows);
463 if (rv != OK) {
464 printError(ErrSysInit, "Unable to execute create table stmt\n");
465 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
466 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
467 SQLDisconnect (hdbc);
468 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
469 SQLFreeHandle (SQL_HANDLE_ENV, henv);
470 delete inf;
471 return ErrSysInit;
473 logFinest(Conf::logger, "Cache Table: Table Created :%s", crtTblStmt);
475 //Table is created.
476 //Create primary key index if present
477 if (isPriIndex && ( iskeyfieldExist ||
478 (strcmp(fieldlistVal,"")==0 || strcmp(fieldlistVal,"NULL")== 0))) {
479 rv = stmt->prepare(crtIdxStmt);
480 if (rv != OK) {
481 printError(ErrSysInit, "Unable to prepare create table stmt\n");
482 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
483 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
484 SQLDisconnect (hdbc);
485 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
486 SQLFreeHandle (SQL_HANDLE_ENV, henv);
487 delete inf;
488 return ErrSysInit;
490 int rows = 0;
491 rv = stmt->execute(rows);
492 if (rv != OK) {
493 printError(ErrSysInit, "Unable to execute create table stmt\n");
494 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
495 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
496 SQLDisconnect (hdbc);
497 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
498 SQLFreeHandle (SQL_HANDLE_ENV, henv);
499 delete inf;
500 return ErrSysInit;
502 //printf("Primary index created from create Index stmt\n");
504 retValue = SQLCloseCursor(hstmtmeta);
505 rv = createIndex(hstmtmeta, tableName, inf, stmt,isPKFieldSpecified);
506 if(rv!=OK) {
507 dbMgr->dropTable(tableName);
508 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
509 SQLDisconnect (hdbc);
510 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
511 SQLFreeHandle (SQL_HANDLE_ENV, henv);
512 //delete inf;
513 return rv;
515 //delete inf;
517 // Now load the table with records
518 char insStmt[1024];
519 char *ptr = insStmt;
520 sprintf(ptr,"INSERT INTO %s VALUES(", tableName);
521 ptr += strlen(ptr);
522 bool firstFld = true;
523 SqlStatement *sqlStmt = (SqlStatement *)stmt->getInnerStatement();
524 sqlStmt->setConnection(con);
525 List fNameList = sqlStmt->getFieldNameList(tableName);
526 int noOfFields = fNameList.size();
527 int totalFields = noOfFields;
528 while (noOfFields--) {
529 if (firstFld) {
530 firstFld = false;
531 sprintf(ptr,"?", tableName);
532 ptr += strlen(ptr);
533 } else {
534 sprintf(ptr, ",?");
535 ptr += strlen(ptr);
538 sprintf(ptr, ");");
539 ptr += strlen(ptr);
540 //printf("insert stmt: '%s'\n", insStmt);
542 rv = stmt->prepare(insStmt);
543 if (rv != OK) {
544 printError(ErrSysInit, "Unable to prepare create table stmt\n");
545 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
546 SQLDisconnect (hdbc);
547 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
548 SQLFreeHandle (SQL_HANDLE_ENV, henv);
549 return ErrSysInit;
551 ListIterator fNameIter = fNameList.getIterator();
552 FieldInfo *info = new FieldInfo();
553 int fcount =1; void *valBuf;
554 Identifier *elem = NULL;
555 void *tembuf=NULL;//For postgre BigInt type
556 BindBuffer *bBuf;
557 List valBufList;
558 SQLLEN *len = (SQLLEN *)malloc((totalFields+1)*sizeof(SQLLEN));
559 for(int i=0;i<=totalFields;i++) { len[i] = SQL_NTS ;}
560 while (fNameIter.hasElement()) {
561 elem = (Identifier*) fNameIter.nextElement();
562 sqlStmt->getFieldInfo(tableName, (const char*)elem->name, info);
563 if (info->type == typeString) {
564 valBuf = AllDataType::alloc(info->type, info->length+1);
565 os::memset(valBuf,0,info->length+1);
566 } else {
567 valBuf = AllDataType::alloc(info->type);
568 os::memset(valBuf,0,AllDataType::size(info->type));
570 switch(info->type)
572 case typeDate:
573 bBuf = new BindBuffer();
574 bBuf->csql = valBuf;
575 bBuf->type = typeDate;
576 bBuf->length = sizeof(DATE_STRUCT);
577 bBuf->targetdb = malloc(bBuf->length);
578 memset(bBuf->targetdb, 0, bBuf->length);
579 valBuf = bBuf->targetdb;
580 valBufList.append(bBuf);
581 break;
582 case typeTime:
583 bBuf = new BindBuffer();
584 bBuf->csql = valBuf;
585 bBuf->type = typeTime;
586 bBuf->length = sizeof(TIME_STRUCT);
587 bBuf->targetdb = malloc(bBuf->length);
588 memset(bBuf->targetdb, 0, bBuf->length);
589 valBuf = bBuf->targetdb;
590 valBufList.append(bBuf);
591 break;
592 case typeTimeStamp:
593 bBuf = new BindBuffer();
594 bBuf->csql = valBuf;
595 bBuf->type = typeTimeStamp;
596 bBuf->length = sizeof(TIMESTAMP_STRUCT);
597 bBuf->targetdb = malloc(bBuf->length);
598 memset(bBuf->targetdb, 0, bBuf->length);
599 valBuf = bBuf->targetdb;
600 valBufList.append(bBuf);
601 break;
602 case typeLongLong:
604 if( tdbName == postgres )
606 bBuf = new BindBuffer();
607 bBuf->type = typeLongLong;
608 bBuf->length = 40;
609 bBuf->csql = valBuf;
610 bBuf->targetdb = AllDataType::alloc(typeString,bBuf->length);
611 memset(bBuf->targetdb, 0, bBuf->length);
612 valBuf = bBuf->targetdb;
613 valBufList.append(bBuf);
614 break;
616 else
618 bBuf = new BindBuffer();
619 bBuf->type = info->type;
620 bBuf->csql = valBuf;
621 valBufList.append(bBuf);
622 bBuf->length = info->length;
623 break;
626 case typeString:
627 if( tdbName != mysql)
629 bBuf = new BindBuffer();
630 bBuf->type = typeString;
631 bBuf->csql = valBuf;
632 bBuf->length = info->length+1;
633 valBufList.append(bBuf);
634 break;
636 default:
637 bBuf = new BindBuffer();
638 bBuf->type = info->type;
639 bBuf->csql = valBuf;
640 valBufList.append(bBuf);
641 bBuf->length = info->length;
642 break;
644 //os::memset(valBuf,0,bBuf->length);
645 retValue = SQLBindCol (hstmt, fcount, AllDataType::convertToSQL_C_Type(info->type,tdbName), valBuf, bBuf->length, &len[fcount]);
646 fcount++;
647 if (retValue) {
648 printError(ErrSysInit, "Unable to bind columns in ODBC\n");
649 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
650 SQLDisconnect (hdbc);
651 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
652 SQLFreeHandle (SQL_HANDLE_ENV, henv);
653 free(len);
654 return ErrSysInit;
657 delete info;
658 fNameIter.reset();
659 while (fNameIter.hasElement())
660 delete ((FieldName *) fNameIter.nextElement());
661 fNameList.reset();
663 retValue = SQLExecute (hstmt);
664 if (retValue) {
665 printError(ErrSysInit, "Unable to execute ODBC statement\n");
666 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
667 SQLDisconnect (hdbc);
668 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
669 SQLFreeHandle (SQL_HANDLE_ENV, henv);
670 free(len);
671 return ErrSysInit;
673 int fldpos=0;
674 int countForCommit = 0;
675 while(true) {
676 //TODO: if SQLFetch return other than record not found error
677 //it should drop the table
678 retValue = SQLFetch (hstmt);
679 if (retValue) break;
680 ListIterator bindIter = valBufList.getIterator();
681 fldpos = 0;
682 while (bindIter.hasElement()) {
683 bBuf = (BindBuffer*) bindIter.nextElement();
684 switch (bBuf->type) {
685 case typeString:
687 if( tdbName != mysql)
689 Util::trimRight((char*)bBuf->csql);
691 break;
693 case typeDate:
695 Date *dtCSQL = (Date*) bBuf->csql;
696 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bBuf->targetdb;
697 dtCSQL->set(dtTarget->year,dtTarget->month,dtTarget->day);
698 break;
700 case typeTime:
702 Time *dtCSQL = (Time*) bBuf->csql;
703 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bBuf->targetdb;
704 dtCSQL->set(dtTarget->hour,dtTarget->minute,dtTarget->second);
705 break;
707 case typeTimeStamp:
709 TimeStamp *dtCSQL = (TimeStamp*) bBuf->csql;
710 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bBuf->targetdb;
711 dtCSQL->setDate(dtTarget->year,dtTarget->month,dtTarget->day);
712 dtCSQL->setTime(dtTarget->hour,dtTarget->minute,dtTarget->second, dtTarget->fraction);
713 break;
715 case typeLongLong:
717 if ( tdbName == postgres) {
718 sscanf((const char*)bBuf->targetdb,"%lld",(long long*) bBuf->csql);
720 break;
723 setParamValues(stmt, ++fldpos, bBuf->type, bBuf->length, (char *) bBuf->csql);
725 fldpos=0;
726 //table->resetNullinfo();
727 while(fldpos < fcount-1) {
728 if(len[++fldpos] == SQL_NULL_DATA) {
729 stmt->setNull(fldpos);
732 int rows = 0;
733 rv = stmt->execute(rows);
734 if (rv != OK) {
735 printError(ErrSysInit, "Unable to cache record in CSQL.\n");
736 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
737 SQLDisconnect (hdbc);
738 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
739 SQLFreeHandle (SQL_HANDLE_ENV, henv);
740 free(len);
741 return ErrSysInit;
743 countForCommit++;
744 if (countForCommit == 1000) {
745 countForCommit = 0;
746 conn->commit();
747 conn->beginTrans();
750 free(len);
751 //TODO::leak:: valBufList and its targetdb buffer
752 ListIterator it = valBufList.getIterator();
753 while(it.hasElement()) {
754 BindBuffer *bb = (BindBuffer *) it.nextElement();
755 if (bb->csql) { free(bb->csql); bb->csql = NULL; }
756 if (bb->targetdb) { free(bb->targetdb); bb->targetdb = NULL; }
757 delete bb; bb = NULL;
759 valBufList.reset();
760 SQLCloseCursor (hstmt);
761 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
762 SQLDisconnect (hdbc);
763 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
764 SQLFreeHandle (SQL_HANDLE_ENV, henv);
765 return OK;
768 DbRetVal CacheTableLoader::reload()
770 FILE *fp=NULL;
771 DbRetVal rv = unload(false);
772 if (rv != OK) return rv;
773 //get table cache senarios
774 fp = fopen(Conf::config.getTableConfigFile(),"r");
775 if( fp == NULL ) {
776 printError(ErrSysInit, "csqltable.conf file does not exist");
777 return OK;
779 int mode;
780 rv = OK;
781 char tablename[IDENTIFIER_LENGTH];
782 char fieldname[IDENTIFIER_LENGTH];
783 char field[IDENTIFIER_LENGTH];
784 char condition[IDENTIFIER_LENGTH];
785 char dsnname[IDENTIFIER_LENGTH];
786 while(!feof(fp))
788 fscanf(fp, "%d %s %s %s %s %s\n", &mode, tablename,fieldname,condition,field,dsnname);
789 if(strcmp(tablename,tableName)==0) break;
791 fclose(fp);
792 setCondition(TableConf::config.getRealConditionFromFile(condition));
793 setFieldName(fieldname);
794 setFieldListVal(field);
795 setDsnName(dsnname);
796 rv = load(false);
797 return rv;
800 DbRetVal CacheTableLoader::unload(bool tabDefinition)
802 AbsSqlConnection *conn = SqlFactory::createConnection(CSqlLog);
803 DbRetVal rv = conn->connect(userName, password);
804 if (rv != OK) return ErrSysInit;
805 AbsSqlStatement *stmt = SqlFactory::createStatement(CSqlLog);
806 stmt->setConnection(conn);
807 SqlLogConnection *logConn = (SqlLogConnection *) conn;
808 logConn->setNoMsgLog(true);
809 char statement[1024];
810 if (TableConf::config.isTableCached(tableName) != OK) {
811 printError(ErrNotCached, "The table \'%s\' is not cached", tableName);
812 conn->disconnect();
813 delete stmt;
814 delete conn;
815 return ErrNotCached;
817 SqlConnection *con = (SqlConnection *) conn->getInnerConnection();
818 DatabaseManager *dbMgr = (DatabaseManager*) con->getConnObject().getDatabaseManager();
819 if (dbMgr == NULL) {
820 conn->disconnect();
821 delete stmt; delete conn;
822 printError(ErrSysInit, "Authentication failed\n");
823 return ErrSysInit;
825 if (!tabDefinition)
827 sprintf(statement, "DELETE FROM %s;", tableName);
828 SqlStatement *sqlStmt = (SqlStatement*)stmt;
829 sqlStmt->setLoading(true);
830 rv = stmt->prepare(statement);
831 if (rv != OK) {
832 conn->disconnect();
833 delete stmt; delete conn;
834 return ErrBadCall;
836 conn->beginTrans();
837 int rows = 0;
838 rv = stmt->execute(rows);
839 if (rv != OK) {
840 conn->disconnect();
841 delete stmt; delete conn;
842 return ErrBadCall;
844 conn->commit();
846 else
848 rv = TableConf::config.removeFromCacheTableFile();
849 if (rv != OK) {
850 conn->disconnect(); delete stmt; delete conn;
851 return ErrBadCall;
853 sprintf(statement, "DROP TABLE %s;", tableName);
854 SqlStatement *sqlStmt = (SqlStatement*)stmt;
855 sqlStmt->setLoading(true);
856 rv = stmt->prepare(statement);
857 if (rv != OK) {
858 //TableConf::config.addToCacheTableFile(false);
859 conn->disconnect();
860 delete stmt; delete conn;
861 return ErrBadCall;
863 int rows = 0;
864 rv = stmt->execute(rows);
865 if (rv != OK) {
866 //TableConf::config.addToCacheTableFile(false);
867 conn->disconnect(); delete stmt; delete conn;
868 return ErrBadCall;
871 conn->disconnect();
872 delete stmt; delete conn;
873 logFine(Conf::logger, "Unloaded Cached Table: %s", tableName);
874 return rv;
877 DbRetVal CacheTableLoader::refresh()
879 return OK;
882 DbRetVal CacheTableLoader::recoverAllCachedTables()
884 FILE *fp;
885 Connection conn;
886 DbRetVal rv = conn.open(userName, password);
887 if(rv !=OK) return ErrSysInit;
889 //Note: if connection is not open, configuration veriables may be incorrect
891 fp = fopen(Conf::config.getTableConfigFile(),"r");
892 if( fp == NULL ) {
893 printError(ErrSysInit, "csqltable.conf file does not exist");
894 conn.close();
895 return OK;
897 conn.close();
898 //TODO::take exclusive lock on database
899 char tablename[IDENTIFIER_LENGTH];
900 char fieldname[IDENTIFIER_LENGTH];
901 char condition[IDENTIFIER_LENGTH];
902 char field[IDENTIFIER_LENGTH];
903 char dsnname[IDENTIFIER_LENGTH];
905 int mode;
906 int scanItems=0;
907 rv = OK;
908 while(!feof(fp))
910 scanItems = fscanf(fp, "%d %s %s %s %s %s\n", &mode, tablename,fieldname,condition,field,dsnname);
911 if (scanItems != 6) {
912 tablename[0]='\0';
913 printf("There is no table to be cached.\n");
914 return OK;
916 //if (mode ==2 ) //just replicated table and not cached
917 //continue;
918 printDebug(DM_Gateway, "Recovering Table from target db: %s\n", tablename);
919 setCondition(TableConf::config.getRealConditionFromFile(condition));
920 if( (strcmp(Conf::config.getDSN(),dsnname)!=0) ){
921 setDsnName(dsnname);
922 setTable(tablename);
923 setFieldName(fieldname);
924 setFieldListVal(field);
925 printf("Recovering table %s %s %s\n", tablename,condition,field);
926 rv = load();
927 if (rv != OK) { fclose(fp); return rv; }
928 } else {
929 setDsnName(Conf::config.getDSN());
930 setTable(tablename);
931 setFieldName(fieldname);
932 setFieldListVal(field);
933 printf("Recovering table %s %s %s\n", tablename,condition,field);
934 rv = load();
935 if (rv != OK) { fclose(fp); return rv; }
937 logFine(Conf::logger, "Recovering Table from target db:%s", tablename);
939 fclose(fp);
940 return OK;
943 void CacheTableLoader::setParamValues(AbsSqlStatement *stmt, int parampos, DataType type, int length, char *value)
945 switch(type)
947 case typeInt:
948 stmt->setIntParam(parampos, *(int*)value);
949 break;
950 case typeLong:
951 stmt->setLongParam(parampos, *(long*)value);
952 break;
953 case typeLongLong:
954 stmt->setLongLongParam(parampos, *(long long*)value);
955 break;
956 case typeShort:
957 stmt->setShortParam(parampos, *(short*)value);
958 break;
959 case typeByteInt:
960 stmt->setByteIntParam(parampos, *(char*)value);
961 break;
962 case typeDouble:
963 stmt->setDoubleParam(parampos, *(double*)value);
964 break;
965 case typeFloat:
966 stmt->setFloatParam(parampos, *(float*)value);
967 break;
968 case typeDate:
969 stmt->setDateParam(parampos, *(Date*)value);
970 break;
971 case typeTime:
972 stmt->setTimeParam(parampos, *(Time*)value);
973 break;
974 case typeTimeStamp:
975 stmt->setTimeStampParam(parampos, *(TimeStamp*)value);
976 break;
977 case typeString:
979 char *d =(char*)value;
980 d[length-1] = '\0';
981 stmt->setStringParam(parampos, (char*)value);
982 break;
984 case typeBinary:
985 stmt->setBinaryParam(parampos, (char *) value, length);
986 break;
988 return;
991 DbRetVal CacheTableLoader::createIndex(SQLHSTMT hstmtmeta, char *tableName, HashIndexInitInfo *inf,AbsSqlStatement *stmt,bool isPKFieldSpecified)
993 bool isKeyFld= false;
994 int retValue = 0;
995 char columnname[IDENTIFIER_LENGTH];
996 char indexname[IDENTIFIER_LENGTH];
997 short type;
998 short unique;
999 char *name = NULL;
1000 DbRetVal rv = OK;
1001 retValue = SQLStatistics(hstmtmeta, NULL, 0, NULL, SQL_NTS,
1002 (SQLCHAR*) tableName, SQL_NTS, SQL_INDEX_ALL, SQL_QUICK);
1003 retValue = SQLBindCol(hstmtmeta, 4, SQL_C_SHORT,
1004 &unique, 2, NULL);
1005 retValue = SQLBindCol(hstmtmeta, 6, SQL_C_CHAR,
1006 indexname, 129, NULL);
1007 retValue = SQLBindCol(hstmtmeta, 7, SQL_C_SHORT,
1008 &type, 2, NULL);
1009 retValue = SQLBindCol(hstmtmeta, 9, SQL_C_CHAR,
1010 columnname, 129,NULL);
1011 List indexList;
1012 bool isSecondTime = false;
1013 CacheIndexInfo *info=NULL;
1014 while ((retValue = SQLFetch(hstmtmeta)) == SQL_SUCCESS) {
1015 //if (type != SQL_TABLE_STAT)
1017 printDebug(DM_Gateway, "Column: %-18s Index Name: %-18s unique:%hd type:%hd\n", columnname, indexname, unique, type);
1020 if (type == 3)
1023 bool isFldAdd = false;
1024 ListIterator iter = indexList.getIterator();
1025 iter.reset();
1026 while (iter.hasElement())
1028 CacheIndexInfo *indInfo = (CacheIndexInfo *)iter.nextElement();
1029 if(0 == strcmp( indInfo->indexName, indexname))
1031 indInfo->fieldList.append(columnname);
1032 isFldAdd = true;
1035 if(!isFldAdd){
1036 info = new CacheIndexInfo();
1037 info->fieldList.append(columnname);
1038 strcpy(info->indexName, indexname);
1039 indexList.append(info);
1040 isSecondTime = true;
1045 ListIterator iter = indexList.getIterator();
1046 iter.reset();
1047 int noOfPkfield = inf->list.size();
1048 char *fName=NULL;
1049 char *cptr = NULL;
1050 while (iter.hasElement())
1052 cptr = columnname;
1053 bool isFieldExistInCondition = false;
1054 bool isPrimary=false;
1055 CacheIndexInfo *indInfo = (CacheIndexInfo *)iter.nextElement();
1056 int noOfFld= indInfo->fieldList.size();
1057 indInfo->fieldList.resetIter();
1058 while ((fName = indInfo->fieldList.nextFieldName())!=NULL)
1060 if(( 1 == noOfFld) && (0 == strcmp(fName,fieldName))) { isKeyFld=true; }
1061 inf->list.resetIter();
1062 while ((name=inf->list.nextFieldName())!=NULL)
1064 if(0==strcmp(fName,name)) { isPrimary = true; break; }
1065 isPrimary = false;
1067 if (!TableConf::config.isFieldExist(fName) && ( (strcmp(fieldlistVal,"")!=0) && (strcmp(fieldlistVal,"NULL")!=0) ))
1069 isFieldExistInCondition =true;
1070 continue;
1072 sprintf(cptr, "%s ,",fName);
1073 cptr += strlen(cptr);
1076 if(isFieldExistInCondition) continue;
1077 cptr -=1;
1078 *cptr = '\0';
1080 if (isPrimary) { continue; }
1081 char crtIdxStmt[1024];
1082 char indname[128];
1083 sprintf(indname, "%s_%s", tableName, indInfo->indexName);
1084 sprintf(crtIdxStmt, "CREATE INDEX %s on %s(%s) HASH SIZE 10007;", indname, tableName, columnname);
1085 //printf("create index stmt \n'%s'\n", crtIdxStmt);
1086 rv = stmt->prepare(crtIdxStmt);
1087 if (rv != OK) {
1088 printError(ErrSysInit, "Unable to prepare create table stmt\n");
1089 return ErrSysInit;
1091 int rows = 0;
1092 rv = stmt->execute(rows);
1093 if (rv != OK) {
1094 printError(ErrSysInit, "Unable to execute create table stmt\n");
1095 return ErrSysInit;
1097 delete indInfo;
1098 }// while meta data fetch for index creation
1099 delete inf;
1100 SQLCloseCursor (hstmtmeta);
1101 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
1102 if( !isKeyFld && isPKFieldSpecified) {
1103 if(shouldForce) {
1104 char frcIndStmt[1024];
1105 char indname[128];
1106 sprintf(indname, "%s_%s", tableName, "keyInd");
1107 sprintf(frcIndStmt, "CREATE INDEX %s on %s(%s) HASH;", indname, tableName, fieldName);
1108 rv = stmt->prepare(frcIndStmt);
1109 if (rv != OK) {
1110 printError(ErrSysInit, "Unable to prepare create table stmt\n");
1111 return ErrSysInit;
1113 int rows = 0;
1114 rv = stmt->execute(rows);
1115 if (rv != OK) {
1116 printError(ErrSysInit, "Unable to execute create table stmt\n");
1117 return ErrSysInit;
1119 } else {
1120 printError(ErrSysInit, "Unable to cache Table for %s with key field %s\n", tableName,fieldName);
1121 return ErrSysInit;
1124 return OK;