TDbiTableProxy.cxx

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

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1