00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include <algorithm>
00012 #include <fstream>
00013 #include <memory>
00014 using std::auto_ptr;
00015 #include <sstream>
00016
00017 #include "Conventions/Detector.h"
00018 #include "Conventions/SimFlag.h"
00019
00020 #include "DatabaseInterface/Dbi.h"
00021 #include "DatabaseInterface/DbiExceptionLog.h"
00022 #include "DatabaseInterface/DbiDBProxy.h"
00023 #include "DatabaseInterface/DbiCascader.h"
00024 #include "DatabaseInterface/DbiConfigSet.h"
00025 #include "DatabaseInterface/DbiResultKey.h"
00026 #include "DatabaseInterface/DbiResultPtr.h"
00027 #include "DatabaseInterface/DbiSqlValPacket.h"
00028 #include "DatabaseInterface/DbiStatement.h"
00029 #include "DatabaseInterface/DbiTableProxyRegistry.h"
00030 #include "DatabaseInterface/DbiTimerManager.h"
00031 #include "DatabaseInterface/DbiValidityRec.h"
00032 #include "DatabaseInterface/DbiValRecSet.h"
00033 #include "DatabaseInterface/DbiTableProxy.h"
00034 #include "DatabaseInterface/DbiTableProxyRegistry.h"
00035 #include "DatabaseInterface/DbiWriter.h"
00036
00037 #include "DatabaseMaintenance/DbmCmdOptions.h"
00038 #include "DatabaseMaintenance/DbmLogFile.h"
00039 #include "DatabaseMaintenance/DbmModule.h"
00040 #include "DatabaseMaintenance/DbmNameFilter.h"
00041
00042 #include "LeakChecker/LeaLeakChecker.h"
00043 #include "JobControl/JobCModuleRegistry.h"
00044 #include "JobControl/JobCommand.h"
00045
00046 #include "MessageService/MsgService.h"
00047
00048 #include "TSQLStatement.h"
00049
00050 #include "Util/MsgUtil.h"
00051 #include "Validity/VldContext.h"
00052 #include "Validity/VldTimeStamp.h"
00053
00054
00055 using namespace std;
00056
00057 ClassImp(DbmModule)
00058
00059 CVSID("$Id: DbmModule.cxx,v 1.63 2007/11/11 07:41:21 rhatcher Exp $");
00060
00061 JOBMODULE(DbmModule,"DbmModule","Database Maintenance");
00062
00063
00064
00065 DbmModule::DbmModule() :
00066 fCascader(DbiTableProxyRegistry::Instance().GetCascader()),
00067 fValRecSet(0)
00068 {
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 LEA_CTOR
00091
00092
00093
00094 MSG("Dbm", Msg::kVerbose) << "Creating DbmModule" << endl;
00095
00096 }
00097
00098
00099
00100 DbmModule::~DbmModule() {
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 LEA_DTOR
00124
00125 MSG("Dbm", Msg::kVerbose) << "Destroying DbmModule" << endl;
00126
00127 ClearCache();
00128
00129 }
00130
00131
00132
00133 Bool_t DbmModule::ApplySQLFixup(UInt_t dbNo,
00134 ifstream& in,
00135 DbmLogFile& logFile,
00136 Bool_t enabled) {
00137
00138
00139
00140
00141
00142
00143
00144
00145 auto_ptr<DbiStatement> stmtDb(DbiTableProxyRegistry::Instance()
00146 .GetCascader()
00147 .CreateStatement(dbNo) );
00148 if ( ! stmtDb.get() ) {
00149 MSG("Dbm",Msg::kWarning)
00150 << "Attempting to write to non-existant cascade entry " << dbNo
00151 << endl;
00152 return kFALSE;
00153 }
00154
00155
00156
00157
00158 while ( in.peek() == 'S' ) {
00159 string line;
00160 getline(in,line);
00161 if ( line.substr(0,4) != "SQL:" ) {
00162 MSG("Dbm",Msg::kError)
00163 << "SQL Fixup line does not start: SQL: " << line
00164 << endl;
00165 return kFALSE;
00166 }
00167
00168
00169 string::size_type locSemiColon = line.rfind(';');
00170 if ( locSemiColon == string::npos ) {
00171 MSG("Dbm",Msg::kError)
00172 << "SQL Fixup line does not end with semicolon: " << line
00173 << endl;
00174 return kFALSE;
00175 }
00176 line.erase(locSemiColon+1);
00177
00178 if ( enabled ) {
00179
00180 std::string::size_type p;
00181 if((line.find("delete from ")!=std::string::npos) &&
00182 ((p=line.find("VLD"))!=std::string::npos)){
00183 std::string noVLD=line.substr(0,p);
00184 noVLD+=line.substr(p+3);
00185 stmtDb->ExecuteUpdate(noVLD.substr(4).c_str());
00186 logFile.LogMsg(line,kFALSE);
00187 if ( stmtDb->PrintExceptions() ) logFile.LogMsg(" - above command failed.",kFALSE);
00188 }
00189 stmtDb->ExecuteUpdate(line.substr(4).c_str());
00190 logFile.LogMsg(line,kFALSE);
00191 if ( stmtDb->PrintExceptions() ) logFile.LogMsg(" - above command failed.",kFALSE);
00192 }
00193 else {
00194 string msg("SQL fixup disabled. Ignoring :");
00195 msg += line;
00196 logFile.LogMsg(msg,kFALSE);
00197 }
00198
00199 }
00200 return kTRUE;
00201
00202 }
00203
00204
00205
00206 Bool_t DbmModule::BuildValRecSet(const string& tableName,UInt_t dbNo) {
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 if ( fValRecSet
00234 && ( fValRecSet->GetTableName() != (tableName+"VLD")
00235 || fValRecSet->GetDbNo() != dbNo ) ) {
00236 MSG("Dbm", Msg::kDebug) << "(Dropping Table "
00237 << fValRecSet->GetTableName() << ")" << endl;
00238 ClearCache();
00239 }
00240
00241 if ( ! fValRecSet ) {
00242 MSG("Dbm", Msg::kDebug) << "Reading Table " << tableName
00243 << "..." << endl;
00244
00245 fValRecSet = new DbiValRecSet(tableName,dbNo);
00246 }
00247
00248 int numRows = fValRecSet->GetNumRows();
00249 if ( numRows ) {
00250 MSG("Dbm", Msg::kInfo) << "Table " << tableName
00251 << " contains " << numRows
00252 << " sequence numbers" << endl;
00253 }
00254 else {
00255 MSG("Dbm", Msg::kDebug) << "Table " << tableName
00256 << " missing or empty!" << endl;
00257 }
00258
00259 return numRows > 0;
00260
00261 }
00262
00263
00264
00265 Bool_t DbmModule::CheckMemory(JobCommand *cmd) {
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 if ( cmd ) {
00291 DbmCmdOptions opts("",cmd);
00292 if ( ! opts.IsValid() ) return kFALSE;
00293 }
00294
00295
00296
00297 ClearCache();
00298
00299 LeaLeakChecker* lea = LeaLeakChecker::Instance();
00300 MSG("Dbm",Msg::kInfo) << lea << endl;
00301 DbiTableProxyRegistry::Instance().ShowStatistics();
00302
00303 return kTRUE;
00304
00305 }
00306
00307
00308
00309 void DbmModule::ClearCache() {
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 delete fValRecSet;
00332 fValRecSet = 0;
00333
00334 }
00335
00336
00337 Bool_t DbmModule::ExportTable(const string& tableName,
00338 ofstream* out,
00339 DbmLogFile& logFile,
00340 list<int>seqnos) {
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 MSG("Dbm", Msg::kInfo) << "\nExporting table "
00384 << tableName << "..." << endl;
00385
00386 if ( ! BuildValRecSet(tableName,0) ) return kFALSE;
00387
00388 int numVRecs = fValRecSet->GetNumRows();
00389 int numVRecsOut = 0;
00390 Int_t numModified = 0;
00391
00392 if ( numVRecs == 0 ) {
00393 MSG("Dbm", Msg::kInfo) << "Nothing to do: table "
00394 << tableName << " is empty!" << endl;
00395 return kTRUE;
00396 }
00397
00398 VldTimeStamp farFuture(2030,1,1,0,0,0);
00399
00400
00401 VldTimeStamp now(VldTimeStamp().GetSec() - 5*60, 0);
00402
00403 const DbiDBProxy& proxy = GetDBProxy(tableName);
00404
00405 Int_t numDataRows = 0;
00406 Bool_t writeMeta = kTRUE;
00407
00408 for ( int jvrec = 0; jvrec < numVRecs; ++jvrec ) {
00409
00410
00411 {
00412
00413
00414 const DbiValidityRec* vrec = fValRecSet->GetTableRow(jvrec);
00415 int seqNo = vrec->GetSeqNo();
00416 bool isWanted = true;
00417 if ( seqnos.size() > 0 ) {
00418 isWanted = false;
00419 int seqNoMin = 999999999;
00420 list<int>::iterator itr(seqnos.begin()), itrEnd(seqnos.end());
00421 for ( ; itr != itrEnd; ++itr ) {
00422 int seqNoMax = *itr;
00423 if ( seqNoMax < 0 ) {
00424 seqNoMax = - seqNoMax;
00425 if ( seqNo >= seqNoMin && seqNo <= seqNoMax ) isWanted = true;
00426 }
00427 else {
00428 if ( seqNo == seqNoMax ) isWanted = true;
00429 }
00430 seqNoMin = seqNoMax;
00431 }
00432 }
00433 if ( ! isWanted ) continue;
00434 DbiSqlValPacket packet(*vrec);
00435
00436
00437 if ( vrec->GetInsertDate() > farFuture ) {
00438 vrec->GetTableProxy()
00439 ->GetDBProxy()
00440 .ReplaceInsertDate(now,seqNo,vrec->GetDbNo());
00441 }
00442
00443
00444 if ( seqNo <= Dbi::kMAXLOCALSEQNO ) {
00445 Int_t globalSeqNo = fCascader.AllocateSeqNo(tableName,1);
00446 if ( globalSeqNo < Dbi::kMAXLOCALSEQNO ) {
00447 MSG("Dbi",Msg::kError) << "Failed (cascader returned " <<globalSeqNo
00448 << ") to get replacement for "
00449 << seqNo << endl;
00450 continue;
00451 }
00452
00453 MSG("Dbi",Msg::kInfo) << " Renumbering " << seqNo
00454 << " -> " << globalSeqNo << endl;
00455 if ( ! proxy.ReplaceSeqNo(seqNo,globalSeqNo,0) ) continue;
00456 else ++numModified;
00457 seqNo = globalSeqNo;
00458 packet.SetSeqNo(seqNo);
00459 }
00460
00461 Int_t numRows = packet.GetNumSqlStmts()-1;
00462
00463 MSG("Dbm", Msg::kInfo)
00464 << "Exporting sequence number " << seqNo
00465 << " with " << numRows << " rows of data" << endl;
00466
00467 packet.Write(*out,writeMeta);
00468 writeMeta = kFALSE;
00469 logFile.LogRec(vrec);
00470 numDataRows += numRows;
00471 ++numVRecsOut;
00472
00473 }
00474
00475
00476
00477 DbiTableProxyRegistry::Instance().PurgeCaches();
00478 }
00479
00480
00481 if ( numModified ) ClearCache();
00482
00483 MSG("Dbm", Msg::kInfo)
00484 << "A total of " << numVRecsOut << " validity entries and "
00485 << numDataRows << " data rows written to file" << endl;
00486
00487 logFile.LogRec();
00488
00489
00490 return kTRUE;
00491
00492 }
00493
00494
00495 Bool_t DbmModule::ExportTables(JobCommand *cmd) {
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 MSG("Dbm",Msg::kInfo) << "\n\nProcessing EXPORT command...\n" << endl;
00522
00523 DbmCmdOptions opts("--File:--LogFile:--SeqNo:--Since:--Table", cmd);
00524 if ( ! opts.IsValid() ) return kFALSE;
00525
00526
00527
00528
00529
00530 string logName;
00531 if ( opts.TestOpt("--LogFile") ) {
00532 logName = opts.GetOptString("--LogFile");
00533 }
00534 DbmLogFile logFile(logName);
00535
00536
00537
00538 list<int> seqnos;
00539 if ( opts.TestOpt("--SeqNo" ) ) opts.GetOptIntList("--SeqNo",seqnos);
00540
00541
00542 string insertDateCondition;
00543 if ( opts.TestOpt("--Since" ) ) {
00544 string opt = opts.GetOptString("--Since");
00545
00546 insertDateCondition = insertDateCondition + "InsertDate >'"
00547 + opt + "'";
00548 MSG("Dbm",Msg::kInfo) << "Applying condition: "
00549 << insertDateCondition << endl;
00550 }
00551
00552
00553 if ( ! opts.TestOpt("--Table" ) ) {
00554 MSG("Dbm",Msg::kWarning) << "Table names not specified." << endl;
00555 return kFALSE;
00556 }
00557 if ( ! opts.TestOpt("--File" ) ) {
00558 MSG("Dbm",Msg::kWarning) << "File name not specified." << endl;
00559 return kFALSE;
00560 }
00561
00562 DbmNameFilter nameFilter(opts.GetOptString("--Table"));
00563 MSG("Dbm",Msg::kInfo) << " Export table name mask set to: "
00564 << opts.GetOptString("--Table") << endl;
00565 string fileName = opts.GetOptString("--File");
00566
00567
00568
00569 ofstream exportFile(fileName.c_str(),ios_base::app);
00570 if ( ! exportFile ) {
00571 MSG("Dbm", Msg::kInfo) << "Unable to open " << fileName << endl;
00572 return kFALSE;
00573 }
00574
00575
00576
00577
00578 list<string> tableNames;
00579 this->ListTables(nameFilter,0,tableNames);
00580
00581
00582
00583 if ( insertDateCondition != "" ) {
00584 ClearCache();
00585 DbiTableProxyRegistry::Instance()
00586 .SetSqlCondition(insertDateCondition);
00587 }
00588
00589
00590
00591 logFile.LogCmd("export",opts);
00592
00593 for ( list<string>::const_iterator itr = tableNames.begin();
00594 itr != tableNames.end();
00595 ++itr ) {
00596 DbiTableProxyRegistry::Instance()
00597 .SetSqlCondition(insertDateCondition);
00598 ExportTable(*itr,&exportFile,logFile,seqnos);
00599 DbiTableProxyRegistry::Instance().SetSqlCondition("");
00600 }
00601
00602
00603 if ( insertDateCondition != "" ) {
00604 ClearCache();
00605 DbiTableProxyRegistry::Instance().SetSqlCondition();
00606 }
00607
00608
00609 exportFile.close();
00610
00611 return kTRUE;
00612
00613 }
00614
00615
00616 const DbiDBProxy& DbmModule::GetDBProxy(const string& tableName) const {
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 DbiConfigSet pet;
00639 return DbiTableProxyRegistry::Instance()
00640 .GetTableProxy(tableName,&pet)
00641 .GetDBProxy();
00642
00643 }
00644
00645
00646
00647 Bool_t DbmModule::GlobaliseSeqNo(JobCommand *cmd) {
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 string tableName;
00678
00679 DbmCmdOptions opts("--Table", cmd);
00680 if ( ! opts.IsValid() ) return kFALSE;
00681
00682 if ( ! opts.TestOpt("--Table" ) ) {
00683 MSG("Dbm",Msg::kWarning) << "Table name not specified." << endl;
00684 return kFALSE;
00685 }
00686
00687 tableName = opts.GetOptString("--Table");
00688
00689 return GlobaliseSeqNo(tableName);
00690
00691 }
00692
00693
00694
00695 Bool_t DbmModule::GlobaliseSeqNo(const string& tableName) {
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 Bool_t ok = kTRUE;
00724 Int_t numModified = 0;
00725
00726
00727 if ( ! BuildValRecSet(tableName,0) ) return kFALSE;
00728
00729
00730 if ( fCascader.GetAuthorisingDbNo() < 0 ) {
00731 MSG("Dbi",Msg::kError) << "No authorising DB in cascade" << endl;
00732 return kFALSE;
00733 }
00734
00735
00736
00737 const DbiDBProxy& proxy = GetDBProxy(tableName);
00738
00739 MSG("Dbm", Msg::kInfo) << "Scanning for local sequence numbers..." << endl;
00740 int numRows = fValRecSet->GetNumRows();
00741
00742 for ( int irow = 0; irow < numRows; ++ irow ) {
00743 const DbiValidityRec* vrec = fValRecSet->GetTableRow(irow);
00744 int seqNo = vrec->GetSeqNo();
00745 if ( seqNo <= Dbi::kMAXLOCALSEQNO ) {
00746 Int_t globalSeqNo = fCascader.AllocateSeqNo(tableName,1);
00747 if ( globalSeqNo < Dbi::kMAXLOCALSEQNO ) {
00748 MSG("Dbi",Msg::kError) << "Failed to get replacement for "
00749 << seqNo << endl;
00750 ok = kFALSE;
00751 break;
00752 }
00753
00754 MSG("Dbi",Msg::kInfo) << " Renumbering " << seqNo
00755 << " -> " << globalSeqNo << endl;
00756 if ( ! proxy.ReplaceSeqNo(seqNo,globalSeqNo,0) ) ok = kFALSE;
00757 else ++numModified;
00758
00759 }
00760 }
00761
00762 MSG("Dbi",Msg::kInfo) << "A total of " << numRows
00763 << " were scanned" << endl;
00764
00765
00766 if ( numModified ) {
00767 MSG("Dbi",Msg::kInfo) << "A total of " << numModified
00768 << " were renumbered" << endl;
00769 ClearCache();
00770 BuildValRecSet(tableName,0);
00771 }
00772 else MSG("Dbi",Msg::kInfo) << "No local SeqNos found" << endl;
00773 return ok;
00774
00775 }
00776
00777
00778
00779 void DbmModule::HandleCommand(JobCommand *cmd) {
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 this->ClearCache();
00805
00806 const char* c = cmd->PopCmd();
00807
00808 if (c) {
00809 TString sc(c);
00810 sc.ToLower();
00811 if (sc == "checkmemory" ) CheckMemory(cmd);
00812 else if (sc == "export" ) ExportTables(cmd);
00813 else if (sc == "globaliseseqno" ) GlobaliseSeqNo(cmd);
00814 else if (sc == "import" ) Import(cmd);
00815 else if (sc == "logentry" ) LogEntry(cmd);
00816 else if (sc == "help" ) Help();
00817 else if (sc == "query" ) Query(cmd);
00818 else if (sc == "setloglevel" ) SetLogLevel(cmd);
00819 else if (sc == "settimer" ) SetTimer(cmd);
00820
00821 else {
00822 MSG("Dbm",Msg::kWarning) << "Unknown command " << sc <<endl
00823 << "Type Help for valid commands." << endl;
00824
00825 }
00826 }
00827
00828 }
00829
00830
00831 void DbmModule::Help() {
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 string helpFileName
00853 = fFileLocater.Find("DatabaseMaintenance/doc/Help.txt");
00854 ifstream helpFile(helpFileName.c_str());
00855
00856 if ( ! helpFile.is_open() ) {
00857 MSG("Dbm",Msg::kInfo) << "Sorry, I cannot help you!" << endl;
00858 }
00859 else {
00860 string line;
00861 while ( ! helpFile.eof() ) {
00862 getline(helpFile,line);
00863 MSG("Dbm",Msg::kInfo) << line << endl;
00864 }
00865 }
00866
00867
00868 }
00869
00870
00871 Bool_t DbmModule::Import(JobCommand *cmd) {
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 MSG("Dbm",Msg::kInfo) << "\n\nProcessing IMPORT command...\n" << endl;
00898
00899
00900 DbmCmdOptions opts("--Batch:"
00901 "--DiscardConflicts:"
00902 "--DatabaseNumber:"
00903 "--EnableSQL:"
00904 "--File:"
00905 "--LogFile:"
00906 "--Table:"
00907 "--Test",
00908 cmd);
00909 if ( ! opts.IsValid() ) return kFALSE;
00910
00911
00912 UInt_t dbNo = 0;
00913 if ( opts.TestOpt("--DatabaseNumber" ) ) {
00914 dbNo = opts.GetOptInt("--DatabaseNumber");
00915 MSG("Dbm",Msg::kInfo) << " using database number " << dbNo
00916 << " " << opts.GetOptString("--DatabaseNumber")
00917 << " for import" << endl;
00918 }
00919
00920
00921 Bool_t batch = opts.TestOpt("--Batch");
00922 if ( batch ) MSG("Dbm",Msg::kInfo)
00923 << " Batch mode: Errors will force exit at end of command." << endl;
00924
00925
00926 Bool_t discardConflicts = opts.TestOpt("--DiscardConflicts");
00927 if ( discardConflicts ) MSG("Dbm",Msg::kInfo)
00928 << " Conflicts will be discarded." << endl;
00929 else MSG("Dbm",Msg::kInfo)
00930 << " Conflicts will be imported." << endl;
00931
00932
00933 Bool_t enableSQL = opts.TestOpt("--EnableSQL");
00934 if ( enableSQL ) MSG("Dbm",Msg::kInfo)
00935 << " SQL fixups are enabled." << endl;
00936 else MSG("Dbm",Msg::kInfo)
00937 << " SQL fixups are disabled." << endl;
00938
00939
00940 if ( ! opts.TestOpt("--File" ) ) {
00941 MSG("Dbm",Msg::kWarning) << "File name not specified." << endl;
00942 if ( batch ) this->Quit();
00943 return kFALSE;
00944 }
00945 string fileName = opts.GetOptString("--File");
00946
00947
00948
00949 string logName;
00950 if ( opts.TestOpt("--LogFile") ) {
00951 logName = opts.GetOptString("--LogFile");
00952 }
00953 DbmLogFile logFile(logName,dbNo);
00954
00955
00956
00957 string tableMask = "*";
00958 if ( opts.TestOpt("--Table") ) tableMask = opts.GetOptString("--Table");
00959 DbmNameFilter nameFilter(tableMask);
00960 MSG("Dbm",Msg::kInfo) << " Import table name mask set to: " << tableMask << endl;
00961
00962
00963 Bool_t test = opts.TestOpt("--Test");
00964 if ( test ) MSG("Dbm",Msg::kInfo) << " Testing only, database will "
00965 << " not be updated." << endl;
00966
00967
00968 ifstream import(fileName.c_str());
00969 if ( ! import ) {
00970 MSG("Dbm", Msg::kError) << "Unable to open " << fileName << endl;
00971 if ( batch ) this->Quit();
00972 return kFALSE;
00973 }
00974
00975 MSG("Dbm", Msg::kInfo) << "\n\nProcessing file " << fileName
00976 << " ..." << endl;
00977
00978 Int_t numNewTables = 0;
00979 Int_t numImported = 0;
00980 Int_t numImpConfl = 0;
00981 Int_t numImpUpdate = 0;
00982 Int_t numDuplicate = 0;
00983 Int_t numOutOfDate = 0;
00984 Int_t numConflict = 0;
00985 Int_t numLocal = 0;
00986 Int_t numFailed = 0;
00987 Int_t numTest = 0;
00988
00989 string currentTableName;
00990
00991 logFile.LogCmd("import",opts);
00992
00993
00994
00995 if ( ! this->ApplySQLFixup(dbNo, import, logFile, enableSQL) ) {
00996 MSG("Dbm", Msg::kError) << "Fixup failed " << endl;
00997 if ( batch ) this->Quit();
00998 return kFALSE;
00999 }
01000
01001
01002
01003 DbiSqlValPacket packetFile(import);
01004
01005 Bool_t skipTable = kFALSE;
01006
01007 for (; packetFile.CanBeStored(); packetFile.Fill(import) ) {
01008
01009
01010 if ( currentTableName != packetFile.GetTableName() ) {
01011 currentTableName = packetFile.GetTableName();
01012
01013
01014 skipTable = ! nameFilter.Test(currentTableName);
01015 if ( skipTable ) {
01016 if ( ! batch ) MSG("Dbm", Msg::kInfo) << "\nSkipping table "
01017 << currentTableName << "...\n" << endl;
01018 continue;
01019 }
01020 if ( ! batch ) MSG("Dbm", Msg::kInfo) << "\nUpdating table "
01021 << currentTableName << "...\n" << endl;
01022
01023
01024 auto_ptr<DbiStatement> stmtDb(fCascader.CreateStatement(dbNo));
01025 string sql = "select * from ";
01026 sql += currentTableName + " where 1=0;";
01027 TSQLStatement* res = stmtDb->ExecuteQuery(sql.c_str());
01028
01029 if ( ! res ) {
01030 if ( packetFile.CreateTable(dbNo) ) {
01031 MSG("Dbm", Msg::kInfo) << " Created table: "
01032 << currentTableName << endl;
01033 ++numNewTables;
01034 }
01035 else {
01036 MSG("Dbm", Msg::kError) << " failed to create table: "
01037 << currentTableName << endl;
01038 }
01039 }
01040 }
01041
01042
01043 if ( skipTable ) continue;
01044
01045 Int_t seqNo = packetFile.GetSeqNo();
01046
01047
01048 bool tryImport = false;
01049 bool replace = false;
01050
01051
01052
01053 DbiValRecSet vrecSet(currentTableName,dbNo,seqNo);
01054 const DbiValidityRec* vrec = vrecSet.GetTableRowBySeqNo(seqNo);
01055
01056 if ( vrec ) {
01057
01058
01059
01060
01061 DbiSqlValPacket::CompResult_t comp = DbiSqlValPacket::kIdentical;
01062 if ( packetFile.GetCreationDate() > vrec->GetCreationDate()
01063 ) comp = DbiSqlValPacket::kUpdate;
01064 if ( packetFile.GetCreationDate() < vrec->GetCreationDate()
01065 ) comp = DbiSqlValPacket::kOutOfDate;
01066
01067 switch ( comp ) {
01068
01069 case DbiSqlValPacket::kIdentical :
01070 if ( ! batch ) MSG("Dbm", Msg::kInfo) << " " << seqNo
01071 << " skipped (duplicate)" << endl;
01072 ++numDuplicate;
01073 break;
01074
01075 case DbiSqlValPacket::kUpdate :
01076 ++numImpUpdate;
01077 tryImport = true;
01078 replace = true;
01079 break;
01080
01081 case DbiSqlValPacket::kOutOfDate :
01082 if ( ! batch ) MSG("Dbm", Msg::kInfo) << " " << seqNo
01083 << " skipped (out of date)" << endl;
01084 ++numOutOfDate;
01085 break;
01086
01087
01088 default :
01089 if ( discardConflicts ) {
01090 MSG("Dbm", Msg::kError) << " " << seqNo
01091 << " skipped (conflict!)" << endl;
01092 ++numConflict;
01093 }
01094 else {
01095 MSG("Dbm", Msg::kError) << " " << seqNo
01096 << " accepting conflict!" << endl;
01097 ++numImpConfl;
01098 tryImport = true;
01099 replace = true;
01100 }
01101 }
01102 }
01103 else {
01104 if ( Dbi::NotGlobalSeqNo(seqNo) ) {
01105 ++numLocal;
01106 if ( ! batch ) MSG("Dbm", Msg::kInfo) << " " << seqNo
01107 << " skipped (local sSeqNo)" << endl;
01108 }
01109
01110 else {
01111 tryImport = true;
01112 }
01113 }
01114
01115
01116
01117 if ( vrec ) DbiTableProxyRegistry::Instance().PurgeCaches();
01118
01119
01120 if ( tryImport ) {
01121
01122
01123 if ( test ) {
01124 ++numTest;
01125 if ( ! batch ) MSG("Dbm", Msg::kInfo) << " " << seqNo
01126 << " tested" << endl;
01127 }
01128 else {
01129
01130 if ( packetFile.Store(dbNo,replace) ) {
01131 ++numImported;
01132 if ( ! batch ) MSG("Dbm", Msg::kInfo) << " " << seqNo
01133 << " imported" << endl;
01134 logFile.LogRec(currentTableName,seqNo);
01135 }
01136 else {
01137 ++numFailed;
01138 MSG("Dbm", Msg::kError) << " " << seqNo
01139 << " failed" << endl;
01140
01141 DbiConfigSet pet;
01142 DbiTableProxyRegistry::Instance()
01143 .GetTableProxy(currentTableName,&pet)
01144 .GetDBProxy().RemoveSeqNo(seqNo,dbNo);
01145 }
01146 }
01147 }
01148 }
01149
01150
01151 if ( packetFile.GetNumErrors() > 0 ) {
01152 ++numFailed;
01153 MSG("Dbm", Msg::kError) << " input error on"
01154 << fileName.c_str() << endl;
01155 }
01156
01157
01158 logFile.LogRec();
01159
01160
01161 MSG("Dbm", Msg::kInfo)
01162 << "Summary of processing of packets (validity rec + data):-" <<endl
01163 << " Packets skipped (local seqNo): " << numLocal << endl
01164 << " Packets skipped (duplicate): " << numDuplicate << endl
01165 << " Packets skipped (out of date): " << numOutOfDate << endl
01166 << " Packets skipped (conflict): " << numConflict << endl
01167 << " Packets failed : " << numFailed << endl
01168 << " Packets tested (not imported): " << numTest << endl
01169 << " Packets imported : " << numImported << endl
01170 << " including conflicts : " << numImpConfl << endl
01171 << " updates : " << numImpUpdate << endl;
01172 if ( numNewTables ) MSG("Dbm", Msg::kInfo) << endl
01173 << " Tables Created : " << numNewTables << endl;
01174
01175
01176 ofstream* log = logFile.GetStream();
01177 if ( log ) {
01178 *log
01179 << " Summary of processing of packets (validity rec + data):-" <<endl;
01180 if ( numLocal ) *log << " Packets skipped (local seqNo): "
01181 << numLocal << endl;
01182 if ( numDuplicate ) *log << " Packets skipped (duplicate): "
01183 << numDuplicate << endl;
01184 if ( numOutOfDate ) *log << " Packets skipped (out of date): "
01185 << numOutOfDate << endl;
01186 if ( numConflict ) *log << " Packets skipped (conflict): "
01187 << numConflict << endl;
01188 if ( numFailed ) *log << " Packets failed : "
01189 << numFailed << endl;
01190 if ( numTest ) *log << " Packets tested (not imported): "
01191 << numTest << endl;
01192 if ( numImported ) *log << " Packets imported : "
01193 << numImported << endl;
01194 if ( numImpConfl) *log << " including conflicts : "
01195 << numImpConfl << endl;
01196 if ( numImpUpdate ) *log << " updates : "
01197 << numImpUpdate << endl;
01198 if ( numNewTables ) *log << endl
01199 << " Tables Created : " << numNewTables << endl;
01200 if ( numConflict + numFailed > 0 ) {
01201 *log << " Import failed!!" << endl;
01202 }
01203 else {
01204 *log << " Import O.K." << endl;
01205 }
01206 }
01207
01208
01209 import.close();
01210
01211
01212
01213 if ( batch
01214 && ( numConflict + numFailed ) > 0 ) this->Quit();
01215 return packetFile.GetNumErrors() ? kFALSE : kTRUE;
01216
01217 }
01218
01219
01220 Bool_t DbmModule::LogEntry(JobCommand *cmd) {
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 std::list<std::string> defaultOpts;
01245 defaultOpts.push_back("--Table");
01246 defaultOpts.push_back("--Reason");
01247 defaultOpts.push_back("--SeqNoMin");
01248 defaultOpts.push_back("--Detector");
01249 defaultOpts.push_back("--SimFlag");
01250
01251 DbmCmdOptions opts("--Table:"
01252 "--Reason:"
01253 "--SeqNoMin:"
01254 "--Detector:"
01255 "--SimFlag:"
01256 "--SeqNoMax:"
01257 "--NumSeqNo:"
01258 "--Task:"
01259 "--UpdateTime:"
01260 "--DatabaseNumber",
01261 cmd, &defaultOpts);
01262 if ( ! opts.IsValid() ) return kFALSE;
01263
01264
01265
01266
01267 if ( ! opts.TestOpt("--Table" ) ) {
01268 MSG("Dbm",Msg::kWarning) << "Table name not specified." << endl;
01269 return kFALSE;
01270 }
01271 string tableName = opts.GetOptString("--Table");
01272
01273 if ( ! opts.TestOpt("--Reason" ) ) {
01274 MSG("Dbm",Msg::kWarning) << "Reason not specified." << endl;
01275 return kFALSE;
01276 }
01277 string reason = opts.GetOptString("--Reason");
01278
01279 if ( ! opts.TestOpt("--SeqNoMin" ) ) {
01280 MSG("Dbm",Msg::kWarning) << "SeqNoMin not specified." << endl;
01281 return kFALSE;
01282 }
01283 Int_t logSeqNoMin = opts.GetOptInt("--SeqNoMin");
01284
01285
01286
01287 UInt_t dbNo = 0;
01288 if ( opts.TestOpt("--DatabaseNumber") ) dbNo = opts.GetOptInt("--DatabaseNumber");
01289
01290
01291 int dbNoFound = DbiTableProxyRegistry::Instance().GetCascader().GetTableDbNo(tableName);
01292 if ( dbNoFound < 0 || dbNoFound != (int) dbNo ) {
01293 MSG("Dbm",Msg::kWarning) << "Sorry, cannot find table " << tableName << endl;
01294 return kFALSE;
01295 }
01296
01297
01298
01299
01300 Int_t detMask = 2;
01301 Int_t simMask = 1;
01302 Dbi::Task task = 0;
01303
01304 DbiResultPtr<DbiConfigSet> dataPtr(tableName,logSeqNoMin,dbNo);
01305 const DbiValidityRec* vrec = dataPtr.GetValidityRec();
01306 if ( dataPtr.GetNumRows() > 0 && vrec ) {
01307 MSG("Dbi",Msg::kInfo) << "Found " << tableName << " " << logSeqNoMin << endl;
01308 const VldRange& vrng = vrec->GetVldRange();
01309 detMask = vrng.GetDetectorMask();
01310 simMask = vrng.GetSimMask();
01311 task = vrec->GetTask();
01312 }
01313
01314 if ( opts.TestOpt("--Detector") ) detMask = opts.GetOptInt("--Detector");
01315
01316 if ( opts.TestOpt("--SimFlag") ) simMask = opts.GetOptInt("--SimFlag");
01317
01318 Int_t logSeqNoMax = logSeqNoMin;
01319 if ( opts.TestOpt("--SeqNoMax") ) logSeqNoMax = opts.GetOptInt("--SeqNoMax");
01320
01321 Int_t logNumSeqNo = logSeqNoMax - logSeqNoMin + 1;
01322 if ( opts.TestOpt("--NumSeqNo") ) logNumSeqNo = opts.GetOptInt("--NumSeqNo");
01323
01324 if ( opts.TestOpt("--Task") ) task = opts.GetOptInt("--Task");
01325
01326 VldTimeStamp updateTime;
01327 if ( opts.TestOpt("--UpdateTime")
01328 ) updateTime = Dbi::MakeTimeStamp(opts.GetOptString("--UpdateTime"));
01329
01330
01331 DbiLogEntry logEntry(tableName,reason,detMask,simMask,task,
01332 logSeqNoMin,logSeqNoMax,logNumSeqNo);
01333 logEntry.SetUpdateTime(updateTime);
01334 MSG("Dbi",Msg::kInfo) << "Created:-\n "
01335 << logEntry << endl;
01336 char ans = '?';
01337 while ( ans != 'y' && ans != 'n' ) {
01338 cout << "O.K. to output ? Ans y or n: ";
01339 cin >> ans;
01340 }
01341
01342 if ( ans == 'y' ) {
01343 bool ioResult = logEntry.Write(dbNo);
01344 if ( ioResult ) MSG("Dbi",Msg::kInfo) << "Successfully wrote entry"
01345 << endl;
01346 return ioResult;
01347 }
01348 MSG("Dbi",Msg::kInfo) << "Entry not written" << endl;
01349 return kFALSE;
01350
01351 }
01352
01353
01354
01355 void DbmModule::ListTables(const DbmNameFilter& nameFilter,
01356 UInt_t dbNo,
01357 std::list<string>& tableNames) const {
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373 auto_ptr<DbiStatement> stmtDb(fCascader.CreateStatement(dbNo));
01374 if ( ! stmtDb.get() ) {
01375 MSG("Dbm", Msg::kInfo) << "Cascade entry " << dbNo
01376 << " empty! " << endl;
01377 return;
01378 }
01379 TSQLStatement* stmt = stmtDb->ExecuteQuery("show tables");
01380 if ( ! stmt ) {
01381 MSG("Dbm", Msg::kInfo) << "Cannot find any tables! " << endl;
01382 return;
01383 }
01384
01385 while ( kTRUE ) {
01386 TString name;
01387 if ( ! stmt->NextResultRow() ) break;
01388 name = stmt->GetString(0);
01389 string tableName = name.Data();
01390 MSG("Dbm", Msg::kDebug )<< "examining table " << tableName << endl;
01391
01392 if ( tableName.size() > 3
01393 && tableName.substr(tableName.size()-3) == "VLD" ) {
01394 tableName.erase(tableName.size()-3);
01395 if ( nameFilter.Test(tableName) ){
01396 tableNames.push_back(tableName);
01397 MSG("Dbm", Msg::kInfo) << "preparing to export: " << tableName << endl;
01398 }
01399 }
01400 }
01401 delete stmt;
01402
01403 if(tableNames.size()==0)
01404 MSG("Dbm", Msg::kInfo) << "error no tables found! " << endl;
01405 }
01406
01407
01408
01409 Bool_t DbmModule::Query(JobCommand *cmd) {
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422 Bool_t satisfied = kFALSE;
01423
01424
01425 string pattern = "*";
01426 Detector::Detector_t det = Detector::kFar;
01427 SimFlag::SimFlag_t sim = SimFlag::kData;
01428 VldTimeStamp date;
01429 Dbi::Task task = 0;
01430
01431
01432
01433 DbmCmdOptions opts("--Table:--Detector:--Date:--SimFlag:--Task", cmd);
01434 if ( ! opts.IsValid() ) return kFALSE;
01435
01436 if ( opts.TestOpt("--Table") ) pattern = opts.GetOptString("--Table");
01437 if ( opts.TestOpt("--Detector") ) {
01438 string detstr = opts.GetOptString("--Detector");
01439 if ( detstr == "Unknown" ) det = Detector::kUnknown;
01440 if ( detstr == "Near" ) det = Detector::kNear;
01441 if ( detstr == "Far" ) det = Detector::kFar;
01442 if ( detstr == "CalDet" ) det = Detector::kCalDet;
01443 if ( detstr == "Calib" ) det = Detector::kCalib;
01444 if ( detstr == "TestStand" ) det = Detector::kTestStand;
01445 if ( detstr == "Mapper" ) det = Detector::kMapper;
01446 }
01447 if ( opts.TestOpt("--SimFlag") ) {
01448 string simstr = opts.GetOptString("--SimFlag");
01449 if ( simstr == "Unknown" ) sim = SimFlag::kUnknown;
01450 if ( simstr == "Data" ) sim = SimFlag::kData;
01451 if ( simstr == "DaqFakeData" ) sim = SimFlag::kDaqFakeData;
01452 if ( simstr == "MC" ) sim = SimFlag::kMC;
01453 if ( simstr == "Reroot" ) sim = SimFlag::kReroot;
01454 }
01455 if ( opts.TestOpt("--Date") ) {
01456 string datestr = opts.GetOptString("--Date");
01457 date = Dbi::MakeTimeStamp(datestr);
01458 }
01459
01460 if ( opts.TestOpt("--Task") ) {
01461 task = opts.GetOptInt("--Task");
01462 }
01463
01464
01465 VldContext vc(det,sim,date);
01466
01467
01468 list<string> tableNames;
01469 this->ListTables(pattern,0,tableNames);
01470
01471
01472
01473 for ( list<string>::const_iterator itr = tableNames.begin();
01474 itr != tableNames.end();
01475 ++itr ) {
01476 DbiResultPtr<DbiConfigSet> rptr(*itr,vc,task);
01477 MSG("Dbm", Msg::kInfo) << "Query for table: " << *itr ;
01478 if ( ! rptr.GetNumRows() ) MSG("Dbm",Msg::kInfo) << " failed\n";
01479 else {
01480 MSG("Dbm",Msg::kInfo) << " succeeded. "
01481 << rptr.GetNumRows() << " rows"
01482 << "\n ResultKey: " << *rptr.GetKey();
01483 satisfied = kTRUE;
01484 }
01485 MSG("Dbm", Msg::kInfo) << " ValidityRec: " << *rptr.GetValidityRec() << endl;
01486
01487 }
01488
01489 return satisfied;
01490
01491
01492 }
01493
01494
01495
01496 void DbmModule::Quit() const {
01497 MSG("Dbm", Msg::kInfo) << "Exit forced due to above errors" << endl;
01498 exit(1);
01499 }
01500
01501
01502
01503 void DbmModule::SetLogLevel(JobCommand *cmd) const {
01504
01505
01506
01507
01508
01509
01510
01511
01512 const char* stream = cmd->PopOpt();
01513 const char* level = cmd->PopOpt();
01514 if ( ! stream or ! level ) {
01515 MSG("Dbm",Msg::kWarning)
01516 << "Please supply both a stream and a level to the SetLogLevel command\n" << endl;
01517 return;
01518 }
01519
01520 bool set_ok = Util::MsgLevel(stream,level);
01521 MSG("Dbm",Msg::kInfo) << "Setting MessageService level on stream " << stream
01522 << " to level " << level
01523 << ( set_ok ? " succeeded" : " failed" ) << endl;
01524
01525 }
01526
01527
01528 void DbmModule::SetTimer(JobCommand *cmd) const {
01529
01530
01531
01532
01533
01534
01535
01536
01537 bool enableTimer = true;
01538 const char* mode = cmd->PopOpt();
01539 if ( mode and ! strcmp(mode,"off") ) enableTimer = false;
01540 DbiTimerManager::gTimerManager.Enable(enableTimer);
01541 MSG("Dbm",Msg::kInfo) << "Setting Timer " << (enableTimer ? "on" : "off") << endl;
01542
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574