Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DbiTableProxy.cxx

Go to the documentation of this file.
00001 // $Id: DbiTableProxy.cxx,v 1.28 2006/08/08 10:51:32 west Exp $
00002 
00003 #include "Conventions/Detector.h"
00004 #include "Conventions/SimFlag.h"
00005 #include "DatabaseInterface/DbiBinaryFile.h"
00006 #include "DatabaseInterface/DbiCache.h"
00007 #include "DatabaseInterface/DbiConnectionMaintainer.h"
00008 #include "DatabaseInterface/DbiResultAgg.h"
00009 #include "DatabaseInterface/DbiResultNonAgg.h"
00010 #include "DatabaseInterface/DbiResultSet.h"
00011 #include "DatabaseInterface/DbiTableProxy.h"
00012 #include "DatabaseInterface/DbiTableRow.h"
00013 #include "DatabaseInterface/DbiTimerManager.h"
00014 #include "DatabaseInterface/DbiValidityRec.h"
00015 #include "DatabaseInterface/DbiValidityRecBuilder.h"
00016 #include "LeakChecker/Lea.h"
00017 #include "MessageService/MsgService.h"
00018 
00019 ClassImp(DbiTableProxy)
00020 
00021 //   Definition of static data members
00022 //   *********************************
00023 
00024 CVSID("$Id: DbiTableProxy.cxx,v 1.28 2006/08/08 10:51:32 west Exp $");
00025 
00026 //    Definition of all member functions (static or otherwise)
00027 //    *******************************************************
00028 //
00029 //    -  ordered: ctors, dtor, operators then in alphabetical order.
00030 
00031 //.....................................................................
00032 
00033 DbiTableProxy::DbiTableProxy(DbiCascader* cascader, 
00034                              const string& tableName,
00035                              const string& vldSuffix,
00036                              const DbiTableRow* tableRow) :
00037   fCascader(cascader),
00038 fMetaData(tableName),
00039 fMetaValid(tableName+vldSuffix),
00040 fCanL2Cache(kFALSE),
00041 fCache(0),
00042 fDBProxy(*cascader,tableName,&fMetaData,&fMetaValid,this),
00043 fExists(0),
00044 fTableName(tableName),
00045 fTableRow(tableRow->CreateTableRow())
00046 {
00047 //
00048 //
00049 //  Purpose:  Constructor
00050 //
00051 //  Arguments:   
00052 //             in  cascader   Reference to one and only cascader
00053 //             in  tableName  Table name.
00054 //             in  vldSuffix  Suffix to tableName for validity table
00055 //             in  tableRow   Example table row object.
00056 //
00057 //  Return:    n/a
00058 //
00059 //  Contact:   N. West
00060 //
00061 //  Specification:-
00062 //  =============
00063 //
00064 //  o Create table proxy for supplied table name.
00065 
00066 
00067 //  Program Notes:-
00068 //  =============
00069 
00070 //  None.
00071 
00072   LEA_CTOR    //Leak Checker
00073 
00074   fCache = new DbiCache(*this,fTableName);
00075   this->RefreshMetaData();
00076   fExists = fDBProxy.TableExists();
00077   fCanL2Cache = tableRow->CanL2Cache();
00078   if ( fCanL2Cache ) 
00079     MSG("Dbi", Msg::kInfo) << "DbiTableProxy: Can L2 cache " << this->GetRowName() << endl;
00080   MSG("Dbi", Msg::kVerbose) << "Creating DbiTableProxy " 
00081                           << fTableName.c_str() << " at " << this
00082                           << ( fExists ? " (table exists)" 
00083                                        : " (table missing)" )
00084                           << endl;
00085 }
00086 
00087 //.....................................................................
00088 
00089 DbiTableProxy::~DbiTableProxy() {
00090 //
00091 //
00092 //  Purpose: Destructor
00093 //
00094 //  Arguments: 
00095 //    None.
00096 //
00097 //  Return:    n/a
00098 //
00099 //  Contact:   N. West
00100 //
00101 //  Specification:-
00102 //  =============
00103 //
00104 //  o  Destroy object.
00105 
00106 
00107 //  Program Notes:-
00108 //  =============
00109 
00110 //  None.
00111 
00112   LEA_DTOR    //Leak Checker
00113 
00114     MSG("Dbi", Msg::kVerbose) << "Destroying DbiTableProxy " 
00115                             << fTableName << " at " << this
00116                             << endl;
00117   delete fCache;
00118   delete fTableRow;
00119 
00120 }
00121 //.....................................................................
00122 
00123 Bool_t DbiTableProxy::CanReadL2Cache() const {
00124 //
00125 
00126   return fCanL2Cache && DbiBinaryFile::CanReadL2Cache();
00127 
00128 }
00129 Bool_t DbiTableProxy::CanWriteL2Cache() const {
00130 //
00131 
00132   return fCanL2Cache && DbiBinaryFile::CanWriteL2Cache();
00133 
00134 }
00135 
00136 //.....................................................................
00137 
00138 const DbiResult* DbiTableProxy::Query(const VldContext& vc, 
00139                                       const Dbi::Task& task,
00140                                       Bool_t findFullTimeWindow) {
00141 //
00142 //
00143 //  Purpose:  Apply context specific query to database table and return result.
00144 //
00145 //  Arguments: 
00146 //    vc           in    The Validity Context for the query.
00147 //    task         in    The task of the query.
00148 //    findFullTimeWindow
00149 //                 in    Attempt to find full validity of query 
00150 //                        i.e. beyond Dbi::GetTimeGate
00151 //
00152 //  Return:    Query result (never zero even if query fails).
00153 //
00154 //  Contact:   N. West
00155 //
00156 //  Specification:-
00157 //  =============
00158 //
00159 //  o Apply query to database table and return result.
00160 
00161 //  Program Notes:-
00162 //  =============
00163 
00164 //  None.
00165 
00166 //  See if there is one already in the cache for universal aggregate no.
00167 
00168   if ( const DbiResult* result = fCache->Search(vc,task) 
00169      ) return result;
00170 
00171   DbiConnectionMaintainer cm(fCascader);  //Stack object to hold connections
00172 
00173 // Make Global Exception Log bookmark
00174   UInt_t startGEL = DbiExceptionLog::GetGELog().Size()+1;
00175 
00176 // Build a complete set of effective validity record from the database.
00177   DbiValidityRecBuilder builder(fDBProxy,vc,task,-1,findFullTimeWindow);
00178 
00179 // Deal with non-aggregated data.
00180 
00181   if ( builder.NonAggregated() ) {
00182 
00183     DbiValidityRec effVRec = builder.GetValidityRec(0);
00184 //  Force off const - we haven't finished with DbiResult yet!
00185     DbiResult* result = const_cast<DbiResult*>(Query(effVRec));
00186 //  Record latest entries from Global Exception Log.
00187     result->CaptureExceptionLog(startGEL);
00188     return result;
00189   }
00190 
00191 // Deal with aggregated data.
00192 
00193 // Don't look in the level 2 cache if more than half of the 
00194 // component aggregates are already in the cache;
00195 // for in this case, the chances are that we have just 
00196 // crossed a validity boundary in only a few aggregates and 
00197 // we don't want to waste time loading in a full set only to throw
00198 // it away again.
00199 
00200   if ( this->CanReadL2Cache() ) {
00201     UInt_t numPresent  = 0;
00202     UInt_t numRequired = 0;
00203     Int_t maxRow = builder.GetNumValidityRec() - 1;
00204     for ( Int_t rowNo = 1; rowNo <= maxRow; ++rowNo ) {
00205       const DbiValidityRec& vrec = builder.GetValidityRec(rowNo);
00206       if ( fCache->Search(vrec) ) ++numPresent;
00207       else if ( ! vrec.IsGap() ) ++numRequired;
00208     }
00209     if ( numRequired < numPresent ) MSG("Dbi",Msg::kInfo) 
00210       << "Skipping search of L2 cache; already have "
00211       << numPresent << " aggregates, and only require a further "
00212       << numRequired << endl;
00213     else this->RestoreFromL2Cache(builder);
00214   }
00215 
00216   DbiResult* result = new DbiResultAgg(fTableName,
00217                                        fTableRow,
00218                                        fCache,
00219                                        &builder,
00220                                        &fDBProxy);
00221 // Record latest entries from Global Exception Log.
00222   result->CaptureExceptionLog(startGEL);
00223 
00224   fCache->Adopt(result);
00225   this->SaveToL2Cache(builder.GetL2CacheName(),*result);
00226   return result;
00227 
00228 }
00229 //.....................................................................
00230 
00231 const DbiResult* DbiTableProxy::Query(const string& context, 
00232                                       const Dbi::Task& task,
00233                                       const string& data,
00234                                       const string&fillOpts) {
00235 //
00236 //
00237 //  Purpose:  Apply extended context query to database table and return result.
00238 //
00239 //  Arguments: 
00240 //    context      in    The Validity Context (see DbiSqlContext)
00241 //    task         in    The task of the query.
00242 //    data         in    Optional SQL extension to secondary query.
00243 //    fillOpts     in    Optional fill options (available to DbiTableRow)
00244 //
00245 //  Return:    Query result (never zero even if query fails).
00246 //
00247 //  Contact:   N. West
00248 //
00249 //  Specification:-
00250 //  =============
00251 //
00252 //  o Apply extended context query to database table and return result.
00253 //
00254 //  o Don't save/restore to L2 cache: encoding the query name as a file name
00255 //    would be cumbersome and in any case extended queries are abnormal
00256 //    so optimisation is unwarranted.
00257 
00258 
00259 //  Construct the query's "SQL Qualifiers" by forming the 3 strings 
00260 //  (which task encoded into the context) into a single semi-colon 
00261 //  separated string.
00262 
00263   std::ostringstream os;
00264   os << context;
00265   if ( task != Dbi::kAnyTask
00266        ) os << " and  Task = " << task;
00267   os <<  ';' << data << ';' << fillOpts;
00268   string sqlQualifiers = os.str();
00269 
00270   MSG("Dbi", Msg::kVerbose) 
00271     << "Extended query: sqlQualifiers: " << sqlQualifiers << endl;
00272 
00273 //  See if there is one already in the cache.
00274 
00275   if ( const DbiResult* result = fCache->Search(sqlQualifiers) 
00276      ) return result;
00277 
00278   DbiConnectionMaintainer cm(fCascader);  //Stack object to hold connections
00279 
00280 // Make Global Exception Log bookmark
00281   UInt_t startGEL = DbiExceptionLog::GetGELog().Size()+1;
00282 
00283 // Build a complete set of effective validity records from the database.
00284   DbiValidityRecBuilder builder(fDBProxy,context,task);
00285 
00286 // For extended context queries, DbiValidityRecBuilder will always 
00287 // assemble a result that has to be represented by a DbiResultAgg
00288 
00289   DbiResult* result = new DbiResultAgg(fTableName,
00290                                        fTableRow,
00291                                        fCache,
00292                                        &builder,
00293                                        &fDBProxy,
00294                                        sqlQualifiers);
00295 // Record latest entries from Global Exception Log.
00296   result->CaptureExceptionLog(startGEL);
00297 
00298   fCache->Adopt(result);
00299   return result;
00300 
00301 }
00302 //.....................................................................
00303 
00304 const DbiResult* DbiTableProxy::Query(UInt_t seqNo,UInt_t dbNo) {
00305 //
00306 //
00307 //  Purpose:  Apply non-agregate query to database table and return result.
00308 //
00309 //  Arguments: 
00310 //    seqNo        in    The sequence number of validity record that satisfies the query.
00311 //    dbNo         in    Database number in the cascade.
00312 //
00313 //  Return:    Query result (never zero even if query fails).
00314 
00315   DbiConnectionMaintainer cm(fCascader);  //Stack object to hold connections
00316 
00317 // Make Global Exception Log bookmark
00318   UInt_t startGEL = DbiExceptionLog::GetGELog().Size()+1;
00319 
00320   // Apply SEQNO query to cascade member.
00321   DbiResultSet* rs = fDBProxy.QueryValidity(seqNo,dbNo);
00322   DbiValidityRec tr;
00323   DbiResultNonAgg result(rs,&tr,0,kFALSE);
00324   delete rs;
00325 
00326   // If query failed, return an empty result.
00327   if ( result.GetNumRows() == 0 ) {
00328     DbiResultNonAgg* empty = new DbiResultNonAgg();
00329 //  Record latest entries from Global Exception Log.
00330     empty->CaptureExceptionLog(startGEL);
00331     fCache->Adopt(empty);
00332     return empty;
00333   }
00334 
00335 // Otherwise perform a validity rec query, but don't
00336 // allow result to be used; it's validity has not been trimmed
00337 // by neighbouring records.
00338 
00339   const DbiValidityRec* vrec 
00340        = dynamic_cast<const DbiValidityRec*>(result.GetTableRow(0));
00341 //  Force off const - we haven't finished with DbiResult yet!
00342   DbiResult* res = const_cast<DbiResult*>(Query(*vrec,kFALSE));
00343 // Record latest entries from Global Exception Log.
00344   res->CaptureExceptionLog(startGEL);
00345   return res;
00346 
00347 }
00348 //.....................................................................
00349 
00350 const DbiResult* DbiTableProxy::Query(const DbiValidityRec& vrec, 
00351                                       Bool_t canReuse /* = kTRUE */) {
00352 //
00353 //
00354 //  Purpose:  Apply non-agregate query to database table and return result.
00355 //
00356 //  Arguments: 
00357 //    vrec         in    The validity record that satisfies the query.
00358 //    canReuse     in    True if result is to be cached.
00359 //
00360 //  Return:    Query result (never zero even if query fails).
00361 //
00362 //  Contact:   N. West
00363 //
00364 //  Specification:-
00365 //  =============
00366 //
00367 //  o Apply non-aggregated query to main database table. Cache if required,
00368 //    and return result.
00369 
00370 
00371 // See if it can be recovered from the level 2 disk cache.
00372 
00373   DbiConnectionMaintainer cm(fCascader);  //Stack object to hold connections
00374 
00375 // Make Global Exception Log bookmark
00376   UInt_t startGEL = DbiExceptionLog::GetGELog().Size()+1;
00377 
00378   if ( canReuse ) {
00379     DbiValidityRecBuilder builder(vrec,this->GetTableName());
00380     if ( this->RestoreFromL2Cache(builder) ) {
00381       const DbiResult* res = fCache->Search(vrec);
00382       if ( res ) return res;
00383     }
00384   }
00385 
00386   unsigned int seqNo = vrec.GetSeqNo();
00387   DbiResult* result = 0;
00388 
00389 //  If no records, create an empty DbiResult.
00390   if ( ! seqNo ) {
00391     result = new DbiResultNonAgg(0,0,&vrec);
00392   }
00393 
00394 //  If query does not apply to this table, report error and
00395 //  produce an empty DbiResult.
00396 
00397   else if (vrec.GetTableProxy()->GetTableName() != GetTableName() ) {
00398     MAXMSG("Dbi",Msg::kError,20) 
00399        << "Unable to satisfy DbiValidityRec keyed query:" << endl
00400        << vrec
00401        << " was filled by " << vrec.GetTableProxy()->GetTableName() 
00402        << " not by this DbiTableProxy (" 
00403        << GetTableName() << ")" << endl;
00404     result = new DbiResultNonAgg(0,0,&vrec);
00405   }
00406 
00407   else {
00408 
00409 
00410 // Apply query, and build DiResult from its DbiResultSet.
00411 
00412     DbiResultSet* rs = fDBProxy.QuerySeqNo(seqNo,vrec.GetDbNo());
00413     result = new DbiResultNonAgg(rs,fTableRow,&vrec);
00414     delete rs;
00415   }
00416 
00417 // Record latest entries from Global Exception Log.
00418   result->CaptureExceptionLog(startGEL);
00419 
00420 //  Cache in memory and on disk if required and return the results.
00421 
00422   fCache->Adopt(result);
00423   if ( canReuse ) this->SaveToL2Cache(vrec.GetL2CacheName(),*result);
00424   else result->SetCanReuse(kFALSE);
00425 
00426   return result;
00427 
00428 }
00429 
00430 //.....................................................................
00431 
00432 void DbiTableProxy::RefreshMetaData() {
00433 //
00434 //
00435 //  Purpose:  Refresh meta data for table.
00436 //
00437 
00438   fDBProxy.StoreMetaData(fMetaData);
00439   fDBProxy.StoreMetaData(fMetaValid);
00440 
00441 }
00442 //.....................................................................
00443 
00444 VldTimeStamp DbiTableProxy::QueryOverlayCreationDate(const DbiValidityRec& vrec,
00445                                                      UInt_t dbNo)
00446 {
00447 //
00448 //  Purpose:  Determine a suitable Creation Date so that this validity
00449 //            record, if written to the selected DB, will overlay
00450 //            correctly.
00451 //
00452 //  Specification:-
00453 //  =============
00454 //
00455 //  o Determine optimal Creation Date to overlay new data.  See Program Notes.
00456 
00457 //  Program Notes:-
00458 //  =============
00459 
00460 
00461 // It is normal practice, particularly for calibration data, to have
00462 // overlapping the validity records.  Each time a new set of runs are
00463 // processed the start time of the validity is set to the start time of
00464 // the first run and the end time is set beyond the start time by an
00465 // interval that characterises the stability of the constants.  So long
00466 // as a new set of constants is created before the end time is reached
00467 // there will be no gap.  Where there is an overlap the Creation Date is
00468 // used to select the later constants on the basis that later is better.
00469 // However, if reprocessing old data it is also normal practice to
00470 // process recent data first and in this case the constants for earlier
00471 // data get later creation dates and overlay works the wrong way.  To
00472 // solve this, the creation date is faked as follows:-
00473 //
00474 //
00475 //   1.  For new data i.e. data that does not overlay any existing data,
00476 //       the creation date is set to the validity start time.
00477 //
00478 //   2.  For replacement data i.e. data that does overlay existing data,
00479 //       the creation date is set to be one minute greater than the Creation
00480 //       Date on the current best data.
00481 //
00482 // This scheme ensures that new data will overlay existing data at the 
00483 // start of its validity but will be itself overlaid by data that has 
00484 // a later start time (assuming validity record start times are more 
00485 // than a few minutes apart)
00486 
00487 
00488   //  Create a context that corresponds to the start time of the validity
00489   //  range.  Note that it is O.K. to use SimFlag and Detector masks 
00490   //  even though this could make the context ambiguous because the 
00491   //  context is only to be used to query the database and the SimFlag and 
00492   //  Detector values will be ORed against existing data so will match
00493   //  all possible data that this validity range could overlay which is
00494   //  just what we want.
00495 
00496   const VldRange& vr(vrec.GetVldRange());
00497   VldContext vc((Detector::Detector_t) vr.GetDetectorMask(),
00498                   (SimFlag::SimFlag_t) vr.GetSimMask(),
00499                                        vr.GetTimeStart());
00500 
00501   DbiConnectionMaintainer cm(fCascader);  //Stack object to hold connections
00502 
00503   // Build a complete set of effective validity records from the 
00504   // selected database.
00505   DbiValidityRecBuilder builder(fDBProxy,vc,vrec.GetTask(),dbNo);
00506 
00507   // Pick up the validity record for the current aggregate.
00508   const DbiValidityRec& vrecOvlay(builder.GetValidityRecFromAggNo(vrec.GetAggregateNo()));
00509 
00510   // If its a gap i.e. nothing is overlayed, return the start time, otherwise
00511   // return its Creation Date plus one minute.
00512   VldTimeStamp ovlayTS(vr.GetTimeStart());
00513   if ( ! vrecOvlay.IsGap() ) {
00514     time_t overlaySecs = vrecOvlay.GetCreationDate().GetSec();
00515     ovlayTS = VldTimeStamp(overlaySecs + 60,0);
00516   }
00517 
00518   MSG("Dbi",Msg::kDebug) << "Looking for overlay creation date for: " 
00519                    << vrec << "found it would overlap: "
00520                    << vrecOvlay << " so overlay creation date set to "
00521                    << ovlayTS.AsString("s") << endl;
00522   return ovlayTS;                                          
00523 
00524 }
00525 //.....................................................................
00526 
00527 Bool_t DbiTableProxy::RestoreFromL2Cache(const DbiValidityRecBuilder& builder) {
00528 //
00529 //
00530 //  Purpose: Restore results from named level 2 disk cache into memory cache. 
00531 //  Returns true if anything restored
00532 
00533 //  Specification:-
00534 //  =============
00535 //
00536 //  o Restore to cache but only if enabled and exists.
00537 
00538   const string name(builder.GetL2CacheName());
00539   MSG("Dbi",Msg::kDebug) << "Request to restore query result  " << name 
00540                          << endl;
00541   if ( ! this->CanReadL2Cache() ) return kFALSE;
00542   string cacheFileName;
00543   if (  name != "" 
00544    ) cacheFileName =  this->GetTableName() + "_" 
00545                     + this->GetRowName() + "_" 
00546                     +  name + ".dbi_cache";
00547   DbiBinaryFile bf(cacheFileName.c_str());
00548   if ( ! bf.IsOK() ) {
00549     MSG("Dbi",Msg::kDebug) << "Caching disabled or cannot open " 
00550                            << bf.GetFileName() << endl;
00551     return kFALSE;
00552   }
00553 
00554   static bool warnOnce = true;
00555   if ( warnOnce ) {
00556     MSG("Dbi",Msg::kWarning) << "\n\n\n"
00557      << " WARNING:  Reading from the Level 2 cache has been activated.\n"
00558      << " *******   This should only be used for development and never for production !!!\n\n\n";
00559     warnOnce = false;
00560   }
00561 
00562   MSG("Dbi",Msg::kInfo) << "Restoring query result from " << bf.GetFileName() << endl;
00563   DbiTimerManager::gTimerManager.RecMainQuery();
00564 
00565   DbiResult* result    = 0;
00566   unsigned numRowsRest = 0;
00567   unsigned numRowsIgn  = 0;
00568   UInt_t numNonAgg     = 0;
00569   bf >> numNonAgg;  
00570 
00571   while ( numNonAgg-- ) {
00572     if ( ! bf.IsOK() ) break;
00573     if ( ! result ) result = new DbiResultNonAgg;
00574     bf >> *result;
00575 
00576 //  The original query may have had a validity range truncated by
00577 //  the time window, so replace its DbiValidityRec with the one
00578 //  just obtained from the database.
00579     const DbiValidityRec& vrec = result->GetValidityRec();
00580     UInt_t seqNo = vrec.GetSeqNo();
00581     MSG("Dbi",Msg::kDebug) << "Fix up L2 cache DbiValidityRec, by replacing: " << vrec 
00582                            << "    with: " << builder.GetValidityRecFromSeqNo(seqNo) << endl;
00583 //  Sneaky end-run round const to fix-up DbiValidityRec.
00584     (const_cast<DbiValidityRec&>(vrec)) = builder.GetValidityRecFromSeqNo(seqNo);
00585 
00586 //  Adopt only if not already in memory cache.
00587     if ( ! fCache->Search(vrec) ) {
00588       numRowsRest += result->GetNumRows();
00589       fCache->Adopt(result);
00590       result = 0;
00591     }
00592     else numRowsIgn += result->GetNumRows();
00593   }
00594   MSG("Dbi",Msg::kInfo) << "   a total of " << numRowsRest << " were restored ("
00595                         << numRowsIgn << " ignored - already in memory)" << endl;
00596 
00597   delete result;
00598   result = 0;
00599 
00600   return numRowsRest > 0;
00601 
00602 }
00603 //.....................................................................
00604 
00605 Bool_t DbiTableProxy::SaveToL2Cache(const string& name, DbiResult& res) {
00606 //
00607 //
00608 //  Purpose: Save result to named level 2 cache. Returns true if saved.
00609 
00610 //  Specification:-
00611 //  =============
00612 //
00613 //  o Save to cache but only if enabled and suitable.
00614 
00615   MSG("Dbi",Msg::kDebug) << "Request to save query result as " << name 
00616                          << " data from DB? " << res.ResultsFromDb()
00617                          << " can be saved? " << res.CanSave() << endl;
00618   if ( ! this->CanWriteL2Cache() || ! res.ResultsFromDb() || ! res.CanSave() ) return kFALSE;
00619 
00620   string cacheFileName;
00621   if (  name != "" 
00622    ) cacheFileName =  this->GetTableName() + "_" 
00623                     + this->GetRowName() + "_" 
00624                     +  name + ".dbi_cache";
00625   DbiBinaryFile bf(cacheFileName.c_str(),kFALSE);
00626   if ( bf.IsOK() ) {
00627     MSG("Dbi",Msg::kInfo) << "Saving query result (" << res.GetNumRows()
00628                           << " rows) to " << bf.GetFileName() << endl;
00629      DbiTimerManager::gTimerManager.RecMainQuery();
00630 
00631     // if writing a DbiResultNonAgg, add leading count of 1. (if writing
00632     // a DbiResultAgg it will writes its one leading count.
00633     if ( dynamic_cast<DbiResultNonAgg*>(&res) ) {
00634       UInt_t numNonAgg = 1;
00635       bf << numNonAgg;
00636     }
00637     bf << res;
00638     return kTRUE;
00639   }
00640   MSG("Dbi",Msg::kDebug) << "Caching disabled or cannot open " 
00641                          << bf.GetFileName() << endl;
00642   return kFALSE;
00643 
00644 }
00645 //.....................................................................
00646 
00647 void DbiTableProxy::SetSqlCondition(const string& sql) {
00648 //
00649 //
00650 //  Purpose:  Apply Sql condition to its DbiDBProxy.
00651 //
00652 //  Arguments: 
00653 //   sql           in    SQL condition string (excluding where).
00654 //
00655 //  Return:  n/a  
00656 //
00657 //  Contact:   N. West
00658 //
00659 //  Specification:-
00660 //  =============
00661 //
00662 //  o Apply Sql condition to its DbiDBProxy.
00663 
00664 //  Program Notes:-
00665 //  =============
00666 
00667 //  None.
00668 
00669   fDBProxy.SetSqlCondition(sql);
00670 
00671 }

Generated on Mon Feb 15 11:06:35 2010 for loon by  doxygen 1.3.9.1