TDbiResultSet.cxx

Go to the documentation of this file.
00001 // $Id: TDbiResultSet.cxx,v 1.2 2011/06/08 09:49:18 finch Exp $
00002 
00003 #include <sstream>
00004 
00005 #include "TDbiBinaryFile.hxx"
00006 #include "TDbiResultKey.hxx"
00007 #include "TDbiResultSet.hxx"
00008 #include "TDbiInRowStream.hxx"
00009 #include "TDbiServices.hxx"
00010 #include "TDbiTableRow.hxx"
00011 #include <TSK_DBI_Log.hxx>
00012 #include <MsgFormat.h>
00013 using std::endl;
00014 
00015 ClassImp(TDbiResultSet)
00016 
00017 //   Definition of static data members
00018 //   *********************************
00019 
00020  Int_t TDbiResultSet::fgLastID(0);
00021 
00022 //  Global functions
00023 //  *****************
00024 
00025 //.....................................................................
00026 
00027 TDbiBinaryFile& operator<<(TDbiBinaryFile& bf, const TDbiResultSet& res) {
00028 
00029 // Writing is a const operation, but uses a non-const method, so cast away const.
00030 
00031   TDbiResultSet& res_tmp = const_cast< TDbiResultSet&>(res);
00032   res_tmp.Streamer(bf);
00033   return bf;
00034 }
00035 
00036 //.....................................................................
00037 
00038 TDbiBinaryFile& operator>>(TDbiBinaryFile& bf, TDbiResultSet& res) {
00039 
00040   res.Streamer(bf);
00041   return bf;
00042 }
00043 
00044 // Definition of member functions (alphabetical order)
00045 // ***************************************************
00046 
00047 
00048 //.....................................................................
00049 
00050 TDbiResultSet::TDbiResultSet(TDbiInRowStream* resultSet,
00051                      const TDbiValidityRec* vrec,
00052                      const string& sqlQualifiers) :
00053 fID(++fgLastID),
00054 fCanReuse(kTRUE),
00055 fEffVRec(0),
00056 fKey(0),
00057 fResultsFromDb(kFALSE),
00058 fNumClients(0),
00059 fTableName("Unknown"),
00060 fSqlQualifiers(sqlQualifiers)
00061 {
00062 //
00063 //
00064 //  Purpose:  Default constructor
00065 //
00066 //  Arguments:
00067 //      resultSet     in   Pointer TDbiInRowStream from query. May be null.
00068 //      vrec          in   Pointer to validity record from query.
00069 //                         May be null
00070 //      sqlQualifier  in   Extended Context sql qualifiers
00071 //
00072 //  Return:    n/a
00073 //
00074 //  Contact:   N. West
00075 //
00076 //  Specification:-
00077 //  =============
00078 //
00079 //  o Create Result from TDbiInRowStream generated by query.
00080 
00081 
00082 //  Program Notes:-
00083 //  =============
00084 
00085 // None.
00086 
00087 
00088   SK_DBI_Trace( "Creating TDbiResultSet" << "  ");
00089 
00090   if ( vrec ) fEffVRec = *vrec;
00091   if ( resultSet ) fTableName = resultSet->TableNameTc();
00092 
00093 }
00094 
00095 //.....................................................................
00096 
00097 TDbiResultSet::~TDbiResultSet() {
00098 //
00099 //
00100 //  Purpose: Destructor
00101 //
00102 //  Arguments:
00103 //    None.
00104 //
00105 //  Return:    n/a
00106 //
00107 //  Contact:   N. West
00108 //
00109 //  Specification:-
00110 //  =============
00111 //
00112 //  o  Destroy Result.
00113 
00114 
00115 //  Program Notes:-
00116 //  =============
00117 
00118 //  None.
00119 
00120 
00121   SK_DBI_Trace( "Destroying TDbiResultSet." << "  ");
00122 
00123   if ( fNumClients ) SK_DBI_Warn(  "Warning: Destroying TDbiResultSet with " << fNumClients
00124     << " clients " << "  ");
00125 
00126   delete fKey;
00127   fKey = 0;
00128   fIndexKeys.clear();
00129 
00130 }
00131 //.....................................................................
00132 
00133 void TDbiResultSet::BuildLookUpTable() const {
00134 //
00135 //
00136 //  Purpose:  Build look-up Natural Index -> TableRow.
00137 //
00138 //  Contact:   N. West
00139 //
00140 //  Program Notes:-
00141 //  =============
00142 //
00143 //  This member function assumes that the sub-class can support
00144 //  the GetTableRow(...) and GetNumRows methods so take care if
00145 //  called in the sub-class ctor.
00146 
00147 //  Extended Context serach can produce duplicates.
00148   Bool_t duplicatesOK = this->IsExtendedContext();
00149 
00150   SK_DBI_Verbose( "Building look-uptable. Allow duplicates: "
00151                             << duplicatesOK << "  ");
00152 
00153   for ( Int_t rowNo = this->GetNumRows()-1;
00154         rowNo >= 0;
00155         --rowNo ) {
00156     const TDbiTableRow* row  = this->GetTableRow(rowNo);
00157     UInt_t index            = row->GetIndex(rowNo);
00158 //  Ensure we use this class's GetTableRowByIndex, the method is
00159 //  virtual but if the subclass has called this method then it must
00160 //  be the right one to use. [Actually TDbiResultSetAgg overrides
00161 //  GetTableRowByIndex, but only to make building lazy].
00162     const TDbiTableRow* row2 = this->TDbiResultSet::GetTableRowByIndex(index);
00163 
00164     SK_DBI_Verbose(  "Look-up. Row no " << rowNo
00165           << " index " << index
00166           << " row,row2 " << (void*) row << "," << (void*) row2 << "  ");
00167 
00168     if ( row2 != 0 && row2 != row && ! duplicatesOK ) {
00169       std::ostringstream msg;
00170       msg << "Duplicated row natural index: " << index
00171           << " Found at row " <<  rowNo
00172           << " of table " <<  this->TableName()
00173           << ":-\n     index of agg " <<  row->GetAggregateNo();
00174       if ( row->GetOwner() ) msg << "(SEQNO " << row->GetOwner()->GetValidityRec(row).GetSeqNo() << ")";
00175       msg << " matches agg " <<  row2->GetAggregateNo();
00176       if ( row2->GetOwner() ) msg << "(SEQNO " << row2->GetOwner()->GetValidityRec(row2).GetSeqNo() << ")";
00177          SK_DBI_Severe( msg.str() << "  ");
00178    }
00179 
00180     else  fIndexKeys[index] = row;
00181   }
00182 
00183 }
00184 
00185 //.....................................................................
00186 
00187 Bool_t TDbiResultSet::CanDelete(const TDbiResultSet* res) {
00188 //
00189 //
00190 //  Purpose:  See if suitable for deleting.
00191 //
00192 //  Arguments:
00193 //    res          in    A TDbiResultSet that is currently used.
00194 //                       Optional: default = 0.
00195 
00196 //  If the query would be satisfied apart from the date, then
00197 //  assume we have moved out of the validity window, never
00198 //  to return!
00199 
00200   if (     res
00201         && this->CanReuse()
00202         && this->GetValidityRec().HasExpired(res->GetValidityRec())
00203      )  this->SetCanReuse(kFALSE);
00204 
00205   return ! this->GetNumClients() && ! this->CanReuse();
00206 }
00207 
00208 //.....................................................................
00209 
00210 void TDbiResultSet::CaptureExceptionLog(UInt_t startFrom) {
00211 //
00212 //
00213 //  Purpose: Capture Exception Log from latest entries in Global Exception Log.
00214 
00215   fExceptionLog.Clear();
00216   TDbiExceptionLog::GetGELog().Copy(fExceptionLog,startFrom);
00217 
00218 }
00219 
00220 //.....................................................................
00221 
00222 void TDbiResultSet::GenerateKey() {
00223 //
00224 //
00225 //  Purpose: Create key if set not empty and not already done.
00226 
00227   if ( fKey || this->GetNumRows() == 0) return;
00228   fKey = this->CreateKey();
00229 
00230 }
00231 
00232 //.....................................................................
00233 
00234 const TDbiResultKey* TDbiResultSet::GetKey() const {
00235 
00236 //  Purpose:  Get the associated TDbiResultKey, or an empty one if none exists.
00237 
00238   return fKey ? fKey : TDbiResultKey::GetEmptyKey();
00239 
00240 }
00241 
00242 //.....................................................................
00243 
00244 const TDbiTableRow* TDbiResultSet::GetTableRowByIndex(UInt_t index) const {
00245 //
00246 //
00247 //  Purpose:  Return row corresponding to Natural Index (or 0 if none)
00248 //
00249 //  Contact:   N. West
00250 //
00251 
00252 // Use Find rather than operator[] to avoid creating entry
00253 // if index missing
00254   IndexToRow_t::const_iterator idx = fIndexKeys.find(index);
00255   return ( idx == fIndexKeys.end() ) ? 0 : (*idx).second;
00256 
00257 }
00258 
00259 //.....................................................................
00260 
00261 Bool_t TDbiResultSet::Satisfies(const TVldContext& vc,
00262                             const TDbi::Task& task) {
00263 //
00264 //
00265 //  Purpose:  Check to see if this Result satisfies specific context query.
00266 //
00267 //  Arguments:
00268 //    vc           in    Context of query
00269 //    task         in    Task of query
00270 //
00271 //  Return:    kTRUE if can satisfy query.
00272 //
00273 //  Contact:   N. West
00274 //
00275 //  Program Notes:-
00276 //  =============
00277 
00278 //  If it cannot satisfy the query in a way that suggests
00279 //  that its unlikely that it will satisfy future queries
00280 //  then mark as cannot reuse so that it becomes eligible
00281 //  for purging.
00282 
00283 // Extended Context queries cannot satisfy specific context queries.
00284 
00285   Bool_t isExtendedContext = this->IsExtendedContext();
00286   Bool_t canReuse          = this->CanReuse();
00287   Bool_t isCompatible      = this->GetValidityRec().IsCompatible(vc,task);
00288   Bool_t hasExpired        = this->GetValidityRec().HasExpired(vc,task);
00289   UInt_t numClients        = this->GetNumClients();
00290   SK_DBI_Debug(  "    Checking result with TDbiValidityRec:- \n      " << this->GetValidityRec()
00291     << "  With extended context: " << isExtendedContext
00292     << " CanReuse: " << canReuse
00293     << " Is Compatible: " << isCompatible
00294     << " HasExpired: " <<  hasExpired
00295     << " number of clients: " << numClients
00296     << "  ");
00297 
00298   if ( isExtendedContext ) return kFALSE;
00299 
00300   if ( canReuse && isCompatible )  return kTRUE;
00301 
00302 //  If the query would be satisfied apart from the date, then
00303 //  assume we have moved out of the validity window, never
00304 //  to return!
00305 
00306   if ( canReuse && hasExpired && numClients == 0 )  {
00307     SK_DBI_Debug( "    Marking result as not reusable" << "  ");
00308    this-> SetCanReuse(kFALSE);
00309   }
00310 
00311   return kFALSE;
00312 
00313 }
00314 //.....................................................................
00315 
00316 void TDbiResultSet::Streamer(TDbiBinaryFile& file) {
00317 //
00318 //
00319 //  Purpose:  I/O to binary file
00320 //
00321 //  Program Notes:-
00322 //  =============
00323 
00324 //  Don't store fIndexKeys; it will be rebuilt on input by the subclass.
00325 
00326   if ( file.IsReading() ) {
00327     SK_DBI_Debug( "    Restoring TDbiResultSet ..." << "  ");
00328     file >> fCanReuse;
00329     fEffVRec.Streamer(file);
00330     SK_DBI_Verbose( "    Restored " << fEffVRec << "  ");
00331     fResultsFromDb = kFALSE;
00332     fNumClients    = 0;
00333     file >> fTableName;
00334     SK_DBI_Verbose( "    Restored string " << fTableName << "  ");
00335   }
00336   else if ( file.IsWriting() ) {
00337     SK_DBI_Debug( "    Saving TDbiResultSet ..." << "  ");
00338     file << fCanReuse;
00339     SK_DBI_Verbose( "    Saving " << fEffVRec << "  ");
00340     fEffVRec.Streamer(file);
00341     SK_DBI_Verbose( "    Saving string " << fTableName << "  ");
00342     file << fTableName;
00343   }
00344 }
00345 
00346 /*    Template for New Member Function
00347 
00348 //.....................................................................
00349 
00350 TDbiResultSet:: {
00351 //
00352 //
00353 //  Purpose:
00354 //
00355 //  Arguments:
00356 //    xxxxxxxxx    in    yyyyyy
00357 //
00358 //  Return:
00359 //
00360 //  Contact:   N. West
00361 //
00362 //  Specification:-
00363 //  =============
00364 //
00365 //  o
00366 
00367 //  Program Notes:-
00368 //  =============
00369 
00370 //  None.
00371 
00372 
00373 }
00374 
00375 */
00376 
00377 

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1