TDbiDBProxy.cxx

Go to the documentation of this file.
00001 
00002 //////////////////////////////////////////////////////////////////////////
00003 ////////////////////////////     ROOT API     ////////////////////////////
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 //   Typedefs
00040 //   ********
00041 
00042 //   Definition of static data members
00043 //   *********************************
00044 
00045 
00046 //    Definition of all member functions (static or otherwise)
00047 //    *******************************************************
00048 //
00049 //    -  ordered: ctors, dtor, operators then in alphabetical order.
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 //  Purpose:  Constructor
00068 //
00069 //  Arguments:
00070 //  cascader   in   Reference to one and only cascader
00071 //  tableName  in   Table name.
00072 //  metaData   in   Meta data for main table.
00073 //  metaValid  in   Meta data for validity.
00074 //  tableProxy in   Owning TDbiTableProxy.
00075 //
00076 
00077 
00078 }
00079 
00080 //.....................................................................
00081 
00082 TDbiDBProxy::~TDbiDBProxy() {
00083 //
00084 //
00085 //  Purpose: Destructor
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 //  Purpose: Find next time boundaries beyond standard time gate.
00105 //
00106 //  Arguments:
00107 //    vc                    in    The Validity Context for the query.
00108 //    task                  in    The task of the query.
00109 //    dbNo                  in    Database number in cascade (starting at 0).
00110 //    lowestPriorityVrec    in    Lowest priority VLD in the time gate
00111 //    resolveByCreationDate in  The method for resolving VLDs:
00112 //                                 if true use CREATIONDATE (MINOS scheme)
00113 //                                 if false use EPOCH,TIMESTART,INSERTDATE (T2K scheme)
00114 //    start                 out   Lower time boundary or TVldTimeStamp(0,0) if none
00115 //    end                   out   Upper time boundary or TVldTimeStamp(0x7FFFFFFF,0) if none
00116 //
00117 //  Specification:-
00118 //  =============
00119 //
00120 //  o Find the next time boundary (either TIMESTART or TIMEEND)
00121 //    outside the current time gate that is potentionally of higher priority.
00122 //
00123 //  Explanation:-
00124 //  ===========
00125 //
00126 //
00127 //  In oder to keep the number of VLDs to a manageable level when doing a
00128 //  Standard Context query, a time gate around the context is imposed and
00129 //  any VLD rejected if it does not overlap the query. However, this
00130 //  implies that the maximum validity of the query result set is also
00131 //  limited by the time gate and hence the interface will again have to
00132 //  query the database when a context outside the time gate is
00133 //  requested. This function attempts to open up the validity of the
00134 //  result set by looking for the nearest start or end of a VLD outside
00135 //  the time gate that is of higher priority. In MINOS, priority is just
00136 //  CREATIONDATE, so the function just looks for VLDs with a higher
00137 //  CREATIONDATE.  For T2K the priority scheme is more complicated:
00138 //  EPOCH,TIMESTART,INSERTDATE and it is not possible to construct a SQL
00139 //  query that only considers higher priority VLDs so the function makes a
00140 //  simplification and only rejects VLDs with a lower EPOCH number.  The
00141 //  consequence of this is that it may accept VLDs that are of a lower
00142 //  priority than the current one and hence the result set validity does
00143 //  not get opened up to its full extent.  All this means is that the
00144 //  interface will have to make another query earlier that it need do but
00145 //  at least it will not miss a VLD boundary and should still keep the current
00146 //  results longer than it would have if this function had not been
00147 //  called.
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 //  Set the limits wide open
00158   start = TVldTimeStamp(0,0);
00159   end   = TVldTimeStamp(0x7FFFFFFF,0);
00160 
00161 //  Construct a Time Gate on the current date.
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 // Extract information for TVldContext.
00173 
00174   DbiDetector::Detector_t    detType(vc.GetDetector());
00175   DbiSimFlag::SimFlag_t       simFlg(vc.GetSimFlag());
00176 
00177 // Use an auto_ptr to manage ownership of TDbiStatement and TSQLStatement
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 //  If the query returns data, convert to a time stamp and trim the limits
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 //  Purpose:  Return the number of databases in the cascade.
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 //  Purpose:  Apply all validities query to database..
00239 //
00240 //  Arguments:
00241 //    dbNo         in    Database number in cascade (starting at 0).
00242 //    seqNo        in    Just this SEQNO if >0 or all if 0 [default: 0]
00243 //
00244 //  Return:    New TDbiResultSet object.
00245 //             NB  Caller is responsible for deleting..
00246 //
00247 //  Contact:   N. West
00248 //
00249 //  Specification:-
00250 //  =============
00251 //
00252 //  o Ask for every row in associated validity range table and return
00253 //    query results qualifying selection by fSqlCondition if defined.
00254 
00255 //  Program Notes:-
00256 //  =============
00257 
00258 //  This function is provided to support database maintenance
00259 //  rather than standard TDbi related I/O
00260 
00261 
00262 // Generate SQL for validity table.
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 //  Apply query and return result..
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 //  Purpose:  Apply sequence query to database..
00293 //
00294 //  Arguments:
00295 //    seqNo        in    The sequence number for the query.
00296 //    dbNo         in    Database number in cascade (starting at 0).
00297 //
00298 //  Return:    New TDbiResultSet object.
00299 //             NB  Caller is responsible for deleting..
00300 //
00301 //  Contact:   N. West
00302 //
00303 //  Specification:-
00304 //  =============
00305 //
00306 //  o Apply sequence query to table and return query results
00307 
00308 //  Program Notes:-
00309 //  =============
00310 
00311 //  None..
00312 
00313 // Generate SQL.
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 //  Apply query and return result..
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 //  Purpose:  Apply query for a list of sequence numbers to database..
00341 //
00342 //  Arguments:
00343 //    seqNos       in    The vector of sequence numbers for the query.
00344 //                       Should be in acsending order, see Program Notes
00345 //    dbNo         in    Database number in cascade (starting at 0).
00346 //    sqlData      in    Optional SQL extension to secondary query.
00347 //    fillOpts     in    Optional fill options (available to TDbiTableRow
00348 //                       objects when filling.
00349 //
00350 //  Return:    New TDbiResultSet object.
00351 //             NB  Caller is responsible for deleting..
00352 //
00353 //  Contact:   N. West
00354 //
00355 //  Specification:-
00356 //  =============
00357 //
00358 //  o Apply sequence query to table and return query results
00359 
00360 //  Program Notes:-
00361 //  =============
00362 
00363 //  Where possible the SQL query is kept to a minimm by using
00364 //  `BETWEEN' comparison to bracket ranges of numbers.
00365 
00366 // Generate SQL.
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 //  Apply query and return result..
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 //  Purpose:  Apply validity query to database..
00426 //
00427 //  Arguments:
00428 //    vc           in    The Validity Context for the query.
00429 //    task         in    The task of the query.
00430 //    dbNo         in    Database number in cascade (starting at 0).
00431 //
00432 //  Return:    New TDbiResultSet object.
00433 //             NB  Caller is responsible for deleting..
00434 //
00435 //  Contact:   N. West
00436 //
00437 //  Specification:-
00438 //  =============
00439 //
00440 //  o Apply query to associated validity range table and return query
00441 //    results qualifying selection by fSqlCondition if defined.
00442 
00443 //  Program Notes:-
00444 //  =============
00445 
00446 //  Rather than search over the full table this function places
00447 //  a time gate round the context time and then trims any validity
00448 //  range returned to this gate.  See FindTimeBoundaries to get a
00449 //  more accurate validity range.
00450 
00451 //  Construct a search window on the current date.
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 // Extract information for TVldContext.
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 // Generate SQL for context.
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 //  Apply query and return result..
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 //  Purpose:  Apply validity query to database..
00488 //
00489 //  Arguments:
00490 //    context      in    The Validity Context (see TDbiSqlContext)
00491 //    task         in    The task of the query.
00492 //    dbNo         in    Database number in cascade (starting at 0).
00493 //
00494 //  Return:    New TDbiResultSet object.
00495 //             NB  Caller is responsible for deleting..
00496 //
00497 //  Contact:   N. West
00498 //
00499 //  Specification:-
00500 //  =============
00501 //
00502 //  o Apply query to associated validity range table and return query
00503 //    results qualifying selection by fSqlCondition if defined.
00504 
00505 
00506 // Generate SQL for validity table.
00507 
00508   TDbiString sql;
00509 
00510 // In the MINOS  scheme queries are  ordered by creation date (the later the better)
00511 // but if the table has an EPOCH column then the T2K scheme is used (EPOCH,TIMESTART,INSERTDATE)
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 //  Apply query and return result..
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 //  Purpose:  Apply validity query to database..
00540 //
00541 //  Arguments:
00542 //    seqNo        in    The SEQNO of the validity rec.
00543 //
00544 //  Return:    New TDbiResultSet object.
00545 //             NB  Caller is responsible for deleting..
00546 //
00547 //  Contact:   N. West
00548 //
00549 //  Specification:-
00550 //  =============
00551 //
00552 //  o Apply query to associated validity range table and return query
00553 //    results qualifying selection by fSqlCondition if defined.
00554 
00555 
00556 // Generate SQL for validity table.
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 //  Apply query and return result..
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 //  Purpose:  Remove sequence number in main and auxiliary tables.
00580 //
00581 //  Arguments:
00582 //    seqNo        in    The sequence number to be removed.
00583 //    dbNo         in    Database number in cascade (starting at 0).
00584 //
00585 //  Return:    kTRUE if output successful,otherwise kFALSE.
00586 //
00587 //  Contact:   N. West
00588 //
00589 //  Specification:-
00590 //  =============
00591 //
00592 //  o Remove sequence number in main and auxiliary tables.
00593 
00594 //  Program Notes:-
00595 //  =============
00596 
00597 //  None.
00598 
00599 
00600 // Generate SQL to remove SeqNo in main table.
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 //  Apply query.
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 // Generate SQL to remove SeqNo in validity table.
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 //  Apply query.
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 //  Purpose:  Replace insertion date for row in auxiliary table.
00646 //
00647 //  Arguments:
00648 //    ts           in    Time stamp for new insertion date.
00649 //    SeqNo        in    The sequence number of the row to be replaced.
00650 //    dbNo         in    Database number in cascade (starting at 0).
00651 //
00652 //  Return:    kTRUE if output successful,otherwise kFALSE.
00653 //
00654 //  Contact:   N. West
00655 
00656 
00657 // Generate SQL.
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 //  Apply query.
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 //  Purpose:  Replace sequence number in main and auxiliary tables.
00688 //
00689 //  Arguments:
00690 //    oldSeqNo     in    The old sequence number.
00691 //    nwSeqNo      in    The new sequence number.
00692 //    dbNo         in    Database number in cascade (starting at 0).
00693 //
00694 //  Return:    kTRUE if output successful,otherwise kFALSE.
00695 //
00696 //  Contact:   N. West
00697 //
00698 //  Specification:-
00699 //  =============
00700 //
00701 //  o Replace sequence number in main and auxiliary tables.
00702 
00703 //  Program Notes:-
00704 //  =============
00705 
00706 //  None.
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 // Generate SQL to replace SeqNo in validity table.
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 //  Apply query.
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 // Generate SQL to replace SeqNo in main table.
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 //  Apply query.
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 //  Purpose:  Store table meta data.
00760 //
00761 //  Arguments:
00762 //    metaData   in    Empty TDbiTableMetaData object apart from table name.
00763 
00764 
00765 
00766   const char* tableName = metaData.TableName().c_str();
00767   SK_DBI_Verbose( "Get meta-data for table: " << tableName << "  ");
00768 
00769 //  Check each Db in turn until table found and store table meta data.
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     // Clear out any existing data, although there should not be any.
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       // For now continue to check for unsigned (even though not supported)
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 //  Purpose:  Return true if table exists on selected cascade entry
00826 //            or any entry if selectDbNo=-1 (default)
00827 
00828 
00829   return fCascader.TableExists(fTableName,selectDbNo);
00830 
00831 }
00832 
00833 

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1