00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <CSql.h>
00017 #include <list>
00018 #include <SqlFactory.h>
00019 #include <SqlOdbcConnection.h>
00020 #include <SqlOdbcStatement.h>
00021
00022 void printUsage()
00023 {
00024 printf("Usage: cacheverify [-U username] [-P passwd] -t tablename\n"
00025 " [-p] [-f]\n");
00026 printf(" username -> username to connect with csql.\n");
00027 printf(" passwd -> password for the above username to connect with csql.\n");
00028 printf(" tablename -> cached table name in csql from target db.\n");
00029 printf(" p -> verification at primary key field level\n");
00030 printf(" f -> verification at record level\n");
00031 printf(" ? -> help\n");
00032 return;
00033 }
00034
00035 typedef struct PrimaryKeyField {
00036 int val;
00037 bool inCsql;
00038 bool inTrgtDb;
00039 } PrimKeyFldVal;
00040
00041 using namespace std;
00042 bool cmp(const PrimKeyFldVal *a, const PrimKeyFldVal *b)
00043 {
00044 return a->val < b->val;
00045 }
00046
00047 DbRetVal verifyCount(const char *tblName, long numTuples)
00048 {
00049 char statement[200];
00050 AbsSqlConnection *con = SqlFactory::createConnection(CSqlAdapter);
00051 DbRetVal rv = con->connect("root", "manager");
00052 if (rv != OK) { delete con; return ErrSysInit; }
00053 AbsSqlStatement *stmt = SqlFactory::createStatement(CSqlAdapter);
00054 stmt->setConnection(con);
00055 int count = 0;
00056 int rows = 0;
00057 sprintf(statement, "select count(*) from %s;", tblName);
00058 rv = con->beginTrans();
00059 rv = stmt->prepare(statement);
00060 if(rv != OK) {
00061 delete stmt; delete con;
00062 printError(rv, "Prepare failed\n");
00063 return rv;
00064 }
00065 stmt->bindField(1, &count);
00066 rv = stmt->execute(rows);
00067 if(rv != OK) {
00068 delete stmt; delete con;
00069 printError(rv, "Execute failed\n");
00070 return rv;
00071 }
00072 if (stmt->fetch()== NULL) {
00073 delete stmt; delete con;
00074 printError(ErrSysInternal, "Fetch failed\n");
00075 return ErrSysInternal;
00076 }
00077 con->commit();
00078 printf("--------------------+-----------------+----------------------+\n");
00079 printf(" Data | In CSQL | In TargetDb |\n");
00080 printf("--------------------+-----------------+----------------------+\n");
00081 printf(" Number of Tuples | %5d | %5d |\n", numTuples, count);
00082 printf("--------------------+-----------------+----------------------+\n");
00083 delete stmt; delete con;
00084 return OK;
00085 }
00086
00087 DbRetVal verifyPrimKeyFldVal(const char *tblName)
00088 {
00089 Connection conn;
00090 DbRetVal rv = conn.open("root", "manager");
00091 if (rv != OK) return ErrSysInit;
00092 DatabaseManager *dbMgr = (DatabaseManager *) conn.getDatabaseManager();
00093 if (dbMgr == NULL) {
00094 conn.close();
00095 printError(ErrSysInit, "Auth failed");
00096 return ErrSysInit;
00097 }
00098 Table *table = dbMgr->openTable(tblName);
00099 if(table == NULL) {
00100 conn.close();
00101 printError(ErrNotExists, "Table \'%s\' does not exist", tblName);
00102 return ErrNotExists;
00103 }
00104
00105 char statement[200];
00106 AbsSqlConnection *con = SqlFactory::createConnection(CSqlAdapter);
00107 rv = con->connect("root", "manager");
00108 if (rv != OK) { delete con; return ErrSysInit; }
00109 AbsSqlStatement *stmt = SqlFactory::createStatement(CSqlAdapter);
00110 stmt->setConnection(con);
00111 char fieldName[IDENTIFIER_LENGTH];
00112 fieldName[0] = '\0';
00113 SqlOdbcStatement *ostmt = (SqlOdbcStatement*) stmt;
00114 ostmt->getPrimaryKeyFieldName((char*)tblName, fieldName);
00115 if (fieldName[0] == '\0') {
00116 printError(ErrNotExists, "Primary key does not exist.");
00117 return ErrNotExists;
00118 }
00119 printf("Primary key field name is \'%s\'\n", fieldName);
00120 FieldInfo *fldInfo = new FieldInfo();
00121 table->getFieldInfo(fieldName, fldInfo);
00122
00123 int csqlVal = 0;
00124 List valListInCsql;
00125 table->bindFld(fieldName, &csqlVal);
00126 conn.startTransaction();
00127 table->setCondition(NULL);
00128 rv = table->execute();
00129 if(rv != OK) {
00130 delete stmt; delete con;
00131 printError(rv, "Execute failed\n");
00132 return rv;
00133 }
00134 while(true) {
00135 void* tuple = table->fetch(rv);
00136 if (tuple == NULL) break;
00137 PrimKeyFldVal *pkFldVal = new PrimKeyFldVal();
00138 pkFldVal->val = csqlVal;
00139 pkFldVal->inCsql = true;
00140 pkFldVal->inTrgtDb = true;
00141 valListInCsql.append(pkFldVal);
00142 }
00143 conn.commit();
00144 table->close();
00145 dbMgr->closeTable(table);
00146 int trgtDbVal = 0;
00147 int rows = 0;
00148 List valListInTrgtDb;
00149 sprintf(statement, "select %s from %s;", fieldName, tblName);
00150 rv = con->beginTrans();
00151 rv = stmt->prepare(statement);
00152 if(rv != OK) {
00153 delete stmt; delete con;
00154 printError(rv, "Prepare failed\n");
00155 return rv;
00156 }
00157 stmt->bindField(1, &trgtDbVal);
00158 rv = stmt->execute(rows);
00159 if(rv != OK) {
00160 delete stmt; delete con;
00161 printError(rv, "Execute failed\n");
00162 return rv;
00163 }
00164 while (stmt->fetch() != NULL) {
00165 PrimKeyFldVal *pkFldVal = new PrimKeyFldVal();
00166 pkFldVal->val = trgtDbVal;
00167 pkFldVal->inCsql = true;
00168 pkFldVal->inTrgtDb = true;
00169 valListInTrgtDb.append(pkFldVal);
00170 }
00171 con->commit();
00172 delete stmt; delete con;
00173
00174 List diffInValList;
00175 ListIterator csqlValIter = valListInCsql.getIterator();
00176 ListIterator trgtDbValIter = valListInTrgtDb.getIterator();
00177 PrimKeyFldVal *csqlelem, *trgtdbelem;
00178 while( (csqlelem = (PrimKeyFldVal *) csqlValIter.nextElement()) != NULL) {
00179 while ( (trgtdbelem = (PrimKeyFldVal *) trgtDbValIter.nextElement()) != NULL) {
00180 if (csqlelem->val == trgtdbelem->val) {
00181 trgtDbValIter.reset();
00182 break;
00183 }
00184 }
00185 if (trgtdbelem == NULL) {
00186 csqlelem->inTrgtDb = false;
00187 PrimKeyFldVal *elm = new PrimKeyFldVal();
00188 *elm = * csqlelem;
00189 diffInValList.append(elm);
00190 trgtDbValIter.reset();
00191 }
00192 }
00193 csqlValIter.reset();
00194
00195 while((trgtdbelem = (PrimKeyFldVal *)trgtDbValIter.nextElement()) != NULL) {
00196 while((csqlelem = (PrimKeyFldVal *)csqlValIter.nextElement()) != NULL) {
00197 if (trgtdbelem->val == csqlelem->val) {
00198 csqlValIter.reset();
00199 break;
00200 }
00201 }
00202 if (csqlelem == NULL) {
00203 trgtdbelem->inCsql = false;
00204 PrimKeyFldVal *elm = new PrimKeyFldVal();
00205 *elm = *trgtdbelem;
00206 diffInValList.append(elm);
00207 csqlValIter.reset();
00208 }
00209 }
00210 list <PrimKeyFldVal *> li;
00211 ListIterator diffValIter = diffInValList.getIterator();
00212 if (diffInValList.size()) {
00213 PrimKeyFldVal *elem = NULL;
00214 while ((elem = (PrimKeyFldVal *) diffValIter.nextElement()) != NULL )
00215 li.push_back(elem);
00216
00217 list<PrimKeyFldVal *>::iterator it;
00218 li.sort(cmp);
00219 printf("-----------------+-------------------+-----------------------+\n");
00220 printf("%10s | not in csql | not in targetdb |\n", fieldName);
00221 printf("-----------------+-------------------+-----------------------+\n");
00222 for (it = li.begin(); it != li.end(); it++) {
00223 if ((*it)->inCsql == false)
00224 printf(" %6d | X | |\n", (*it)->val);
00225 else if ((*it)->inTrgtDb == false)
00226 printf(" %6d | | X |\n", (*it)->val);
00227 }
00228 printf("-----------------+-------------------+-----------------------+\n");
00229 }
00230 else printf("The data in both the servers is consistent\n");
00231 li.clear();
00232 PrimKeyFldVal *elem;
00233 while((elem = (PrimKeyFldVal *)trgtDbValIter.nextElement()) != NULL)
00234 delete elem;
00235 while((elem = (PrimKeyFldVal *)csqlValIter.nextElement()) != NULL)
00236 delete elem;
00237 while ((elem = (PrimKeyFldVal *) diffValIter.nextElement()) != NULL )
00238 delete elem;
00239 diffInValList.reset();
00240 valListInTrgtDb.reset();
00241 valListInCsql.reset();
00242 return OK;
00243 }
00244
00245 int main(int argc, char **argv)
00246 {
00247 char username[IDENTIFIER_LENGTH];
00248 username [0] = '\0';
00249 char password[IDENTIFIER_LENGTH];
00250 password [0] = '\0';
00251 int c = 0, opt = 10;
00252 char tableName[IDENTIFIER_LENGTH];
00253 tableName[0] = '\0';
00254 while ((c = getopt(argc, argv, "U:P:t:pf?")) != EOF)
00255 {
00256 switch (c)
00257 {
00258 case 'U' : { strcpy(username, argv[optind - 1]); opt=10; break; }
00259 case 'P' : { strcpy(password, argv[optind - 1]); opt=10; break; }
00260 case 't' : { strcpy(tableName, argv[optind - 1]);
00261 if (opt==10) opt = 2;
00262 break;
00263 }
00264 case 'p' : { opt = 3; break; }
00265 case 'f' : { opt = 4; break; }
00266 case '?' : { opt = 10; break; }
00267 default: opt=10;
00268
00269 }
00270 }
00271 if (opt == 10) {
00272 printUsage();
00273 return 0;
00274 }
00275
00276
00277 if (username[0] == '\0' )
00278 {
00279 strcpy(username, "root");
00280 strcpy(password, "manager");
00281 }
00282 Connection conn;
00283 DbRetVal rv = conn.open(username, password);
00284 if (rv != OK) return ErrSysInit;
00285 DatabaseManager *dbMgr = (DatabaseManager *) conn.getDatabaseManager();
00286 if (dbMgr == NULL) {
00287 conn.close();
00288 printError(ErrSysInit, "Auth failed");
00289 return ErrSysInit;
00290 }
00291 Table *table = dbMgr->openTable(tableName);
00292 if(table == NULL) {
00293 conn.close();
00294 printError(ErrNotExists, "Table \'%s\' does not exist", tableName);
00295 return ErrNotExists;
00296 }
00297
00298 FILE *fp;
00299 fp = fopen(Conf::config.getTableConfigFile(),"r");
00300 if( fp == NULL ) {
00301 dbMgr->closeTable(table);
00302 conn.close();
00303 printError(ErrSysInit, "cachetable.conf file does not exist");
00304 return ErrSysInit;
00305 }
00306 char tablename[IDENTIFIER_LENGTH];
00307 int mode;
00308 bool filePresent = false;
00309 while(!feof(fp)) {
00310 fscanf(fp, "%d:%s\n", &mode, tablename);
00311 if (mode ==2 )
00312 continue;
00313 if (strcmp(tableName, tablename) == 0) {
00314 filePresent = true;
00315 break;
00316 }
00317 }
00318 fclose(fp);
00319 long numTuples = table->numTuples();
00320 dbMgr->closeTable(table);
00321 conn.close();
00322
00323 if (filePresent == false) { printError(ErrNotCached, "The table \'%s\' is not cached", tableName);
00324 return ErrNotCached;
00325 }
00326
00327 if (opt == 2) {
00328 rv = verifyCount(tableName, numTuples);
00329 if (rv != OK) return 1;
00330 }
00331
00332 if (opt == 3) {
00333 rv = verifyPrimKeyFldVal(tableName);
00334 if (rv != OK) return 2;
00335 }
00336 return 0;
00337 }