00001
00002
00003 #include <algorithm>
00004 #include <memory>
00005 using std::auto_ptr;
00006 #include <sstream>
00007 #include <vector>
00008
00009 #include "DatabaseInterface/Dbi.h"
00010 #include "DatabaseInterface/DbiCascader.h"
00011 #include "DatabaseInterface/DbiConfigSet.h"
00012 #include "DatabaseInterface/DbiOutRowStream.h"
00013 #include "DatabaseInterface/DbiResultPtr.h"
00014 #include "DatabaseInterface/DbiResultSet.h"
00015 #include "DatabaseInterface/DbiSqlValPacket.h"
00016 #include "DatabaseInterface/DbiStatement.h"
00017 #include "DatabaseInterface/DbiTableProxy.h"
00018 #include "DatabaseInterface/DbiTableRow.h"
00019 #include "DatabaseInterface/DbiTableProxyRegistry.h"
00020 #include "DatabaseInterface/DbiValidityRec.h"
00021 #include "DatabaseInterface/DbiValRecSet.h"
00022
00023 #include "LeakChecker/Lea.h"
00024 #include "MessageService/MsgService.h"
00025 #include "Util/UtilString.h"
00026 #include "Validity/VldRange.h"
00027
00028 ClassImp(DbiSqlValPacket)
00029
00030 #ifdef IRIX6
00031
00032
00033 enum EFillState { kLOOKING_FOR_HEADER,
00034 kLOOKING_FOR_TRAILER };
00035 #endif
00036
00037
00038
00039
00040 Bool_t DbiSqlValPacket::fgLastMetaHadRowCounter = false;
00041
00042 CVSID("$Id: DbiSqlValPacket.cxx,v 1.43 2007/04/26 14:19:57 west Exp $");
00043
00044
00045
00046
00047 static bool compStringPtrs(const string* str1, const string* str2 ) {
00048 return *str1 < *str2; }
00049
00050
00051
00052
00053
00054
00055
00056
00057 DbiSqlValPacket::DbiSqlValPacket() :
00058 fNumErrors(0),
00059 fSeqNo(0),
00060 fNumStmts(0)
00061 {
00062
00063
00064
00065
00066 LEA_CTOR
00067
00068 MSG("Dbi", Msg::kVerbose) << "Creating DbiSqlValPacket" << endl;
00069 }
00070
00071
00072
00073 DbiSqlValPacket::DbiSqlValPacket(std::ifstream& is) :
00074 fNumErrors(0),
00075 fSeqNo(0),
00076 fNumStmts(0)
00077 {
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 LEA_CTOR
00101
00102 MSG("Dbi", Msg::kVerbose) << "Creating DbiSqlValPacket" << endl;
00103
00104 Fill(is);
00105
00106 }
00107
00108
00109 DbiSqlValPacket::DbiSqlValPacket(const DbiValidityRec& vrec) :
00110 fNumErrors(0),
00111 fSeqNo(vrec.GetSeqNo()),
00112 fNumStmts(0),
00113 fTableName(vrec.GetTableProxy()->GetTableName()),
00114 fCreationDate(vrec.GetCreationDate())
00115 {
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 LEA_CTOR
00140
00141 MSG("Dbi", Msg::kVerbose) << "Creating DbiSqlValPacket" << endl;
00142
00143 const DbiTableProxy& tableProxy = *vrec.GetTableProxy();
00144 Int_t seqNo = vrec.GetSeqNo();
00145 UInt_t dbNo = vrec.GetDbNo();
00146
00147
00148 this->AddRow(tableProxy,0,vrec);
00149
00150
00151
00152 const DbiDBProxy& dbProxy = tableProxy.GetDBProxy();
00153 DbiResultSet* rset = dbProxy.QuerySeqNo(seqNo,dbNo);
00154
00155
00156 for(; ! rset->IsExhausted(); rset->FetchRow()) {
00157 string str;
00158 rset->RowAsCsv(str);
00159 this->AddRow(str);
00160 }
00161 delete rset;
00162 rset = 0;
00163 }
00164
00165
00166
00167 DbiSqlValPacket::~DbiSqlValPacket() {
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 LEA_DTOR
00191
00192 MSG("Dbi", Msg::kVerbose) << "Destroying DbiSqlValPacket" << endl;
00193
00194 Clear();
00195
00196 }
00197
00198
00199
00200 Bool_t DbiSqlValPacket::AddDataRow(const DbiTableProxy& tblProxy,
00201 const DbiValidityRec* vrec,
00202 const DbiTableRow& row){
00203
00204
00205
00206
00207
00208 if ( this->GetNumSqlStmts() == 0 ) {
00209 MAXMSG("Dbi",Msg::kError,20)
00210 << "Cannot add data row - packet does not have a VLD row" << endl;
00211 ++fNumErrors;
00212 return kFALSE;
00213 }
00214
00215 return this->AddRow(tblProxy,vrec,row);
00216
00217 }
00218
00219
00220
00221 void DbiSqlValPacket::AddRow(const string & row){
00222
00223
00224
00225
00226
00227 string sql("INSERT INTO ");
00228 sql += this->GetTableName();
00229 if ( this->GetNumSqlStmts() == 0 ) sql += "VLD";
00230 sql += " VALUES (" + row + ");";
00231 ostringstream seqno;
00232 seqno << this->GetSeqNo();
00233 this->SetSeqNoOnRow(sql,seqno.str());
00234 fSqlStmts.push_back(sql);
00235 ++fNumStmts;
00236
00237 }
00238
00239
00240
00241 Bool_t DbiSqlValPacket::AddRow(const DbiTableProxy& tblProxy,
00242 const DbiValidityRec* vrec,
00243 const DbiTableRow& row){
00244
00245
00246
00247
00248
00249
00250 bool isVld = this->GetNumSqlStmts() == 0;
00251 const DbiTableMetaData& meta = isVld ? tblProxy.GetMetaValid() : tblProxy.GetMetaData();
00252 DbiOutRowStream outRow(&meta);
00253
00254
00255 if ( ! isVld ) {
00256 outRow << 0;
00257 if ( outRow.HasRowCounter() ) outRow << fNumStmts;
00258 }
00259 row.Store(outRow,vrec);
00260 if ( ! outRow.HasGoodData() ) {
00261 if ( ! outRow.IsComplete() ) {
00262 MAXMSG("Dbi",Msg::kError,20)
00263 << "Incomplete data supplied for row " << this->GetNumSqlStmts()-1
00264 << " of table "
00265 << tblProxy.GetTableName() << endl;
00266 }
00267 ++fNumErrors;
00268 return kFALSE;
00269 }
00270 this->AddRow(outRow.GetCSV());
00271 return kTRUE;
00272 }
00273
00274
00275 DbiSqlValPacket::CompResult_t DbiSqlValPacket::Compare(
00276 const DbiSqlValPacket& that,
00277 Bool_t log,
00278 const Char_t* thisName,
00279 const Char_t* thatName ) const {
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 if ( this->IsEqual(that,log,thisName,thatName ) ) return kIdentical;
00299
00300 if ( fSeqNo != that.fSeqNo
00301 || fTableName != that.fTableName ) return kConflict;
00302
00303 std::vector<std::string> valuesThis = this->GetStmtValues(0);
00304 std::vector<std::string> valuesThat = that.GetStmtValues(0);
00305
00306
00307 int comp = valuesThis[7].compare(valuesThat[7]);
00308
00309 if ( comp < 0 ) {
00310 if ( log ) MSG("Dbi",Msg::kInfo)
00311 << " Difference classified as Update" << endl;;
00312 return kUpdate;
00313 }
00314 else if ( comp > 0 ) {
00315 if ( log ) MSG("Dbi",Msg::kInfo)
00316 << " Difference classified as OutOfDate" << endl;
00317 return kOutOfDate;
00318 }
00319 return kConflict;
00320
00321 }
00322
00323
00324
00325
00326 Bool_t DbiSqlValPacket::CreateTable(UInt_t dbNo) const {
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 if ( ! CanBeStored() ) return kFALSE;
00351
00352
00353 auto_ptr<DbiStatement> stmtDb(DbiTableProxyRegistry::Instance()
00354 .GetCascader()
00355 .CreateStatement(dbNo));
00356 if ( ! stmtDb.get() ) {
00357 MSG("Dbi",Msg::kWarning)
00358 << "Attempting to write to non-existant cascade entry " << dbNo
00359 << endl;
00360 return kFALSE;
00361 }
00362 if ( fSqlMySqlMetaMain == "" || fSqlMySqlMetaVld == "" ) {
00363 MSG("Dbi",Msg::kWarning)
00364 << "No SQL available to create table " << fTableName
00365 << " in cascade entry: " << dbNo << endl;
00366 return kFALSE;
00367 }
00368
00369 stmtDb->ExecuteUpdate(fSqlMySqlMetaVld.c_str());
00370 if ( stmtDb->PrintExceptions() ) return kFALSE;
00371 stmtDb->ExecuteUpdate(fSqlMySqlMetaMain.c_str());
00372 if ( stmtDb->PrintExceptions() ) return kFALSE;
00373
00374 DbiTableProxyRegistry::Instance().RefreshMetaData(this->GetTableName());
00375
00376 return kTRUE;
00377
00378 }
00379
00380
00381
00382 Bool_t DbiSqlValPacket::Fill(std::ifstream& is) {
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 #ifdef IRIX6
00408 EFillState state = kLOOKING_FOR_HEADER;
00409 #else
00410 enum { kLOOKING_FOR_HEADER,
00411 kLOOKING_FOR_TRAILER } state = kLOOKING_FOR_HEADER;
00412 #endif
00413
00414 enum { kMAXTABLENAMELEN = Dbi::kMAXTABLENAMELEN,
00415 kHEADER_TRAILER_MAX_LEN = kMAXTABLENAMELEN + 20 };
00416
00417 string nameHead;
00418 string nameTrail;
00419 UInt_t seqNoHead = 0;
00420 UInt_t seqNoTrail = 0;
00421
00422 string line;
00423 string msg;
00424 string sql;
00425 int lineNum = 0;
00426
00427 this->Reset();
00428
00429
00430 while ( ! is.eof() ) {
00431 getline(is,line);
00432 ++lineNum;
00433
00434 if (line.size() == 0 ) continue;
00435
00436
00437 if ( state == kLOOKING_FOR_HEADER ) {
00438 if ( line.substr(0,5) == ">>>>>" ) {
00439 if ( line.size() >= kHEADER_TRAILER_MAX_LEN ) {
00440 Report("Bad header",lineNum,line);
00441 continue;
00442 }
00443
00444
00445 if ( line.find("Metadata") != string::npos ) {
00446 getline(is,fSqlMySqlMetaVld);
00447 ++lineNum;
00448 getline(is,fSqlMySqlMetaMain);
00449
00450 fgLastMetaHadRowCounter =
00451 fSqlMySqlMetaMain.find("ROW_COUNTER",fSqlMySqlMetaMain.find("(")) != string::npos;
00452 ++lineNum;
00453 getline(is,line);
00454 ++lineNum;
00455 if ( line.substr(0,5) != "<<<<<"
00456 || line.find("Metadata") == string::npos ) {
00457 Report("Bad metadata",lineNum,line);
00458 continue;
00459 }
00460 getline(is,line);
00461 ++lineNum;
00462 if ( line.size() >= kHEADER_TRAILER_MAX_LEN ) {
00463 Report("Bad header",lineNum,line);
00464 continue;
00465 }
00466 }
00467
00468
00469 istringstream istr(line.substr(5));
00470 istr.width(kMAXTABLENAMELEN);
00471 istr >> nameHead >> seqNoHead;
00472 if ( ! istr.eof() ) {
00473 Report("Input error",lineNum,line);
00474 continue;
00475 }
00476
00477
00478 state = kLOOKING_FOR_TRAILER;
00479 sql = "";
00480 }
00481 else {
00482 Report("Not header",lineNum,line);
00483 }
00484 }
00485
00486
00487
00488 else {
00489 if ( line.substr(0,5) == "<<<<<" ) {
00490 if ( line.size() >= kHEADER_TRAILER_MAX_LEN
00491 ) msg = "Bad trailer";
00492
00493 else {
00494
00495
00496 istringstream istr(line.substr(5));
00497 istr.width(kMAXTABLENAMELEN);
00498 istr >> nameTrail >> seqNoTrail;
00499 if ( ! istr.eof() ) msg = "Input error";
00500
00501 else if ( nameTrail != nameHead
00502 || seqNoHead != seqNoTrail ) {
00503 msg = "Header/Trailer mismatch: Header: ";
00504 msg += istr.str();
00505 }
00506 else if ( GetNumSqlStmts() == 0
00507 ) msg = "No SQL statements between Header/Trailer";
00508 else {
00509
00510
00511 fSeqNo = seqNoHead;
00512 fTableName = nameHead;
00513
00514
00515 string date = this->GetStmtValues(0)[7];
00516
00517 date.erase(0,1);
00518 date.erase(date.size()-1,1);
00519 fCreationDate = Dbi::MakeTimeStamp(date);
00520
00521 if ( fTableName == "DBUSUBRUNSUMMARY" ) {
00522 std::vector<std::string> ls;
00523 UtilString::StringTok(ls,*fSqlStmts.begin(),",");
00524
00525 if (ls.size() >= 7 && ls[6] != "-1") {
00526 static bool warnOnce = true;
00527 if ( warnOnce ) {
00528 MSG("Dbi",Msg::kWarning)
00529 << "Setting aggregate number for DBUSUBRUNSUMMARY = -1\n"
00530 << " Expect this message once. DBUSUBRUNSUMMARY needs to be "
00531 << " fixed!" << endl;
00532 warnOnce = false;
00533 }
00534 ls[6] = "-1";
00535 sql = ls[0];
00536 for (unsigned i=1; i<ls.size(); ++i ) sql += "," + ls[i];
00537 fSqlStmts.pop_front();
00538 fSqlStmts.push_front(sql);
00539 }
00540 }
00541 return kTRUE;
00542
00543 }
00544 }
00545
00546
00547 Report(msg.c_str(),lineNum,line);
00548 state = kLOOKING_FOR_HEADER;
00549 }
00550
00551
00552
00553 else {
00554 sql += line;
00555 if ( sql[sql.size()-1] == ';') {
00556 fSqlStmts.push_back(sql);
00557 ++fNumStmts;
00558 sql = "";
00559 }
00560 }
00561 }
00562
00563 }
00564
00565 if ( state != kLOOKING_FOR_HEADER
00566 ) Report("Unexpected EOF",lineNum,"EOF");
00567 this->Reset();
00568 return kFALSE;
00569
00570 }
00571
00572
00573 string DbiSqlValPacket::GetStmt(UInt_t stmtNo) const {
00574
00575
00576
00577
00578 if ( stmtNo >= this->GetNumSqlStmts() ) return "";
00579
00580
00581 std::list<std::string>::const_iterator itr = fSqlStmts.begin();
00582 while ( stmtNo ) { ++itr; --stmtNo; }
00583
00584 return *itr;
00585
00586 }
00587
00588
00589 std::vector<std::string> DbiSqlValPacket::GetStmtValues(UInt_t stmtNo) const {
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 std::vector<std::string> vec;
00603 if ( stmtNo >= this->GetNumSqlStmts() ) return vec;
00604
00605
00606 std::string str = this->GetStmt(stmtNo);
00607
00608
00609 std::string::size_type pos = str.find('(');
00610 ++pos;
00611 std::string::size_type n = str.find(')') - pos;
00612 UtilString::StringTok(vec,str.substr(pos,n),",");
00613
00614 return vec;
00615
00616 }
00617
00618
00619
00620 Bool_t DbiSqlValPacket::IsEqual(const DbiSqlValPacket& that,
00621 Bool_t log,
00622 const Char_t* thisName,
00623 const Char_t* thatName ) const {
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 if ( fSeqNo != that.fSeqNo
00650 || fTableName != that.fTableName
00651 || fNumStmts != that.fNumStmts ) {
00652 if ( log ) MSG("Dbi",Msg::kInfo) << "Conflict found:"
00653 << " for : " << thisName << " , " << thatName << " :-\n"
00654 << " SeqNo " << fSeqNo << "," << that.fSeqNo
00655 << "\n TableName " << fTableName << "," << that.fTableName
00656 << "\n Size " << fNumStmts << ","
00657 << that.fNumStmts << endl;
00658 return kFALSE;
00659 }
00660
00661 list<string>::const_iterator itrThisBegin = fSqlStmts.begin();
00662 list<string>::const_iterator itrThisEnd = fSqlStmts.end();
00663 list<string>::const_iterator itrThatBegin = that.fSqlStmts.begin();
00664 list<string>::const_iterator itrThatEnd = that.fSqlStmts.end();
00665
00666 list<string>::const_iterator itrThis = itrThisBegin;
00667 list<string>::const_iterator itrThat = itrThatBegin;
00668
00669 Bool_t isEqual = kTRUE;
00670
00671
00672
00673
00674 string strThis = (*itrThis).substr(0,(*itrThis).rfind(','));
00675 string strThat = (*itrThat).substr(0,(*itrThat).rfind(','));
00676 if ( strThis != strThat ) {
00677 if ( ! log ) return kFALSE;
00678 isEqual = kFALSE;
00679 MSG("Dbi",Msg::kInfo)
00680 << "Difference on VLD record " << ":-\n"
00681 << " " << thisName << ": " << strThis << endl
00682 << " " << thatName << ": " << strThat << endl;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691 ++itrThis;
00692 ++itrThat;
00693 while ( itrThis != itrThisEnd && (*itrThis) == (*itrThat) ) {
00694
00695
00696 ++itrThis;
00697 ++itrThat;
00698 }
00699 if ( itrThis == itrThisEnd ) return isEqual;
00700
00701 itrThis = itrThisBegin;
00702 itrThat = itrThatEnd;
00703 ++itrThis;
00704 --itrThat;
00705
00706 while ( itrThis != itrThisEnd && (*itrThis) == (*itrThat) ) {
00707
00708
00709 ++itrThis;
00710 --itrThat;
00711 }
00712 if ( itrThis == itrThisEnd ) return isEqual;
00713
00714
00715
00716
00717 typedef vector<const string*> shadow_list_t;
00718 typedef shadow_list_t::iterator shadow_list_itr_t;
00719
00720 shadow_list_t shadowThis;
00721 shadow_list_t shadowThat;
00722
00723 itrThis = itrThisBegin;
00724 itrThat = itrThatBegin;
00725 ++itrThis;
00726 ++itrThat;
00727
00728 while ( itrThis != itrThisEnd ) {
00729 shadowThis.push_back(&(*itrThis));
00730 shadowThat.push_back(&(*itrThat));
00731 ++itrThis;
00732 ++itrThat;
00733 }
00734
00735 shadow_list_itr_t shadowThisItr = shadowThis.begin();
00736 shadow_list_itr_t shadowThisItrEnd = shadowThis.end();
00737 shadow_list_itr_t shadowThatItr = shadowThat.begin();
00738 shadow_list_itr_t shadowThatItrEnd = shadowThat.end();
00739
00740 sort(shadowThisItr,shadowThisItrEnd,compStringPtrs);
00741 sort(shadowThatItr,shadowThatItrEnd,compStringPtrs);
00742
00743 while ( shadowThisItr != shadowThisItrEnd ) {
00744 if ( (**shadowThisItr) != (**shadowThatItr) ){
00745 if ( ! log ) return kFALSE;
00746 isEqual = kFALSE;
00747 MSG("Dbi",Msg::kInfo) << "Difference on data record "
00748 << ":-\n"
00749 << " " << thisName << ": " << **shadowThisItr << endl
00750 << " " << thatName << ": " << **shadowThatItr << endl;
00751 }
00752 ++shadowThisItr;
00753 ++shadowThatItr;
00754 }
00755
00756 return isEqual;
00757
00758 }
00759
00760
00761
00762 void DbiSqlValPacket::Print(Option_t * ) const {
00763
00764
00765
00766
00767 MSG("Dbi",Msg::kInfo)
00768 << "DbiSQLValPacket:"
00769 << " table \"" << fTableName << "\" "
00770 << " SeqNo " << fSeqNo
00771 << " NumErrors " << fNumErrors
00772 << endl
00773 << " CreationDate " << fCreationDate
00774 << endl;
00775
00776 MSG("Dbi",Msg::kInfo)
00777 << " MySQL Main table creation: \"" << fSqlMySqlMetaMain << "\"" << endl;
00778
00779 MSG("Dbi",Msg::kInfo)
00780 << " MySQL VLD table creation: \"" << fSqlMySqlMetaVld << "\"" << endl;
00781
00782 if ( GetNumSqlStmts() > 0 ) {
00783 std::list<string>::const_iterator itr = fSqlStmts.begin();
00784 std::list<string>::const_iterator itrEnd = fSqlStmts.end();
00785 for (; itr != itrEnd; ++itr)
00786 MSG("Dbi",Msg::kInfo)
00787 << " SqlStmt \"" << *itr << "\"" << endl;
00788 }
00789 else {
00790 MSG("Dbi",Msg::kInfo) << " No SqlStmts." << endl;
00791 }
00792
00793 }
00794
00795
00796
00797
00798 void DbiSqlValPacket::Recreate(const string& tableName,
00799 const VldRange& vr,
00800 Int_t aggNo,
00801 Dbi::Task task,
00802 VldTimeStamp creationDate
00803 ) {
00804
00805
00806
00807
00808
00809 this->Clear();
00810
00811 DbiTableProxyRegistry& tablePR = DbiTableProxyRegistry::Instance();
00812 if ( ! tablePR.GetCascader().TableExists(tableName) ) {
00813 MAXMSG("Dbi",Msg::kError,20) << "Cannot create packet - table " << tableName
00814 << " does not exist." << endl;
00815 fNumErrors = 1;
00816 return;
00817 }
00818
00819 fTableName = tableName;
00820
00821
00822
00823 DbiValidityRec vrec(vr,task,aggNo,0);
00824
00825
00826 DbiConfigSet dummy;
00827 const DbiTableMetaData& metaValid = tablePR.GetTableProxy(tableName,&dummy)
00828 .GetMetaValid();
00829 DbiOutRowStream buff(&metaValid);
00830
00831 vrec.Store(buff,0);
00832 this->AddRow(buff.GetCSV());
00833 this->SetCreationDate(creationDate);
00834
00835 }
00836
00837
00838
00839 void DbiSqlValPacket::Report(const char* msg,
00840 UInt_t lineNum,
00841 const string& line) {
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 MAXMSG("Dbi",Msg::kError,20) << msg << " on line " << lineNum
00866 <<":- \n " << line << endl;
00867 this->Reset();
00868 ++fNumErrors;
00869
00870 }
00871
00872
00873 void DbiSqlValPacket::Reset() {
00874
00875
00876
00877
00878 fSeqNo = 0;
00879 fSqlMySqlMetaMain = "";
00880 fSqlMySqlMetaVld = "";
00881 fSqlStmts.clear();
00882 fNumStmts = 0;
00883 fTableName = "";
00884
00885 }
00886
00887
00888 void DbiSqlValPacket::SetCreationDate(VldTimeStamp ts) {
00889
00890
00891
00892
00893 fCreationDate = ts;
00894
00895
00896 if ( this->GetNumSqlStmts() == 0 ) return;
00897
00898 string& vldRow = *fSqlStmts.begin();
00899 string::size_type locEnd = vldRow.rfind(',');
00900 if ( locEnd == string::npos ) return;
00901 locEnd -=2;
00902 string::size_type locStart = vldRow.rfind(',',locEnd);
00903 if ( locStart == string::npos ) return;
00904 locStart+=2;
00905 vldRow.replace(locStart,locEnd-locStart+1,ts.AsString("s"));
00906
00907 }
00908
00909
00910
00911 void DbiSqlValPacket::SetMetaData() const {
00912
00913
00914
00915
00916 DbiTableProxyRegistry& tbprxreg = DbiTableProxyRegistry::Instance();
00917
00918
00919 DbiCascader& cas = tbprxreg.GetCascader();
00920 Int_t dbNo = cas.GetTableDbNo(this->GetTableName());
00921 if ( dbNo < 0 ) return;
00922
00923
00924
00925 DbiConfigSet dummy;
00926 const DbiTableMetaData & metaVld = tbprxreg.GetTableProxy(this->GetTableName(),&dummy)
00927 .GetMetaValid();
00928 const DbiTableMetaData & metaMain = tbprxreg.GetTableProxy(this->GetTableName(),&dummy)
00929 .GetMetaData();
00930 fSqlMySqlMetaVld = metaVld.Sql();
00931 fSqlMySqlMetaMain = metaMain.Sql();
00932
00933 }
00934
00935
00936
00937 void DbiSqlValPacket::SetSeqNo(UInt_t seqno) {
00938
00939
00940
00941
00942 fSeqNo = seqno;
00943
00944
00945 if ( this->GetNumSqlStmts() == 0 ) return;
00946
00947 ostringstream tmp;
00948 tmp << seqno;
00949 const string seqnoStr = tmp.str();
00950
00951 std::list<string>::iterator itr = fSqlStmts.begin();
00952 std::list<string>::iterator itrEnd = fSqlStmts.end();
00953 for (; itr != itrEnd; ++itr) SetSeqNoOnRow(*itr,seqnoStr);
00954
00955
00956 }
00957
00958
00959
00960 void DbiSqlValPacket::SetSeqNoOnRow(string& row,const string& seqno) {
00961
00962
00963
00964
00965
00966
00967 string::size_type locStart = row.find('(');
00968 if ( locStart == string::npos ) return;
00969 ++locStart;
00970 string::size_type locEnd = row.find(',',locStart);
00971 if ( locEnd == string::npos ) return;
00972 row.replace(locStart,locEnd-locStart,seqno);
00973
00974 }
00975
00976
00977
00978 Bool_t DbiSqlValPacket::Store(UInt_t dbNo, Bool_t replace) const {
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 if ( ! CanBeStored() ) return kFALSE;
00998
00999
01000 DbiConfigSet pet;
01001 DbiTableProxy& tp = DbiTableProxyRegistry::Instance()
01002 .GetTableProxy(this->GetTableName(),&pet);
01003 if ( replace ) {
01004 const DbiDBProxy & proxy = tp.GetDBProxy();
01005 if ( ! proxy.RemoveSeqNo(this->GetSeqNo(),dbNo) ) return kFALSE;
01006 }
01007
01008
01009 auto_ptr<DbiStatement> stmtDb(DbiTableProxyRegistry::Instance()
01010 .GetCascader()
01011 .CreateStatement(dbNo));
01012 if ( ! stmtDb.get() ) {
01013 MSG("Dbi",Msg::kWarning)
01014 << "Attempting to write to non-existant cascade entry " << dbNo
01015 << endl;
01016 return kFALSE;
01017 }
01018
01019
01020
01021
01022
01023 bool removeRowCounter = fgLastMetaHadRowCounter
01024 && ! tp.GetMetaData().HasRowCounter();
01025
01026
01027 Bool_t first = kTRUE;
01028 int combineInserts = 0;
01029
01030 int maxInserts = stmtDb->GetDBType() == Dbi::kOracle ? 1 : 20;
01031 string sqlInserts;
01032
01033 for (list<string>::const_iterator itr = fSqlStmts.begin();
01034 itr != fSqlStmts.end();
01035 ++itr) {
01036 if ( first ) {
01037
01038 string sql = *itr;
01039 list<string>::size_type locDate = sql.rfind(",\'");
01040 if ( locDate != string::npos ) {
01041 VldTimeStamp now;
01042 sql.replace(locDate+2,19,Dbi::MakeDateTimeString(now));
01043 }
01044 stmtDb->ExecuteUpdate(sql.c_str());
01045 if ( stmtDb->PrintExceptions() ) return kFALSE;
01046 first = kFALSE;
01047 continue;
01048 }
01049
01050 string sql = *itr;
01051
01052
01053 if (removeRowCounter) {
01054 list<string>::size_type locStart = sql.find(',');
01055 ++locStart;
01056 list<string>::size_type locEnd = sql.find(',',locStart);
01057 if ( locEnd != string::npos ) {
01058 list<string>::size_type numChars = locEnd - locStart + 1;
01059 sql.erase(locStart,numChars);
01060 }
01061 }
01062
01063
01064
01065 string::size_type insertIndex = sql.find("VALUES (");
01066 if ( insertIndex == string::npos) {
01067 MAXMSG("Dbi",Msg::kError,20) << "Unexpected SQL : " << sql
01068 << "\n should be of form INSERT INTO ... VALUES (...);" << endl;
01069 return kFALSE;
01070 }
01071 ++combineInserts;
01072 if ( combineInserts == 1 ) sqlInserts = sql;
01073 else {
01074 sqlInserts[sqlInserts.size()-1] = ',';
01075 sqlInserts += sql.substr(insertIndex+7);
01076 }
01077 if ( combineInserts >= maxInserts ) {
01078 stmtDb->ExecuteUpdate(sqlInserts.c_str());
01079 if ( stmtDb->PrintExceptions() ) return kFALSE;
01080 combineInserts = 0;
01081 }
01082 }
01083
01084
01085 if ( combineInserts ) {
01086 stmtDb->ExecuteUpdate(sqlInserts.c_str());
01087 combineInserts = 0;
01088 if ( stmtDb->PrintExceptions() ) return kFALSE;
01089 }
01090
01091 return kTRUE;
01092
01093 }
01094
01095
01096 Bool_t DbiSqlValPacket::Write(std::ofstream& ios,
01097 Bool_t addMetadata) const {
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121 if ( ! CanBeStored() ) return kFALSE;
01122 if ( addMetadata ) {
01123 if ( fSqlMySqlMetaMain.size() == 0 ) this->SetMetaData();
01124 if ( fSqlMySqlMetaMain.size() == 0 ) {
01125 MSG("Dbi",Msg::kWarning)
01126 << "Cannot write metadata; no associated DbiTableProxy "
01127 << endl;
01128 }
01129 else {
01130
01131
01132 ios << ">>>>>" << GetTableName() << " Metadata [MySQL]" << endl;
01133 ios << fSqlMySqlMetaVld << endl;
01134 ios << fSqlMySqlMetaMain << endl;
01135 ios << "<<<<<" << GetTableName() << " Metadata" << endl;
01136 }
01137 }
01138
01139 ios << ">>>>>" << GetTableName() << " " << GetSeqNo() << endl;
01140
01141 for ( list<string>::const_iterator itr = fSqlStmts.begin();
01142 itr != fSqlStmts.end();
01143 ++itr) ios << (*itr) << endl;
01144
01145 ios << "<<<<<" << GetTableName() << " " << GetSeqNo() << endl;
01146
01147 return kTRUE;
01148
01149 }
01150