1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
18 #include <SqlFactory.h>
19 #include <SqlStatement.h>
20 #include <SqlOdbcConnection.h>
21 #include <SqlOdbcStatement.h>
23 AbsSqlConnection
*conn
=NULL
;
24 AbsSqlStatement
*stmt
=NULL
;
25 DataType pkFldType
= typeUnknown
;
29 printf("Usage: cacheverify [-U username] [-P passwd] -t tablename [-p] [-f]\n");
30 printf(" username -> username to connect with csql.\n");
31 printf(" passwd -> password for the above username to connect with csql.\n");
32 printf(" tablename -> cached table name in csql from target db.\n");
33 printf(" p -> verification at primary key field level\n");
34 printf(" f -> verification at record level\n");
35 printf(" ? -> help\n");
39 typedef struct PrimaryKeyField
{
45 typedef struct FldVal
{
58 int cmpIntPkFldVal (const void *pkfv1
, const void *pkfv2
)
60 PrimKeyFldVal
*p1
= (PrimKeyFldVal
*)pkfv1
;
61 PrimKeyFldVal
*p2
= (PrimKeyFldVal
*)pkfv2
;
63 result
=AllDataType::compareVal(&p1
->val
,&p2
->val
,OpLessThan
,pkFldType
);
64 if (result
) return -1;
68 int cmpStringPkFldVal (const void *pkfv1
, const void *pkfv2
)
70 PrimKeyFldVal
*p1
= (PrimKeyFldVal
*)pkfv1
;
71 PrimKeyFldVal
*p2
= (PrimKeyFldVal
*)pkfv2
;
72 char *val1
= (char *) &p1
->val
;
73 char *val2
= (char *) &p2
->val
;
74 if (strcmp(val1
, val2
) < 0) return -1;
78 int cmpIntRecord (const void *pkfv1
, const void *pkfv2
)
80 Record
*p1
= (Record
*)pkfv1
;
81 Record
*p2
= (Record
*)pkfv2
;
82 if (AllDataType::compareVal(&p1
->val
, &p2
->val
, OpLessThan
, pkFldType
))
87 int cmpStringRecord (const void *pkfv1
, const void *pkfv2
)
89 Record
*p1
= (Record
*)pkfv1
;
90 Record
*p2
= (Record
*)pkfv2
;
91 char *val1
= (char *) &p1
->val
;
92 char *val2
= (char *) &p2
->val
;
93 if (strcmp(val1
, val2
) < 0) return -1;
97 DbRetVal
verifyCount(const char *tblName
, long numTuples
)
100 AbsSqlConnection
*adConn
= SqlFactory::createConnection(CSqlAdapter
);
101 DbRetVal rv
= adConn
->connect(I_USER
,I_PASS
);
102 if (rv
!= OK
) { delete adConn
; return ErrSysInit
; }
103 AbsSqlStatement
*adStmt
= SqlFactory::createStatement(CSqlAdapter
);
104 adStmt
->setConnection(adConn
);
107 sprintf(statement
, "select count(*) from %s;", tblName
);
108 rv
= adConn
->beginTrans();
109 rv
= adStmt
->prepare(statement
);
111 delete adStmt
; delete adConn
;
112 printError(rv
, "Prepare failed");
115 SqlOdbcConnection
*adcon
= (SqlOdbcConnection
*)adConn
;
116 adStmt
->bindField(1, &count1
);
117 rv
= adStmt
->execute(rows
);
119 delete adStmt
; delete adConn
;
120 printError(rv
, "Execute failed");
123 if (adStmt
->fetch()== NULL
) {
124 delete adStmt
; delete adConn
;
125 printError(ErrSysInternal
, "Fetch failed");
126 return ErrSysInternal
;
130 printf("\nNumber of Records:\n");
131 printf("-------------------+-------------------+-------------------+\n");
132 printf(" Data | In CSQL | In TargetDB |\n");
133 printf("-------------------+-------------------+-------------------+\n");
134 printf(" No. Of Records | %-6ld | %-6ld |\n", numTuples
, count1
);
135 printf("-------------------+-------------------+-------------------+\n");
136 delete adStmt
; delete adConn
;
140 DbRetVal
verifyMismatchingRecords(const char *tblName
, int option
)
142 char csqlstatement
[256];
143 char tdbstatement
[256];
144 AbsSqlConnection
*trgtDbCon
= SqlFactory::createConnection(CSqlAdapter
);
145 DbRetVal rv
= trgtDbCon
->connect(I_USER
,I_PASS
);
147 delete trgtDbCon
; return ErrSysInit
;
149 AbsSqlStatement
*trgtDbStmt
= SqlFactory::createStatement(CSqlAdapter
);
150 trgtDbStmt
->setConnection(trgtDbCon
);
152 char fieldName
[IDENTIFIER_LENGTH
];
154 SqlOdbcStatement
*ostmt
= (SqlOdbcStatement
*) trgtDbStmt
;
155 ostmt
->getPrimaryKeyFieldName((char*)tblName
, fieldName
);
156 if (fieldName
[0] == '\0') {
157 delete trgtDbStmt
; delete trgtDbCon
;
158 printError(ErrSysInternal
, "Primary key does not exist on table %s", tblName
);
161 printf("\nPrimary key field name is \'%s\'\n", fieldName
);
164 //will work for single field primary keys
165 //composite need to be worked out
166 FieldInfo
*fInfo
= new FieldInfo();
167 ((SqlStatement
*)stmt
)->getFieldInfo(tblName
, fieldName
, fInfo
);
168 pkFldType
= fInfo
->type
;
169 if (pkFldType
== typeString
) pkFldLen
= os::align(fInfo
->length
+ 1);
170 else pkFldLen
= fInfo
->length
;
171 void *pkval
= AllDataType::alloc(pkFldType
, pkFldLen
);
172 memset(pkval
, 0, pkFldLen
);
173 //List for primary key field values present in csql server
175 List valListInTrgtDb
;
179 sprintf(csqlstatement
, "select %s from %s;", fieldName
, tblName
);
180 sprintf(tdbstatement
, "select %s from %s where %s=?;", fieldName
, tblName
, fieldName
);
181 rv
= stmt
->prepare(csqlstatement
);
183 delete trgtDbStmt
; delete trgtDbCon
;
184 printError(rv
, "Prepare failed");
187 rv
= trgtDbStmt
->prepare(tdbstatement
);
189 delete trgtDbStmt
; delete trgtDbCon
;
190 printError(rv
, "Prepare failed");
193 stmt
->bindField(1, pkval
);
194 trgtDbStmt
->bindField(1, pkval
);
195 rv
= conn
->beginTrans();
198 delete trgtDbStmt
; delete trgtDbCon
;
199 printError(rv
, "BeginTrans failed");
202 rv
= stmt
->execute(rows
);
205 delete trgtDbStmt
; delete trgtDbCon
;
206 printError(ErrSysInternal
, "Execute failed");
209 rv
= trgtDbCon
->beginTrans();
210 int pkFldValSize
= sizeof(PrimKeyFldVal
) - 1 + pkFldLen
;
211 while(stmt
->fetch(rv
) != NULL
&& rv
== OK
) {
212 PrimKeyFldVal
*pkFldVal
= (PrimKeyFldVal
*) malloc (pkFldValSize
);
213 memset(pkFldVal
, 0, pkFldValSize
);
214 AllDataType::copyVal(&pkFldVal
->val
, pkval
, pkFldType
, pkFldLen
);
215 pkFldVal
->inCsql
= true;
216 pkFldVal
->inTrgtDb
= true;
217 SqlStatement::setParamValues(trgtDbStmt
,1, pkFldType
,pkFldLen
,pkval
);
218 trgtDbStmt
->execute(rows
);
219 if (trgtDbStmt
->fetch(rv
) != NULL
) {
220 sameInBothDb
.append(pkFldVal
);
222 pkFldVal
->inTrgtDb
= false;
223 missingList
.append(pkFldVal
);
233 // List for primary key field values present in target DB
234 sprintf(tdbstatement
, "select %s from %s;", fieldName
, tblName
);
235 sprintf(csqlstatement
, "select %s from %s where %s=?;", fieldName
, tblName
, fieldName
);
236 rv
= trgtDbCon
->beginTrans();
237 rv
= trgtDbStmt
->prepare(tdbstatement
);
239 delete trgtDbStmt
; delete trgtDbCon
;
240 printError(rv
, "Prepare failed");
243 stmt
->prepare(csqlstatement
);
244 stmt
->bindField(1, pkval
);
245 trgtDbStmt
->bindField(1, pkval
);
246 rv
= trgtDbStmt
->execute(rows
);
248 delete trgtDbStmt
; delete trgtDbCon
;
249 printError(rv
, "Execute failed\n");
253 while (trgtDbStmt
->fetch() != NULL
) {
254 PrimKeyFldVal
*pkFldVal
= (PrimKeyFldVal
*) malloc (pkFldValSize
);
255 memset(pkFldVal
, 0, pkFldValSize
);
256 AllDataType::copyVal(&pkFldVal
->val
, pkval
, pkFldType
, pkFldLen
);
257 pkFldVal
->inCsql
= true;
258 pkFldVal
->inTrgtDb
= true;
259 SqlStatement::setParamValues(stmt
, 1, pkFldType
, pkFldLen
, pkval
);
261 if (stmt
->fetch(rv
) == NULL
&& rv
==OK
) {
262 pkFldVal
->inCsql
= false;
263 missingList
.append(pkFldVal
);
273 PrimKeyFldVal *pkArr = NULL;
274 ListIterator missIter = missingList.getIterator();
275 int nEitherDb = missingList.size();
277 pkArr = (PrimKeyFldVal *) malloc(nEitherDb * pkFldValSize);
279 char *ptr = (char *)pkArr;
280 while (missIter.hasElement()) {
281 PrimKeyFldVal *elm = (PrimKeyFldVal *)missIter.nextElement();
282 memcpy(ptr, elm, pkFldValSize);
285 if (pkFldType == typeByteInt || pkFldType == typeShort ||
286 pkFldType == typeInt || pkFldType == typeLong ||
287 pkFldType == typeLongLong)
288 qsort (pkArr, nEitherDb, pkFldValSize, cmpIntPkFldVal);
289 else if (pkFldType == typeString)
290 qsort (pkArr, nEitherDb, pkFldValSize, cmpStringPkFldVal);
293 // Sorting the primary key field values present in either of the databases
294 bool missingRecords
= false;
295 printf("\nMissing Records: Marked by \'X\'\n");
296 printf("-------------------+-------------------+-------------------+\n");
297 printf(" Primary Key | In CSQL | In Target DB |\n");
298 printf("-------------------+-------------------+-------------------+\n");
299 /* if (missingList.size()) {
300 char *ptr = (char *) pkArr;
301 missingRecords = true;
302 for (int i = 0; i < nEitherDb; i++) {
303 PrimKeyFldVal *pkFldVal = (PrimKeyFldVal *) ptr;
305 int nChrs = AllDataType::printVal(&pkFldVal->val, pkFldType,
308 while (nChrs-- != 0) printf(" ");
309 if (pkFldVal->inCsql == false) {
312 else if (pkFldVal->inTrgtDb == false) {
317 printf("-------------------+-------------------+-------------------+\n");
320 printf(" No missing Records in either of the databases |\n");
321 printf("-------------------+-------------------+-------------------+\n");
331 ListIterator missIter
= missingList
.getIterator();
332 if (missingList
.size()) {
333 missingRecords
= true;
334 while (missIter
.hasElement()) {
335 PrimKeyFldVal
*pkFldVal
= (PrimKeyFldVal
*) missIter
.nextElement();
337 int nChrs
= AllDataType::printVal(&pkFldVal
->val
, pkFldType
,
340 while (nChrs
-- != 0) printf(" ");
341 if (pkFldVal
->inCsql
== false) {
344 else if (pkFldVal
->inTrgtDb
== false) {
348 printf("-------------------+-------------------+-------------------+\n");
351 printf(" No missing Records in either of the databases |\n");
352 printf("-------------------+-------------------+-------------------+\n");
355 // Need to clean up the mess that is no more required
358 PrimKeyFldVal
*pkFldVal
= NULL
;
359 while ((pkFldVal
= (PrimKeyFldVal
*) missIter
.nextElement()) != NULL
)
364 //statement to fetch the values from the database
365 sprintf(csqlstatement
, "select * from %s where %s = ?;", tblName
, fieldName
);
366 rv
= stmt
->prepare(csqlstatement
);
367 rv
= trgtDbStmt
->prepare(csqlstatement
);
369 delete trgtDbStmt
; delete trgtDbCon
;
370 printError(rv
, "Prepare failed");
374 // need to bind each field with buffer which is list of field values
375 SqlStatement
*sqlStmt
= (SqlStatement
*) stmt
;
376 List fldNameList
= sqlStmt
->getFieldNameList(tblName
, rv
);
377 ListIterator iter
= fldNameList
.getIterator();
378 Identifier
*fname
= NULL
;
379 FieldInfo
*fldInfo
= new FieldInfo();
380 List cfieldValueList
;
381 List tfieldValueList
;
383 // List to hold all the records that are present in both the databases
386 while (iter
.hasElement()) {
387 fname
= (Identifier
*) iter
.nextElement();
389 delete trgtDbStmt
; delete trgtDbCon
;
391 printError(ErrSysFatal
, "Fatal:Field Name list has NULL");
394 rv
= sqlStmt
->getFieldInfo(tblName
, fname
->name
, fldInfo
);
395 if (ErrNotFound
== rv
) {
396 delete trgtDbStmt
; delete trgtDbCon
;
398 printError(ErrSysInternal
, "Field %s does not exist in table", fname
->name
);
399 return ErrSyntaxError
;
401 FldVal
*cfldVal
= new FldVal();
402 FldVal
*tfldVal
= new FldVal();
403 cfldVal
->type
= fldInfo
->type
;
404 tfldVal
->type
= fldInfo
->type
;
405 if(cfldVal
->type
== typeString
)
406 cfldVal
->length
= os::align(fldInfo
->length
+ 1);
407 else cfldVal
->length
= fldInfo
->length
;
408 cfldVal
->value
= AllDataType::alloc(fldInfo
->type
, cfldVal
->length
);
409 tfldVal
->value
= AllDataType::alloc(fldInfo
->type
, cfldVal
->length
);
410 memset(cfldVal
->value
, 0, cfldVal
->length
);
411 memset(tfldVal
->value
, 0, cfldVal
->length
);
412 cfieldValueList
.append(cfldVal
);
413 tfieldValueList
.append(tfldVal
);
414 stmt
->bindField(paramPos
, cfldVal
->value
);
415 trgtDbStmt
->bindField(paramPos
, tfldVal
->value
);
420 while ((fname
=(Identifier
*)iter
.nextElement())!= NULL
) delete fname
;
423 // WHERE parameter should be binded with the primary key field value of the list that is present in both the databases
424 int recSize
= 2 * sizeof(List
) + pkFldLen
;
425 ListIterator sameValIter
= sameInBothDb
.getIterator();
426 PrimKeyFldVal
*sameElem
= NULL
;
427 while((sameElem
= (PrimKeyFldVal
*)sameValIter
.nextElement()) != NULL
) {
429 trgtDbCon
->beginTrans();
430 SqlStatement::setParamValues(stmt
, 1, pkFldType
, pkFldLen
,
432 SqlStatement::setParamValues(trgtDbStmt
, 1, pkFldType
, pkFldLen
,
434 rv
= stmt
->execute(rows
);
435 rv
= trgtDbStmt
->execute(rows
);
437 delete trgtDbStmt
; delete trgtDbCon
;
438 printError(rv
, "Execute failed");
441 if (stmt
->fetch() != NULL
&& trgtDbStmt
->fetch() != NULL
) {
442 Record
*rec
= (Record
*) malloc(recSize
);
443 memset(rec
, 0, recSize
);
444 AllDataType::copyVal(&rec
->val
, &sameElem
->val
,
445 pkFldType
, pkFldLen
);
446 ListIterator cfldValIter
= cfieldValueList
.getIterator();
447 ListIterator tfldValIter
= tfieldValueList
.getIterator();
449 while (cfldValIter
.hasElement() && tfldValIter
.hasElement()) {
450 FldVal
*cfldVal
= (FldVal
*) cfldValIter
.nextElement();
451 FldVal
*tfldVal
= (FldVal
*) tfldValIter
.nextElement();
452 if (AllDataType::compareVal(cfldVal
->value
, tfldVal
->value
, OpEquals
, cfldVal
->type
, cfldVal
->length
) == false) {
453 FldVal
*cfldValue
= new FldVal();
454 FldVal
*tfldValue
= new FldVal();
455 cfldValue
->type
= cfldVal
->type
;
456 tfldValue
->type
= cfldVal
->type
;
457 cfldValue
->length
= cfldVal
->length
;
458 tfldValue
->length
= cfldVal
->length
;
459 cfldValue
->value
= AllDataType::alloc(cfldValue
->type
, cfldValue
->length
);
460 tfldValue
->value
= AllDataType::alloc(cfldValue
->type
, cfldValue
->length
);
461 cfldValue
->pos
= pos
; tfldValue
->pos
= pos
;
462 memset(cfldValue
->value
, 0, cfldValue
->length
);
463 memset(tfldValue
->value
, 0, cfldValue
->length
);
464 AllDataType::cachecopyVal(cfldValue
->value
, cfldVal
->value
, cfldVal
->type
, cfldVal
->length
);
465 AllDataType::cachecopyVal(tfldValue
->value
, tfldVal
->value
, cfldVal
->type
, cfldVal
->length
);
466 rec
->csqlFldValList
.append(cfldValue
);
467 rec
->tdbFldValList
.append(tfldValue
);
471 if (rec
->csqlFldValList
.size()) recordList
.append(rec
);
478 // stmt->free(); // dont free it just yet needed further up
481 // freeing the field value list that is present in both the databases
482 PrimKeyFldVal
*pkFldVal
= NULL
;
483 while ((pkFldVal
= (PrimKeyFldVal
*) sameValIter
.nextElement()) != NULL
)
485 sameInBothDb
.reset();
487 // sort the records based on Primary key that is present in both the databases
488 int size = recordList.size();
489 char *arr = (char *) malloc(size * recSize);
490 memset(arr, 0, size * recSize);
493 ListIterator recIter = recordList.getIterator();
494 while (recIter.hasElement()) {
495 Record *rec = (Record *) recIter.nextElement();
496 memcpy(ptr, rec, recSize);
499 if (pkFldType == typeByteInt || pkFldType == typeShort ||
500 pkFldType == typeInt || pkFldType == typeLong ||
501 pkFldType == typeLongLong)
502 qsort(arr, size, recSize, cmpIntRecord);
503 else if (pkFldType == typeString)
504 qsort(arr, size, recSize, cmpStringRecord);
508 bool isConsistent
= true;
509 printf("\nInconsistent Records for the same key:\n");
510 printf("-------------------+-------------------+-------------------+-------------------+\n");
511 printf(" %-16s | %-16s | %-16s | %-16s |\n", "Primary Key", "Field Name", "In CSQL", "In Trgt DB");
512 printf("-------------------+-------------------+-------------------+-------------------+\n");
514 char *fldname = NULL;
515 for (int i = 0; i < size; i++) {
516 Record *recd = (Record *) ptr;
517 ListIterator csqlIt = recd->csqlFldValList.getIterator();
518 ListIterator trgtDbIt = recd->tdbFldValList.getIterator();
520 while (csqlIt.hasElement() && trgtDbIt.hasElement()) {
521 FldVal *csqlElem = (FldVal *) csqlIt.nextElement();
522 FldVal *trgtDbElem = (FldVal *) trgtDbIt.nextElement();
523 fldname = ((SqlStatement *) stmt)->getFieldName(csqlElem->pos);
524 if (AllDataType::compareVal(csqlElem->value, trgtDbElem->value, OpEquals, csqlElem->type, csqlElem->length) == false) {
525 isConsistent = false;
528 int cnt = AllDataType::printVal(&recd->val,
529 pkFldType, pkFldLen);
531 while (cnt-- != 0) printf(" ");
532 printf("| %-16s | ", fldname);
535 else printf(" | %-16s | ", fldname);
536 int cnt = AllDataType::printVal(csqlElem->value, csqlElem->type, csqlElem->length);
541 cnt = AllDataType::printVal(trgtDbElem->value, trgtDbElem->type, trgtDbElem->length);
551 ListIterator recIter
= recordList
.getIterator();
553 char *fldname
= NULL
;
554 if (recordList
.size()) {
555 isConsistent
= false;
556 while(recIter
.hasElement()) {
557 Record
*recd
= (Record
*) recIter
.nextElement();
558 ListIterator csqlIt
= recd
->csqlFldValList
.getIterator();
559 ListIterator trgtDbIt
= recd
->tdbFldValList
.getIterator();
561 while (csqlIt
.hasElement()) {
562 FldVal
*csqlElem
= (FldVal
*) csqlIt
.nextElement();
563 FldVal
*trgtDbElem
= (FldVal
*) trgtDbIt
.nextElement();
564 fldname
= ((SqlStatement
*) stmt
)->getFieldName(csqlElem
->pos
);
567 int cnt
= AllDataType::printVal(&recd
->val
,
568 pkFldType
, pkFldLen
);
570 while (cnt
-- != 0) printf(" ");
571 printf("| %-16s | ", fldname
);
574 else printf(" | %-16s | ", fldname
);
575 int cnt
= AllDataType::printVal(csqlElem
->value
, csqlElem
->type
, csqlElem
->length
);
577 while (cnt
-- != 0) printf(" ");
579 cnt
= AllDataType::printVal(trgtDbElem
->value
, trgtDbElem
->type
, trgtDbElem
->length
);
581 while (cnt
-- != 0) printf(" ");
587 if (isConsistent
== true && missingRecords
== false)
588 printf(" The data is consistent in both the databases |\n");
589 else if (isConsistent
== true && missingRecords
== true)
590 printf(" The data is consistent for the records with the same key |\n");
591 printf("-------------------+-------------------+-------------------+-------------------+\n");
593 // clean up all the mess before leaving
597 while((itm
= (Record
*) recIter
.nextElement()) != NULL
) {
598 ListIterator cit
= (ListIterator
) itm
->csqlFldValList
.getIterator();
599 ListIterator tit
= (ListIterator
) itm
->tdbFldValList
.getIterator();
600 FldVal
*cfldVal
= NULL
; FldVal
*tfldVal
= NULL
;
601 while( (cfldVal
= (FldVal
*) cit
.nextElement()) != NULL
&&
602 (tfldVal
= (FldVal
*) tit
.nextElement()) != NULL
) {
603 free (cfldVal
->value
); free (tfldVal
->value
);
604 delete cfldVal
; delete tfldVal
;
606 cit
.reset(); tit
.reset();
610 delete trgtDbStmt
; delete trgtDbCon
;
614 int main(int argc
, char **argv
)
616 char username
[IDENTIFIER_LENGTH
];
618 char password
[IDENTIFIER_LENGTH
];
621 char tableName
[IDENTIFIER_LENGTH
];
623 bool tableNameSpecified
= false;
625 while ((c
= getopt(argc
, argv
, "U:P:t:pf?")) != EOF
)
629 case 'U' : { strcpy(username
, argv
[optind
- 1]); opt
=10; break; }
630 case 'P' : { strcpy(password
, argv
[optind
- 1]); opt
=10; break; }
631 case 't' : { strcpy(tableName
, argv
[optind
- 1]);
632 if (opt
==10) opt
= 2;
633 tableNameSpecified
= true;
636 case 'p' : { opt
= 3; break; } //verify at primary key level
637 case 'f' : { opt
= 4; break; } //verify at record level
638 case '?' : { opt
= 10; break; } //print help
648 if (!tableNameSpecified
) {
649 printError(ErrSysInternal
, "Table name is not specified. Check usage with ?");
653 //printf("%s %s \n", username, password);
654 if (username
[0] == '\0' )
656 strcpy(username
, I_USER
);
657 strcpy(password
, I_PASS
);
660 conn
= SqlFactory::createConnection(CSqlDirect
);
661 DbRetVal rv
= conn
->connect(username
, password
);
663 printError(rv
, "Authentication failed");
667 stmt
= SqlFactory::createStatement(CSqlDirect
);
668 stmt
->setConnection(conn
);
670 List tableNameList
= stmt
->getAllTableNames(rv
);
671 ListIterator it
= tableNameList
.getIterator();
672 while (it
.hasElement()) {
673 Identifier
*elem
= (Identifier
*) it
.nextElement();
674 if (strcmp(elem
->name
, tableName
) == 0) {
680 fp
= fopen(Conf::config
.getTableConfigFile(),"r");
683 delete stmt
; delete conn
;
684 printError(ErrSysInternal
, "csqltable.conf file does not exist");
687 char tablename
[IDENTIFIER_LENGTH
];
688 char fieldname
[IDENTIFIER_LENGTH
];
689 char condition
[IDENTIFIER_LENGTH
];
690 char field
[IDENTIFIER_LENGTH
];
691 char dsnName
[IDENTIFIER_LENGTH
];
694 bool isCached
= false;
696 fscanf(fp
, "%d %s %s %s %s %s\n", &mode
, tablename
,fieldname
,condition
,field
,dsnName
);
697 if (strcmp(tableName
, tablename
) == 0) {
707 sprintf(statement
, "select count(*) from %s;", tableName
);
708 rv
= stmt
->prepare(statement
);
711 delete stmt
; delete conn
;
714 rv
= conn
->beginTrans();
717 delete stmt
; delete conn
;
720 stmt
->bindField(1, &numTuples
);
724 delete stmt
; delete conn
;
727 void *tuple
= stmt
->fetch(rv
);
732 if (isCached
== false) {
734 printError(ErrSysInternal
, "The table \'%s\' is not cached", tableName
);
735 delete stmt
; delete conn
; return 5;
739 rv
= verifyCount(tableName
, numTuples
);
741 conn
->disconnect(); delete stmt
; delete conn
; return 7;
745 if (opt
== 3 || opt
== 4) {
746 rv
= verifyCount(tableName
, numTuples
);
748 conn
->disconnect(); delete stmt
; delete conn
; return 8;
750 rv
= verifyMismatchingRecords(tableName
, opt
);
752 conn
->disconnect(); delete stmt
; delete conn
; return 9;
755 conn
->disconnect(); delete stmt
; delete conn
;