00001
00002
00003
00004
00005
00006
00007 #include <memory>
00008 #include <cassert>
00009
00010 #include "TCollection.h"
00011 #include "TList.h"
00012 #include "TSQLColumnInfo.h"
00013 #include "TSQLStatement.h"
00014 #include "TSQLServer.h"
00015 #include "TSQLTableInfo.h"
00016 #include "TString.h"
00017
00018 #include "DbiDetector.hxx"
00019 #include "DbiSimFlag.hxx"
00020 #include "TDbiDBProxy.hxx"
00021 #include "TDbiCascader.hxx"
00022 #include "TDbiFieldType.hxx"
00023 #include "TDbiInRowStream.hxx"
00024 #include "TDbiServices.hxx"
00025 #include "TDbiString.hxx"
00026 #include "TDbiStatement.hxx"
00027 #include "TDbiTableMetaData.hxx"
00028 #include "TDbiTimerManager.hxx"
00029 #include "TDbiValidityRec.hxx"
00030 #include <TSK_DBI_Log.hxx>
00031 #include <MsgFormat.h>
00032 using std::endl;
00033 #include "TVldContext.hxx"
00034
00035 #include "UtilString.hxx"
00036
00037 ClassImp(TDbiDBProxy)
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 TDbiDBProxy::TDbiDBProxy(TDbiCascader& cascader,
00055 const string& tableName,
00056 const TDbiTableMetaData* metaData,
00057 const TDbiTableMetaData* metaValid,
00058 const TDbiTableProxy* tableProxy) :
00059 fCascader(cascader),
00060 fMetaData(metaData),
00061 fMetaValid(metaValid),
00062 fTableName(tableName),
00063 fTableProxy(tableProxy)
00064 {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 }
00079
00080
00081
00082 TDbiDBProxy::~TDbiDBProxy() {
00083
00084
00085
00086
00087
00088 SK_DBI_Trace( "Destroying TDbiDBProxy "
00089 << fTableName << " at " << this
00090 << " ");
00091
00092 }
00093
00094
00095 void TDbiDBProxy::FindTimeBoundaries(const TVldContext& vc,
00096 const TDbi::Task& task,
00097 UInt_t dbNo,
00098 const TDbiValidityRec& lowestPriorityVrec,
00099 Bool_t resolveByCreationDate,
00100 TVldTimeStamp& start,
00101 TVldTimeStamp& end) const {
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
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 SK_DBI_Verbose( "FindTimeBoundaries for table " << fTableName
00150 << " context " << vc
00151 << " task " << task
00152 << " Lowest priority VLD creation date: " << lowestPriorityVrec.GetCreationDate()
00153 << " and EPOCH: " << lowestPriorityVrec.GetEpoch()
00154 << " resolve by: " << ( resolveByCreationDate ? "CREATIONDATE" : "EPOCH")
00155 << " database " << dbNo << " ");
00156
00157
00158 start = TVldTimeStamp(0,0);
00159 end = TVldTimeStamp(0x7FFFFFFF,0);
00160
00161
00162
00163 const TVldTimeStamp curVTS = vc.GetTimeStamp();
00164 Int_t timeGate = TDbi::GetTimeGate(this->GetTableName());
00165 time_t vcSec = curVTS.GetSec() - timeGate;
00166 TVldTimeStamp startGate(vcSec,0);
00167 vcSec += 2*timeGate;
00168 TVldTimeStamp endGate(vcSec,0);
00169 string startGateString(TDbi::MakeDateTimeString(startGate));
00170 string endGateString(TDbi::MakeDateTimeString(endGate));
00171
00172
00173
00174 DbiDetector::Detector_t detType(vc.GetDetector());
00175 DbiSimFlag::SimFlag_t simFlg(vc.GetSimFlag());
00176
00177
00178 auto_ptr<TDbiStatement> stmtDb(fCascader.CreateStatement(dbNo));
00179
00180 for (int i_limit =1; i_limit <= 4; ++i_limit ) {
00181 TDbiString sql("select ");
00182 if ( i_limit == 1 ) sql << "min(TIMESTART) from " << fTableName
00183 << "VLD where TIMESTART > '" << endGateString << "' ";
00184 if ( i_limit == 2 ) sql << "min(TIMEEND) from " << fTableName
00185 << "VLD where TIMEEND > '" << endGateString << "' ";
00186 if ( i_limit == 3 ) sql << "max(TIMESTART) from " << fTableName
00187 << "VLD where TIMESTART < '" << startGateString << "' ";
00188 if ( i_limit == 4 ) sql << "max(TIMEEND) from " << fTableName
00189 << "VLD where TIMEEND < '" << startGateString << "' ";
00190 sql << " and DetectorMask & " << static_cast<unsigned int>(detType)
00191 << " and SimMask & " << static_cast<unsigned int>(simFlg)
00192 << " and Task = " << task;
00193 if ( resolveByCreationDate )
00194 sql << " and CREATIONDATE >= '" << TDbi::MakeDateTimeString(lowestPriorityVrec.GetCreationDate()) << "'";
00195 else sql << " and EPOCH >= " << lowestPriorityVrec.GetEpoch();
00196 SK_DBI_Verbose( " FindTimeBoundaries query no. " << i_limit
00197 << " SQL:" <<sql.c_str() << " ");
00198
00199 auto_ptr<TSQLStatement> stmt(stmtDb->ExecuteQuery(sql.c_str()));
00200
00201
00202
00203 TString date;
00204 if ( ! stmt.get() || ! stmt->NextResultRow() || stmt->IsNull(0) ) continue;
00205 date = stmt->GetString(0);
00206 if ( date.IsNull() ) continue;
00207 TVldTimeStamp ts(TDbi::MakeTimeStamp(date.Data()));
00208 SK_DBI_Verbose( " FindTimeBoundaries query result: " << ts << " ");
00209 if ( i_limit <= 2 && ts < end ) end = ts;
00210 if ( i_limit >= 3 && ts > start ) start = ts;
00211
00212 }
00213
00214 SK_DBI_Verbose( "FindTimeBoundaries for table " << fTableName
00215 << " found " << start << " .. " << end << " ");
00216
00217 }
00218
00219
00220 UInt_t TDbiDBProxy::GetNumDb() const {
00221
00222
00223
00224
00225 return fCascader.GetNumDb();
00226
00227 }
00228
00229
00230 Bool_t TDbiDBProxy::HasEpoch() const {
00231 return fMetaValid->HasEpoch();
00232 }
00233
00234
00235 TDbiInRowStream* TDbiDBProxy::QueryAllValidities (UInt_t dbNo,UInt_t seqNo) const {
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 TDbiString sql;
00265
00266 sql << "select * from " << fTableName << "VLD";
00267 if ( fSqlCondition != "" ) sql << " where " << fSqlCondition;
00268 if ( seqNo > 0 ) {
00269 if ( fSqlCondition == "" ) sql << " where ";
00270 else sql << " and ";
00271 sql << "seqno = " << seqNo;
00272 }
00273 sql << ";" << '\0';
00274
00275 SK_DBI_Verbose( "Database: " << dbNo
00276 << " query: " << sql.GetString() << " ");
00277
00278
00279
00280 TDbiStatement* stmtDb = fCascader.CreateStatement(dbNo);
00281 return new TDbiInRowStream(stmtDb,sql,fMetaValid,fTableProxy,dbNo);
00282
00283 }
00284
00285
00286
00287
00288
00289 TDbiInRowStream* TDbiDBProxy::QuerySeqNo(UInt_t seqNo, UInt_t dbNo) const {
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 TDbiTimerManager::gTimerManager.RecMainQuery();
00316 TDbiString sql;
00317 sql << "select * from " << fTableName << " where "
00318 << " SEQNO= " << seqNo;
00319
00320 if ( TDbiServices::OrderContextQuery() ) sql << " order by ROW_COUNTER";
00321
00322 SK_DBI_Verbose( "Database: " << dbNo
00323 << " SeqNo query: " << sql.c_str() << " ");
00324
00325
00326
00327 TDbiStatement* stmtDb = fCascader.CreateStatement(dbNo);
00328 return new TDbiInRowStream(stmtDb,sql,fMetaData,fTableProxy,dbNo);
00329
00330 }
00331
00332
00333
00334 TDbiInRowStream* TDbiDBProxy::QuerySeqNos(SeqList_t& seqNos,
00335 UInt_t dbNo,
00336 const string& sqlData,
00337 const string& fillOpts) const {
00338
00339
00340
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 if ( seqNos.size() == 0 ) return 0;
00369
00370 TDbiTimerManager::gTimerManager.RecMainQuery();
00371 TDbiString sql;
00372 sql << "select * from " << fTableName << " where ";
00373
00374 if ( sqlData != "" ) sql << "( ";
00375 Bool_t first = kTRUE;
00376 SeqList_t::const_iterator itr1 = seqNos.begin();
00377
00378 while ( itr1 != seqNos.end() ) {
00379 UInt_t seq1 = *itr1;
00380 UInt_t seq2 = seq1;
00381 SeqList_t::const_iterator itr2 = itr1;
00382 while ( itr2 != seqNos.end() && seq2 == *itr2 ) {
00383 ++itr2;
00384 ++seq2;
00385 }
00386 if ( first ) {
00387 first = kFALSE;
00388 }
00389 else {
00390 sql << "or ";
00391 }
00392 if ( seq2 > seq1 + 1) {
00393 sql << "SEQNO between " << seq1 << " and " << seq2-1 << ' ';
00394 itr1 = itr2;
00395 }
00396 else {
00397 sql << "SEQNO = " << seq1 << ' ';
00398 ++itr1;
00399 }
00400 }
00401
00402 if ( sqlData != "" ) sql << ") and " << "(" << sqlData << ")" << " ";
00403
00404 sql << "order by SEQNO";
00405
00406 if ( TDbiServices::OrderContextQuery() ) sql << ",ROW_COUNTER";
00407
00408 SK_DBI_Verbose( "Database: " << dbNo
00409 << " SeqNos query: " << sql.c_str() << " ");
00410
00411
00412
00413 TDbiStatement* stmtDb = fCascader.CreateStatement(dbNo);
00414 return new TDbiInRowStream(stmtDb,sql,fMetaData,fTableProxy,dbNo,fillOpts);
00415
00416 }
00417
00418
00419
00420 TDbiInRowStream* TDbiDBProxy::QueryValidity (const TVldContext& vc,
00421 const TDbi::Task& task,
00422 UInt_t dbNo) const {
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 const TVldTimeStamp curVTS = vc.GetTimeStamp();
00454 Int_t timeGate = TDbi::GetTimeGate(this->GetTableName());
00455 time_t vcSec = curVTS.GetSec() - timeGate;
00456 TVldTimeStamp startGate(vcSec,0);
00457 vcSec += 2*timeGate;
00458 TVldTimeStamp endGate(vcSec,0);
00459
00460
00461
00462 string startGateString(TDbi::MakeDateTimeString(startGate));
00463 string endGateString(TDbi::MakeDateTimeString(endGate));
00464 DbiDetector::Detector_t detType(vc.GetDetector());
00465 DbiSimFlag::SimFlag_t simFlg(vc.GetSimFlag());
00466
00467
00468
00469 TDbiString context;
00470 context << " TimeStart <= '" << endGateString << "' "
00471 << "and TimeEnd > '" << startGateString << "' "
00472 << "and DetectorMask & " << static_cast<unsigned int>(detType)
00473 << " and SimMask & " << static_cast<unsigned int>(simFlg);
00474
00475
00476
00477 return this->QueryValidity(context.GetString(),task,dbNo);
00478
00479 }
00480
00481
00482 TDbiInRowStream* TDbiDBProxy::QueryValidity (const string& context,
00483 const TDbi::Task& task,
00484 UInt_t dbNo) const {
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 TDbiString sql;
00509
00510
00511
00512
00513 string orderByName("CREATIONDATE desc");
00514 if ( this->HasEpoch() ) orderByName = "EPOCH desc,TIMESTART desc,INSERTDATE desc";
00515 sql << "select * from " << fTableName << "VLD"
00516 << " where " ;
00517 if ( fSqlCondition != ""
00518 ) sql << fSqlCondition << " and ";
00519 sql << context;
00520 if ( task != TDbi::kAnyTask
00521 ) sql << " and Task = " << task
00522 << " order by " << orderByName << ";" << '\0';
00523
00524 SK_DBI_Verbose( "Database: " << dbNo
00525 << " query: " << sql.c_str() << " ");
00526
00527
00528
00529 TDbiStatement* stmtDb = fCascader.CreateStatement(dbNo);
00530 return new TDbiInRowStream(stmtDb,sql,fMetaValid,fTableProxy,dbNo);
00531
00532 }
00533
00534
00535 TDbiInRowStream* TDbiDBProxy::QueryValidity (UInt_t seqNo,
00536 UInt_t dbNo) const {
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 TDbiString sql;
00559 sql << "select * from " << fTableName << "VLD where ";
00560 if ( fSqlCondition != "" ) sql << fSqlCondition << " and ";
00561 sql << "SEQNO = " << seqNo << ";";
00562
00563 SK_DBI_Verbose( "Database: " << dbNo
00564 << " SEQNO query: " << sql.c_str() << " ");
00565
00566
00567
00568 TDbiStatement* stmtDb = fCascader.CreateStatement(dbNo);
00569 return new TDbiInRowStream(stmtDb,sql,fMetaValid,fTableProxy,dbNo);
00570
00571 }
00572
00573
00574
00575 Bool_t TDbiDBProxy::RemoveSeqNo(UInt_t seqNo,
00576 UInt_t dbNo) const {
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 TDbiString sql;
00602 sql << "delete from " << fTableName
00603 << " where SEQNO = " << seqNo << ";"
00604 << '\0';
00605
00606 SK_DBI_Verbose( "Database: " << dbNo
00607 << " RemoveSeqNo SQL: " << sql.c_str() << " ");
00608
00609
00610 auto_ptr<TDbiStatement> stmtDb(fCascader.CreateStatement(dbNo));
00611 if ( ! stmtDb.get() ) return false;
00612 if ( ! stmtDb->ExecuteUpdate(sql.c_str()) || stmtDb->PrintExceptions() ) {
00613 SK_DBI_Severe( "SQL: " << sql.c_str()
00614 << " Failed. " << " ");
00615 return false;
00616 }
00617
00618
00619 sql.GetString().erase();
00620 sql << "delete from " << fTableName
00621 << "VLD where SEQNO = " << seqNo << ";"
00622 << '\0';
00623
00624 SK_DBI_Verbose( "Database: " << dbNo
00625 << " RemoveSeqNo SQL: " << sql.c_str() << " ");
00626
00627
00628 if ( ! stmtDb->ExecuteUpdate(sql.c_str()) || stmtDb->PrintExceptions() ) {
00629 SK_DBI_Severe( "SQL: " << sql.c_str()
00630 << " Failed. " << " ");
00631 return false;
00632 }
00633
00634 return true;
00635
00636 }
00637
00638
00639
00640 Bool_t TDbiDBProxy::ReplaceInsertDate(const TVldTimeStamp& ts,
00641 UInt_t SeqNo,
00642 UInt_t dbNo) const{
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 TDbiString sql;
00659 sql << "update " << fTableName
00660 << "VLD set INSERTDATE = \'" << ts.AsString("s")
00661 << "\' where SEQNO = " << SeqNo << ";"
00662 << '\0';
00663
00664 SK_DBI_Verbose( "Database: " << dbNo
00665 << " ReplaceInsertDate SQL: "
00666 << sql.c_str() << " ");
00667
00668
00669 auto_ptr<TDbiStatement> stmtDb(fCascader.CreateStatement(dbNo));
00670 if ( ! stmtDb.get() ) return false;
00671 if (! stmtDb->ExecuteUpdate(sql.c_str()) || stmtDb->PrintExceptions() ) {
00672 SK_DBI_Severe( "SQL: " << sql.c_str()
00673 << " Failed. " << " ");
00674 return false;
00675 }
00676
00677 return true;
00678
00679 }
00680
00681
00682 Bool_t TDbiDBProxy::ReplaceSeqNo(UInt_t oldSeqNo,
00683 UInt_t newSeqNo,
00684 UInt_t dbNo) const {
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 if ( ! fCascader.GetConnection(dbNo) ) {
00709 SK_DBI_Warn( "Cannot renumber " << oldSeqNo
00710 << " no connection to cascade entry " << dbNo << " ");
00711 return false;
00712 }
00713
00714
00715 TDbiString sql;
00716 sql << "update " << fTableName
00717 << "VLD set SEQNO = " << newSeqNo
00718 << " where SEQNO = " << oldSeqNo << ";"
00719 << '\0';
00720
00721 SK_DBI_Verbose( "Database: " << dbNo
00722 << " ReplaceSeqNo SQL: " << sql.c_str() << " ");
00723
00724
00725 auto_ptr<TDbiStatement> stmtDb(fCascader.CreateStatement(dbNo));
00726 if ( ! stmtDb.get() ) return false;
00727 if ( ! stmtDb->ExecuteUpdate(sql.c_str()) || stmtDb->PrintExceptions() ) {
00728 SK_DBI_Severe( "SQL: " << sql.c_str()
00729 << " Failed. " << " ");
00730 return false;
00731 }
00732
00733
00734 sql.GetString().erase();
00735 sql << "update " << fTableName
00736 << " set SEQNO = " << newSeqNo
00737 << " where SEQNO = " << oldSeqNo << ";"
00738 << '\0';
00739
00740 SK_DBI_Verbose( "Database: " << dbNo
00741 << " ReplaceSeqNo SQL: " << sql.c_str() << " ");
00742
00743
00744 if ( ! stmtDb->ExecuteUpdate(sql.c_str()) || stmtDb->PrintExceptions() ) {
00745 SK_DBI_Severe( "SQL: " << sql.c_str()
00746 << " Failed. " << " ");
00747 return false;
00748 }
00749
00750 return true;
00751
00752 }
00753
00754
00755
00756 void TDbiDBProxy::StoreMetaData(TDbiTableMetaData& metaData) const {
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 const char* tableName = metaData.TableName().c_str();
00767 SK_DBI_Verbose( "Get meta-data for table: " << tableName << " ");
00768
00769
00770
00771 for ( UInt_t dbNo = 0; dbNo < fCascader.GetNumDb(); dbNo++ ) {
00772 TDbiConnection* connection = fCascader.GetConnection(dbNo);
00773 TSQLServer* server = connection->GetServer();
00774 if ( ! server ) continue;
00775 connection->Connect();
00776 TSQLTableInfo* meta = server->GetTableInfo(tableName);
00777 if ( ! meta ) {
00778 connection->DisConnect();
00779 continue;
00780 }
00781 SK_DBI_Verbose( "Meta-data query succeeded on cascade entry " << dbNo << " ");
00782
00783
00784 metaData.Clear();
00785
00786 const TList* cols = meta->GetColumns();
00787 TIter colItr(cols);
00788 int col = 0;
00789 while ( TSQLColumnInfo* colInfo = dynamic_cast<TSQLColumnInfo*>(colItr.Next()) ) {
00790
00791 ++col;
00792 string name(colInfo->GetName());
00793 name = UtilString::ToUpper(name);
00794 metaData.SetColName(name,col);
00795
00796 TDbiFieldType fldType(colInfo->GetSQLType(),
00797 colInfo->GetLength(),
00798 colInfo->GetTypeName());
00799
00800
00801 if ( !colInfo->IsSigned() ) fldType.SetUnsigned();
00802 metaData.SetColFieldType(fldType,col);
00803
00804 metaData.SetColIsNullable(col,colInfo->IsNullable());
00805
00806 SK_DBI_Verbose( "Column " << col << " " << name
00807 << " SQL type " << colInfo->GetSQLType()
00808 << " SQL type name " << colInfo->GetTypeName()
00809 << " DBI type " << fldType.AsString()
00810 << " data size: " << fldType.GetSize()
00811 << " col size: " << colInfo->GetLength() << " ");
00812
00813 }
00814 delete meta;
00815 connection->DisConnect();
00816 return;
00817 }
00818 }
00819
00820
00821
00822 Bool_t TDbiDBProxy::TableExists(Int_t selectDbNo) const {
00823
00824
00825
00826
00827
00828
00829 return fCascader.TableExists(fTableName,selectDbNo);
00830
00831 }
00832
00833