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