// $Id: IDbiResultSetNonAgg.cxx,v 1.2 2011/06/08 09:49:18 finch Exp $ #include "IDbiBinaryFile.hxx" #include "IDbiResultKey.hxx" #include "IDbiResultSetNonAgg.hxx" #include "IDbiInRowStream.hxx" #include "IDbiTableRow.hxx" #include "IDbiTimerManager.hxx" #include #include using std::endl; ClassImp(COMET::IDbiResultSetNonAgg) // Definition of static data members // ********************************* // Definition of all member functions (static or otherwise) // ******************************************************* // // - ordered: ctors, dtor, operators then in alphabetical order. // //..................................................................... ///\verbatim /// Purpose: Default constructor /// /// Arguments: /// resultSet in/out Pointer COMET::IDbiInRowStream from query. May be null. /// tableRow in Pointer to a sample tableRow object. /// May be null. /// vrec in Pointer to validity record from query. /// May be null /// dropSeqNo in If = kTRUE, drop SeqNo if it is the first col. /// sqlQualifier in Extended Context sql qualifiers /// /// Return: n/a /// /// Contact: N. West /// /// Specification:- /// ============= /// /// o Create Result from COMET::IDbiInRowStream generated by query. If first /// column is named SeqNo then strip it off before filling each /// COMET::IDbiTableRow and quit as soon as the SeqNo changes. /// /// /// Program Notes:- /// ============= /// /// o tableRow is just used to create new subclass COMET::IDbiTableRow objects. /// /// o The special treatment for tables that start with SeqNo allow /// a single COMET::IDbiInRowStream to fill multiple COMET::IDbiResultSet objects but does /// require that the result set is ordered by SeqNo. /// /// The look-up table is not built by default, its construction is /// triggered by use (GetTableRowByIndex). For COMET::IDbiResultSetNonAgg /// that are part of a COMET::IDbiResultSetAgg there is no need to build the /// table. ///\endverbatim COMET::IDbiResultSetNonAgg::IDbiResultSetNonAgg(COMET::IDbiInRowStream* resultSet, const COMET::IDbiTableRow* tableRow, const COMET::IDbiValidityRec* vrec, Bool_t dropSeqNo, const string& sqlQualifiers) : COMET::IDbiResultSet(resultSet,vrec,sqlQualifiers), fBuffer(0) { this->DebugCtor(); if ( ! resultSet || resultSet->IsExhausted() || ! tableRow ) return; if ( vrec ) COMET::IDbiTimerManager::gTimerManager.RecFillAgg(vrec->GetAggregateNo()); //Move to first row if result set not yet started. COMET::IDbiInRowStream& rs = *resultSet; if ( rs.IsBeforeFirst() ) rs.FetchRow(); if ( rs.IsExhausted() ) return; //Check and load sequence number if necessary. Int_t seqNo = 0; if ( dropSeqNo && rs.CurColName() == "SEQNO" ) { rs >> seqNo; rs.DecrementCurCol(); } // Main (non-VLD) tables have a ROW_COUNTER (which has to be ignored when reading). bool hasRowCounter = ! rs.IsVLDTable(); // Create and fill table row object and move result set onto next row. while ( ! rs.IsExhausted() ) { // If stripping off sequence numbers check the next and quit, // having restored the last, if it changes. if ( seqNo != 0 ) { Int_t nextSeqNo; rs >> nextSeqNo; if ( nextSeqNo != seqNo ) { rs.DecrementCurCol(); break; } } // Strip off ROW_COUNTER if present. if ( hasRowCounter ) rs.IncrementCurCol(); COMET::IDbiTableRow* row = tableRow->CreateTableRow(); if ( vrec) COMET::IDbiTimerManager::gTimerManager.StartSubWatch(3); row->SetOwner(this); row->Fill(rs,vrec); if ( vrec) COMET::IDbiTimerManager::gTimerManager.StartSubWatch(2); fRows.push_back(row); rs.FetchRow(); if ( vrec) COMET::IDbiTimerManager::gTimerManager.StartSubWatch(1); } //Flag that data was read from Database. this->SetResultsFromDb(); if ( seqNo == 0 ) COMETInfo( "Created unaggregated VLD result set no. of rows: " << this->GetNumRows() << " "); else COMETInfo( "Created unaggregated result set for SeqNo: " << seqNo << " no. of rows: " << this->GetNumRows() << " "); } //..................................................................... // ///\verbatim /// Purpose: Destructor /// /// Arguments: /// None. /// /// Return: n/a /// /// Contact: N. West /// /// Specification:- /// ============= /// /// o Destroy ResultNonAgg and all its owned COMET::IDbiTableRow subclass /// objects. /// /// /// Program Notes:- /// ============= /// /// If fRows restored from BinaryFile then it doesn't own its /// COMET::TDbiTableRows. ///\endverbatim COMET::IDbiResultSetNonAgg::~IDbiResultSetNonAgg() { COMETTrace( "Destroying COMET::IDbiResultSetNonAgg." << " "); if ( ! fBuffer ) for ( vector::iterator itr = fRows.begin(); itr != fRows.end(); ++itr) delete *itr; else { delete [] fBuffer; fBuffer = 0; } } //..................................................................... /// Purpose: Create a key that corresponds to this result. COMET::IDbiResultKey* COMET::IDbiResultSetNonAgg::CreateKey() const { // // string rowName("empty_table"); const COMET::IDbiTableRow* row = this->GetTableRow(0); if ( row ) rowName = row->GetName(); const COMET::IDbiValidityRec& vrec = this->GetValidityRec(); return new COMET::IDbiResultKey(this->TableName(), rowName, vrec.GetSeqNo(), vrec.GetCreationDate() ); } //..................................................................... void COMET::IDbiResultSetNonAgg::DebugCtor() const { COMETTrace( "Creating COMET::IDbiResultSetNonAgg" << (void*) this << " "); static const COMET::IDbiResultSetNonAgg* that = 0; if ( this == that ) { cout << "debug " << (void*) this << endl; } } //..................................................................... ///\verbatim /// /// Purpose: Return TableRow from last query. /// /// Arguments: /// rowNum in Required row number (0..NumRows-1) /// /// Return: TableRow ptr, or =0 if no row. /// /// Contact: N. West /// /// Specification:- /// ============= /// /// o Return TableRow from last query, or =0 if no row. ///\endverbatim const COMET::IDbiTableRow* COMET::IDbiResultSetNonAgg::GetTableRow(UInt_t rowNum) const { // Program Notes:- // ============= // None. if ( rowNum >= fRows.size() ) return 0; return fRows[rowNum]; } //..................................................................... ///\verbatim /// /// Purpose: Return TableRow with supplied index, or =0 if no row. /// /// Arguments: /// index in Required index. /// /// Return: TableRow with required index, or =0 if no row. /// /// Contact: N. West /// /// Specification:- /// ============= /// /// o If look-up table not yet built, build it. /// /// o Return TableRow with supplied index, or =0 if no row. ///\endverbatim const COMET::IDbiTableRow* COMET::IDbiResultSetNonAgg::GetTableRowByIndex(UInt_t index) const { if ( ! this->LookUpBuilt() ) this->BuildLookUpTable(); // The real look-up still takes place in the base class. return this->COMET::IDbiResultSet::GetTableRowByIndex(index); } //..................................................................... // ///\verbatim /// Purpose: Return true if owns row. /// /// /// Program Notes:- /// ============= /// /// Only COMET::TDbiResultSetNonAggs own rows; the base class COMET::IDbiResultSet supplies /// the default method that returns false. ///\endverbatim Bool_t COMET::IDbiResultSetNonAgg::Owns(const COMET::IDbiTableRow* row ) const { vector::const_iterator itr = fRows.begin(); vector::const_iterator itrEnd = fRows.end(); for (; itr != itrEnd; ++itr) if ( *itr == row ) return kTRUE; return kFALSE; } //..................................................................... /// Purpose: Check to see if this Result matches the supplied COMET::IDbiValidityRec. Bool_t COMET::IDbiResultSetNonAgg::Satisfies(const COMET::IDbiValidityRec& vrec, const string& sqlQualifiers) { // // COMETDebug( "Trying to satisfy: Vrec " << vrec << " SQL: " << sqlQualifiers << "\n with CanReuse: " << this->CanReuse() << " vrec: " << this->GetValidityRec() << " sqlQualifiers: " << this->GetSqlQualifiers() << " "); if ( this->CanReuse() ) { const COMET::IDbiValidityRec& this_vrec = this->GetValidityRec(); if ( sqlQualifiers == this->GetSqlQualifiers() && vrec.GetSeqNo() == this_vrec.GetSeqNo() && vrec.GetCreationDate() == this_vrec.GetCreationDate() ) return kTRUE; } return kFALSE; } //..................................................................... ///\verbatim /// /// Purpose: I/O to binary file /// /// Program Notes:- /// ============= /// Do I/O for base class COMET::IDbiResultSet first. Rebuild fIndexKeys on input. ///\endverbatim void COMET::IDbiResultSetNonAgg::Streamer(COMET::IDbiBinaryFile& file) { if ( file.IsReading() ) { this->COMET::IDbiResultSet::Streamer(file); COMETDebug( " Restoring COMET::IDbiResultSetNonAgg ..." << " "); file >> fRows; // Take ownership of the memory holding the array. fBuffer = file.ReleaseArrayBuffer(); this->BuildLookUpTable(); COMETDebug( " Restored COMET::IDbiResultSetNonAgg. Size:" << fRows.size() << " rows" << " "); } else if ( file.IsWriting() ) { this->COMET::IDbiResultSet::Streamer(file); COMETDebug( " Saving COMET::IDbiResultSetNonAgg. Size:" << fRows.size() << " rows" << " "); file << fRows; } } /* Template for New Member Function //..................................................................... COMET::IDbiResultSetNonAgg:: { // // // Purpose: // // Arguments: // xxxxxxxxx in yyyyyy // // Return: // // Contact: N. West // // Specification:- // ============= // // o // Program Notes:- // ============= // None. } */