00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include<CacheTableLoader.h>
00017 #include<Util.h>
00018 DbRetVal CacheTableLoader::addToCacheTableFile()
00019 {
00020 FILE *fp;
00021 fp = fopen(Conf::config.getTableConfigFile(),"a");
00022 if( fp == NULL ) {
00023 printError(ErrSysInit, "Invalid path/filename in TABLE_CONFIG_FILE.\nTable will not be"
00024 "recovered in case of crash");
00025 return ErrSysInit;
00026 }
00027
00028
00029
00030 fprintf(fp, "%d:%s\n", 1, tableName);
00031 fclose(fp);
00032 return OK;
00033 }
00034
00035 DbRetVal CacheTableLoader::removeFromCacheTableFile()
00036 {
00037 FILE *fp, *tmpfp;
00038 char tmpFileName[MAX_FILE_PATH_LEN];
00039 sprintf(tmpFileName, "%s.tmp", Conf::config.getTableConfigFile());
00040 tmpfp = fopen(tmpFileName,"w");
00041 if( tmpfp == NULL ) {
00042 printError(ErrSysInit, "Invalid path/filename in TABLE_CONFIG_FILE.\n");
00043 return ErrSysInit;
00044 }
00045 fp = fopen(Conf::config.getTableConfigFile(),"r");
00046 if( fp == NULL ) {
00047 printError(ErrSysInit, "csqltable.conf file does not exist");
00048 return ErrSysInit;
00049 }
00050 char tablename[IDENTIFIER_LENGTH];
00051 int mode;
00052 while(!feof(fp))
00053 {
00054 fscanf(fp, "%d:%s\n", &mode, tablename);
00055 if (strcmp (tablename, tableName) == 0) continue;
00056 fprintf(tmpfp, "%d:%s\n", mode, tablename);
00057 }
00058 fclose(tmpfp);
00059 fclose(fp);
00060 char sysCommand[MAX_FILE_PATH_LEN * 2];
00061 sprintf(sysCommand, "mv %s %s", tmpFileName, Conf::config.getTableConfigFile());
00062 int ret = system(sysCommand);
00063 if (ret != 0)
00064 {
00065 printError(ErrSysInit, "Check csqltable.conf file permission. unable to remove %s from file", tableName);
00066 return ErrSysInit;
00067 }
00068 return OK;
00069 }
00070
00071 DbRetVal CacheTableLoader::load(bool tabDefinition)
00072 {
00073 Connection conn;
00074 DbRetVal rv = conn.open(userName, password);
00075 if (rv != OK) return ErrSysInit;
00076 DatabaseManager *dbMgr = (DatabaseManager*) conn.getDatabaseManager();
00077 if (dbMgr == NULL) { printError(ErrSysInit, "Auth failed\n"); return ErrSysInit; }
00078 conn.startTransaction();
00079 rv = load(dbMgr, tabDefinition);
00080 conn.commit();
00081 conn.close();
00082 return rv;
00083 }
00084
00085 DbRetVal CacheTableLoader::load(DatabaseManager *dbMgr, bool tabDefinition)
00086 {
00087 char dsn[72];
00088 sprintf(dsn, "DSN=%s;", Conf::config.getDSN());
00089 SQLCHAR outstr[1024];
00090 SQLSMALLINT outstrlen;
00091 DbRetVal rv = OK;
00092 int retValue =0;
00093 SQLHENV henv;
00094 SQLHDBC hdbc;
00095 SQLHSTMT hstmt;
00096 retValue = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
00097 if (retValue) {printError(ErrSysInit, "Unable to allocate ODBC handle \n"); return ErrSysInit; }
00098 SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
00099 retValue = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
00100 if (retValue) {printError(ErrSysInit, "Unable to allocate ODBC handle \n"); return ErrSysInit; }
00101 retValue = SQLDriverConnect(hdbc, NULL, (SQLCHAR*)dsn, SQL_NTS,
00102 outstr, sizeof(outstr), &outstrlen,
00103 SQL_DRIVER_NOPROMPT);
00104 if (SQL_SUCCEEDED(retValue)) {
00105 printDebug(DM_Gateway, "Connected to target database using dsn = %s\n", dsn);
00106 } else {
00107 fprintf(stderr, "Failed to connect to target database\n");
00108 return ErrSysInit;
00109 }
00110
00111 retValue=SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
00112 if (retValue) {printError(ErrSysInit, "Unable to allocate ODBC handle \n"); return ErrSysInit; }
00113 char stmtBuf[1024];
00114 sprintf(stmtBuf, "SELECT * FROM %s;", tableName);
00115 retValue = SQLPrepare (hstmt, (unsigned char *) stmtBuf, SQL_NTS);
00116 if (retValue) {printError(ErrSysInit, "Unable to Prepare ODBC statement \n"); return ErrSysInit; }
00117
00118 if (tabDefinition) {
00119 short totalFields=0;
00120 retValue = SQLNumResultCols (hstmt, &totalFields);
00121 if (retValue) {printError(ErrSysInit, "Unable to retrieve ODBC total columns\n"); return ErrSysInit; }
00122 UWORD icol;
00123 UCHAR colName[IDENTIFIER_LENGTH];
00124 SWORD colNameMax;
00125 SWORD nameLength;
00126 SWORD colType;
00127 SQLULEN colLength;
00128 SWORD scale;
00129 SWORD nullable;
00130 TableDef tabDef;
00131 icol = 1; colNameMax = IDENTIFIER_LENGTH;
00132 while (icol <= totalFields) {
00133 retValue = SQLDescribeCol(hstmt, icol, colName, colNameMax,
00134 &nameLength, &colType, &colLength,
00135 &scale, &nullable);
00136 if (retValue) {printError(ErrSysInit, "Unable to retrieve ODBC column info\n"); return ErrSysInit; }
00137
00138 printDebug(DM_Gateway, "Describe Column %s %d %d \n", colName, colType, colLength);
00139 icol++;
00140 tabDef.addField((char*) colName, AllDataType::convertFromSQLType(colType), colLength +1);
00141 }
00142 rv = dbMgr->createTable(tableName, tabDef);
00143 if (rv != OK)
00144 {
00145 printError(ErrSysInit, "Table creation failed in csql for %s\n", tableName);
00146 SQLDisconnect(hdbc);
00147 return ErrSysInit;
00148 }
00149 char columnname[124]; char indexname[124];
00150 short type; short unique;
00151 SQLHSTMT hstmtmeta;
00152 retValue=SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmtmeta);
00153 if (retValue)
00154 {
00155 printError(ErrSysInit, "Unable to allocate ODBC handle \n");
00156 return ErrSysInit;
00157 }
00158
00159 retValue = SQLStatistics(hstmtmeta, NULL, 0, NULL, SQL_NTS,
00160 (SQLCHAR*) tableName, SQL_NTS, SQL_INDEX_ALL, SQL_QUICK);
00161 retValue = SQLBindCol(hstmtmeta, 4, SQL_C_SHORT,
00162 &unique, 2, NULL);
00163 retValue = SQLBindCol(hstmtmeta, 6, SQL_C_CHAR,
00164 indexname, 129, NULL);
00165 retValue = SQLBindCol(hstmtmeta, 7, SQL_C_SHORT,
00166 &type, 2, NULL);
00167 retValue = SQLBindCol(hstmtmeta, 9, SQL_C_CHAR,
00168 columnname, 129,NULL);
00169 while ((retValue = SQLFetch(hstmtmeta)) == SQL_SUCCESS)
00170 {
00171 {
00172 printDebug(DM_Gateway, "Column: %-18s Index Name: %-18s unique:%hd type:%hd\n",
00173 columnname, indexname, unique, type);
00174 }
00175 if (type == 3) {
00176 HashIndexInitInfo *info = new HashIndexInitInfo();
00177 info->indType = hashIndex;
00178 info->bucketSize = 10007;
00179 info->list.append(columnname);
00180 strcpy(info->tableName, tableName);
00181 char indname[128];
00182 sprintf(indname, "%s_%s", tableName, indexname);
00183 rv = dbMgr->createIndex(indname, info);
00184 if (rv != OK)
00185 {
00186 printError(ErrSysInit, "Index creation failed in csql for %s\n", tableName);
00187 SQLDisconnect(hdbc);
00188 return ErrSysInit;
00189 }
00190 delete info;
00191 } else {
00192 printError(ErrSysInit,"CSQL does not support this index type\n");
00193 SQLDisconnect(hdbc);
00194 return ErrSysInit;
00195 }
00196 }
00197 SQLCloseCursor (hstmtmeta);
00198 SQLFreeHandle (SQL_HANDLE_STMT, hstmtmeta);
00199 }
00200 Table *table = dbMgr->openTable(tableName);
00201 if (table == NULL) {
00202 printError(ErrSysInit,"unable to open table %d\n", tableName);
00203 dbMgr->closeTable(table);
00204 if (tabDefinition) dbMgr->dropTable(tableName);
00205 SQLDisconnect(hdbc);
00206 return ErrSysInit;
00207 }
00208 table->setUndoLogging(false);
00209
00210 if (rv != OK)
00211 {
00212 dbMgr->closeTable(table);
00213 if (tabDefinition) dbMgr->dropTable(tableName);
00214 SQLDisconnect(hdbc);
00215 return ErrSysInit;
00216 }
00217 List fNameList = table->getFieldNameList();
00218 ListIterator fNameIter = fNameList.getIterator();
00219 FieldInfo *info = new FieldInfo();
00220 int fcount =1; void *valBuf; int fieldsize=0;
00221 Identifier *elem = NULL;
00222
00223 BindBuffer *bBuf;
00224 List valBufList;
00225 while (fNameIter.hasElement()) {
00226 elem = (Identifier*) fNameIter.nextElement();
00227 table->getFieldInfo((const char*)elem->name, info);
00228 valBuf = AllDataType::alloc(info->type, info->length);
00229 table->bindFld(elem->name, valBuf);
00230 fieldsize=0;
00231 switch( info->type)
00232 {
00233 case typeString:
00234 fieldsize = info->length;
00235 break;
00236 case typeDate:
00237 bBuf = new BindBuffer();
00238 bBuf->csql = valBuf;
00239 bBuf->type = typeDate;
00240 fieldsize = sizeof(DATE_STRUCT);
00241 bBuf->targetdb = malloc(fieldsize);
00242 valBuf = bBuf->targetdb;
00243 valBufList.append(bBuf);
00244 break;
00245 case typeTime:
00246 bBuf = new BindBuffer();
00247 bBuf->csql = valBuf;
00248 bBuf->type = typeTime;
00249 fieldsize = sizeof(TIME_STRUCT);
00250 bBuf->targetdb = malloc(fieldsize);
00251 valBuf = bBuf->targetdb;
00252 valBufList.append(bBuf);
00253 break;
00254 case typeTimeStamp:
00255 bBuf = new BindBuffer();
00256 bBuf->csql = valBuf;
00257 bBuf->type = typeTimeStamp;
00258 fieldsize = sizeof(TIMESTAMP_STRUCT);
00259 bBuf->targetdb = malloc(fieldsize);
00260 valBuf = bBuf->targetdb;
00261 valBufList.append(bBuf);
00262 break;
00263 }
00264 retValue = SQLBindCol (hstmt, fcount++, AllDataType::convertToSQLType(info->type),
00265 valBuf, fieldsize, NULL);
00266 if (retValue) {printError(ErrSysInit, "Unable to bind columns in ODBC\n"); return ErrSysInit; }
00267 }
00268 delete info;
00269 retValue = SQLExecute (hstmt);
00270 if (retValue) {printError(ErrSysInit, "Unable to execute ODBC statement\n"); return ErrSysInit; }
00271 while(true)
00272 {
00273 retValue = SQLFetch (hstmt);
00274 if (retValue) break;
00275 ListIterator bindIter = valBufList.getIterator();
00276 while (bindIter.hasElement()) {
00277 bBuf = (BindBuffer*) bindIter.nextElement();
00278 switch (bBuf->type) {
00279 case typeDate: {
00280 Date *dtCSQL = (Date*) bBuf->csql;
00281 DATE_STRUCT *dtTarget = (DATE_STRUCT*) bBuf->targetdb;
00282 dtCSQL->set(dtTarget->year,dtTarget->month,dtTarget->day);
00283 break;
00284 }
00285 case typeTime: {
00286 Time *dtCSQL = (Time*) bBuf->csql;
00287 TIME_STRUCT *dtTarget = (TIME_STRUCT*) bBuf->targetdb;
00288 dtCSQL->set(dtTarget->hour,dtTarget->minute,dtTarget->second);
00289 break;
00290 }
00291 case typeTimeStamp: {
00292 TimeStamp *dtCSQL = (TimeStamp*) bBuf->csql;
00293 TIMESTAMP_STRUCT *dtTarget = (TIMESTAMP_STRUCT*) bBuf->targetdb;
00294 dtCSQL->setDate(dtTarget->year,dtTarget->month,dtTarget->day);
00295 dtCSQL->setTime(dtTarget->hour,dtTarget->minute,dtTarget->second, dtTarget->fraction);
00296 break;
00297 }
00298 }
00299 }
00300 table->insertTuple();
00301 }
00302
00303 valBufList.reset();
00304 dbMgr->closeTable(table);
00305 SQLCloseCursor (hstmt);
00306 SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
00307 SQLDisconnect (hdbc);
00308 SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
00309 SQLFreeHandle (SQL_HANDLE_ENV, henv);
00310 return OK;
00311 }
00312
00313 DbRetVal CacheTableLoader::reload()
00314 {
00315 DbRetVal rv = unload(false);
00316 if (rv != OK) return rv;
00317 rv = load(false);
00318 return rv;
00319 }
00320
00321 DbRetVal CacheTableLoader::unload(bool tabDefinition)
00322 {
00323 Connection conn;
00324 DbRetVal rv = conn.open(userName, password);
00325 if (rv != OK) return ErrSysInit;
00326 DatabaseManager *dbMgr = (DatabaseManager*) conn.getDatabaseManager();
00327 if (dbMgr == NULL) { printError(ErrSysInit, "Auth failed\n"); return ErrSysInit; }
00328 if (!tabDefinition)
00329 {
00330 Table *table = dbMgr->openTable(tableName);
00331 if (table == NULL) { conn.close(); return ErrBadCall; }
00332 rv = conn.startTransaction();
00333 if (rv != OK) { dbMgr->closeTable(table); conn.close(); return ErrBadCall; }
00334 table->truncate();
00335 conn.commit();
00336 dbMgr->closeTable(table);
00337 }
00338 else
00339 {
00340 rv = dbMgr->dropTable(tableName);
00341 }
00342 conn.close();
00343
00344 return rv;
00345 }
00346
00347 DbRetVal CacheTableLoader::refresh()
00348 {
00349 return OK;
00350 }
00351
00352 DbRetVal CacheTableLoader::recoverAllCachedTables()
00353 {
00354 FILE *fp;
00355 Connection conn;
00356 DbRetVal rv = conn.open(userName, password);
00357
00358
00359 fp = fopen(Conf::config.getTableConfigFile(),"r");
00360 if( fp == NULL ) {
00361 printError(ErrSysInit, "cachetable.conf file does not exist");
00362 return OK;
00363 }
00364 conn.close();
00365
00366 char tablename[IDENTIFIER_LENGTH];
00367 int mode;
00368 rv = OK;
00369 while(!feof(fp))
00370 {
00371 fscanf(fp, "%d:%s\n", &mode, tablename);
00372 if (mode ==2 )
00373 continue;
00374 printDebug(DM_Gateway, "Recovering Table from target db: %s\n", tablename);
00375 setTable(tablename);
00376 printf("Recovering table %s\n", tablename);
00377 rv = load();
00378 if (rv != OK) return rv;
00379 }
00380 fclose(fp);
00381 return OK;
00382 }
00383