src/tools/cacheverify.cxx

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by www.databasecache.com                           *
00003  *   Contact: praba_tuty@databasecache.com                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
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     //if(! fldInfo->isPrimary) { printError(ErrBadArg, "\'%s\' is not a primary key field", fldName); return ErrBadArg; }
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     //trgtDbValIter.reset();
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; } //verify at primary key level
00265             case 'f' : { opt = 4; break; } //verify at record level
00266             case '?' : { opt = 10; break; } //print help 
00267             default: opt=10; 
00268 
00269         }
00270     }//while options
00271     if (opt == 10) {
00272         printUsage();
00273         return 0;
00274     }
00275 
00276     //printf("%s %s \n", username, password);
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 )  //just replicated table and not cached
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 }

Generated on Mon Jun 9 22:37:15 2008 for csql by  doxygen 1.4.7