TDbiSqlValPacket Class Reference

Concept The SQL statements to generate a Validity Packet i.e a single TDbiValidityRec row and its associated main table data rows. More...

#include <TDbiSqlValPacket.hxx>

Collaboration diagram for TDbiSqlValPacket:
Collaboration graph
[legend]

List of all members.

Public Types

enum  ECompResult { kIdentical, kUpdate, kOutOfDate, kConflict }
typedef enum
TDbiSqlValPacket::ECompResult 
CompResult_t

Public Member Functions

 TDbiSqlValPacket ()
 TDbiSqlValPacket (std::ifstream &is)
 TDbiSqlValPacket (const TDbiValidityRec &vrec)
virtual ~TDbiSqlValPacket ()
Bool_t CanBeStored () const
CompResult_t Compare (const TDbiSqlValPacket &that, Bool_t log=kFALSE, const Char_t *thisName="this", const Char_t *thatName="that") const
Bool_t CreateTable (UInt_t dbNo) const
UInt_t GetNumErrors () const
UInt_t GetNumSqlStmts () const
UInt_t GetSeqNo () const
TVldTimeStamp GetCreationDate () const
string GetStmt (UInt_t stmtNo) const
std::vector< string > GetStmtValues (UInt_t stmtNo) const
const string & GetTableName () const
Bool_t IsEqual (const TDbiSqlValPacket &that, Bool_t log=kFALSE, const Char_t *thisName="this", const Char_t *thatName="that") const
Bool_t Fill (std::ifstream &is)
Bool_t Store (UInt_t dbNo, Bool_t replace=kFALSE) const
Bool_t Write (std::ofstream &ios, Bool_t addMetadata=kFALSE) const
void Recreate (const string &tableName, const TVldRange &vr, Int_t aggNo, TDbi::Task task=0, TVldTimeStamp creationDate=TVldTimeStamp())
 Purpose: Recreate and define first row (VLD - the validity record).
Bool_t AddDataRow (const TDbiTableProxy &tblProxy, const TDbiValidityRec *vrec, const TDbiTableRow &row)
 Add data row tblProxy vrec row to this object.
void Clear ()
void SetEpoch (UInt_t epoch)
 Set EPOCH.
void SetCreationDate (TVldTimeStamp ts)
 Purpose: Set creation date.
void SetSeqNo (UInt_t seqno)
 Set sequence number.
void Reset ()
 Purpose: Clear out back to unfilled status except for fNumErrors.
virtual void Print (Option_t *option="") const
 Print the current state.

Private Member Functions

void AddRow (const string &row)
 add row to sql statements
Bool_t AddRow (const TDbiTableProxy &tblProxy, const TDbiValidityRec *vrec, const TDbiTableRow &row)
void Report (const char *msg, UInt_t line_num, const string &line)
void SetMetaData () const
 Purpose: Set up meta-data as SQL table creation statements.
void SetSeqNoOnRow (string &row, const string &seqno)
 Purpose: Set Sequence number on supplied row.
 TDbiSqlValPacket (const TDbiSqlValPacket &)

Private Attributes

UInt_t fNumErrors
 Number of error encountered while filling.
UInt_t fSeqNo
 Sequence number or 0 if not filled.
string fSqlMySqlMetaMain
 MySQL SQL to create main table. May be empty until needed.
string fSqlMySqlMetaVld
 As fSqlMySqlMetaMain but for aux. table.
std::list< string > fSqlStmts
 Set of SQL statements to generate packet.
UInt_t fNumStmts
 Number of statements.
string fTableName
 Table name or null if not filled.
TVldTimeStamp fCreationDate
 Creation date, or object creation date if unfilled.

Detailed Description

Concept The SQL statements to generate a Validity Packet i.e a single TDbiValidityRec row and its associated main table data rows.

Purpose Used as part of database maintenance as the unit of transfer between databases. Contact: A.Finch@lancaster.ac.uk

Definition at line 44 of file TDbiSqlValPacket.hxx.


Member Typedef Documentation


Member Enumeration Documentation

Enumerator:
kIdentical 
kUpdate 
kOutOfDate 
kConflict 

Definition at line 51 of file TDbiSqlValPacket.hxx.

00051                            {
00052     kIdentical,
00053     kUpdate,
00054     kOutOfDate,
00055     kConflict
00056   } CompResult_t;


Constructor & Destructor Documentation

TDbiSqlValPacket::TDbiSqlValPacket (  ) 
TDbiSqlValPacket::TDbiSqlValPacket ( std::ifstream &  is  ) 
TDbiSqlValPacket::TDbiSqlValPacket ( const TDbiValidityRec vrec  ) 
TDbiSqlValPacket::~TDbiSqlValPacket (  )  [virtual]

Definition at line 162 of file TDbiSqlValPacket.cxx.

References Clear(), and SK_DBI_Trace.

00162                                     {
00163 //
00164 //
00165 //  Purpose: Destructor
00166 //
00167 //  Arguments:
00168 //    None.
00169 //
00170 //  Return:    n/a
00171 //
00172 //  Contact:   N. West
00173 //
00174 //  Specification:-
00175 //  =============
00176 //
00177 //  o  Destroy TDbiSqlValPacket.
00178 
00179 
00180 //  Program Notes:-
00181 //  =============
00182 
00183 //  None.
00184 
00185 
00186   SK_DBI_Trace( "Destroying TDbiSqlValPacket" << "  ");
00187 
00188   Clear();
00189 
00190 }

Here is the call graph for this function:

TDbiSqlValPacket::TDbiSqlValPacket ( const TDbiSqlValPacket  )  [private]

Member Function Documentation

Bool_t TDbiSqlValPacket::AddDataRow ( const TDbiTableProxy tblProxy,
const TDbiValidityRec vrec,
const TDbiTableRow row 
)

Add data row tblProxy vrec row to this object.

Definition at line 194 of file TDbiSqlValPacket.cxx.

References AddRow(), fNumErrors, GetNumSqlStmts(), and SK_DBI_Severe.

Referenced by TDbiLogEntry::Write().

00196                                                            {
00197 //
00198 //
00199 //  Purpose: Add data row.
00200 //
00201 
00202   if ( this->GetNumSqlStmts() == 0 ) {
00203        SK_DBI_Severe(  "Cannot add data row - packet does not have a VLD row"  << "  ");
00204     ++fNumErrors;
00205     return kFALSE;
00206   }
00207 
00208   return this->AddRow(tblProxy,vrec,row);
00209 
00210 }

Here is the call graph for this function:

Here is the caller graph for this function:

Bool_t TDbiSqlValPacket::AddRow ( const TDbiTableProxy tblProxy,
const TDbiValidityRec vrec,
const TDbiTableRow row 
) [private]

Definition at line 234 of file TDbiSqlValPacket.cxx.

References AddRow(), fNumErrors, fNumStmts, TDbiOutRowStream::GetCSV(), TDbiTableProxy::GetMetaData(), TDbiTableProxy::GetMetaValid(), GetNumSqlStmts(), TDbiTableProxy::GetTableName(), TDbiOutRowStream::HasGoodData(), TDbiOutRowStream::IsComplete(), SK_DBI_Severe, and TDbiTableRow::Store().

00236                                                        {
00237 //
00238 //
00239 //  Purpose: Add row.
00240 //
00241 
00242 
00243   bool isVld = this->GetNumSqlStmts() == 0;
00244   const TDbiTableMetaData& meta = isVld ? tblProxy.GetMetaValid() : tblProxy.GetMetaData();
00245   TDbiOutRowStream outRow(&meta);
00246 
00247 // Store dummy SEQNO and ROW_COUNTER for data rows.
00248   if ( ! isVld ) {
00249     outRow << 0;          // dummy SEQNO
00250     outRow <<  fNumStmts; // ROW_COUNTER
00251   }
00252   row.Store(outRow,vrec);
00253   if ( ! outRow.HasGoodData() ) {
00254     if ( ! outRow.IsComplete() ) {
00255          SK_DBI_Severe(  "Incomplete data supplied for row " << this->GetNumSqlStmts()-1
00256         << " of table "
00257         << tblProxy.GetTableName() << "  ");
00258     }
00259     else {
00260          SK_DBI_Severe(  "Complete but bad data supplied for table "
00261         << tblProxy.GetTableName() << "  ");
00262     }
00263     ++fNumErrors;
00264     return kFALSE;
00265   }
00266   this->AddRow(outRow.GetCSV());
00267   return kTRUE;
00268 }

Here is the call graph for this function:

void TDbiSqlValPacket::AddRow ( const string &  row  )  [private]

add row to sql statements

Definition at line 214 of file TDbiSqlValPacket.cxx.

References fNumStmts, fSqlStmts, GetNumSqlStmts(), GetSeqNo(), GetTableName(), and SetSeqNoOnRow().

Referenced by AddDataRow(), AddRow(), and Recreate().

00214                                                {
00215 //
00216 //
00217 //  Purpose: Add row.
00218 //
00219 
00220   string sql("INSERT INTO ");
00221   sql += this->GetTableName();
00222   if ( this->GetNumSqlStmts() == 0 ) sql += "VLD";
00223   sql += " VALUES (" + row + ");";
00224   ostringstream seqno;
00225   seqno << this->GetSeqNo();
00226   this->SetSeqNoOnRow(sql,seqno.str());
00227   fSqlStmts.push_back(sql);
00228   ++fNumStmts;
00229 
00230 }

Here is the call graph for this function:

Here is the caller graph for this function:

Bool_t TDbiSqlValPacket::CanBeStored (  )  const [inline]

Definition at line 65 of file TDbiSqlValPacket.hxx.

References fNumErrors, fSeqNo, and GetNumSqlStmts().

Referenced by CreateTable(), Store(), and Write().

00065                                    {
00066              return (fSeqNo > 0 && fNumErrors == 0 && this->GetNumSqlStmts()> 0)
00067             ? kTRUE : kFALSE; };

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiSqlValPacket::Clear (  )  [inline]

Definition at line 102 of file TDbiSqlValPacket.hxx.

References fNumErrors, and Reset().

Referenced by Recreate(), and ~TDbiSqlValPacket().

00102 { this->Reset(); fNumErrors = 0; }

Here is the call graph for this function:

Here is the caller graph for this function:

TDbiSqlValPacket::CompResult_t TDbiSqlValPacket::Compare ( const TDbiSqlValPacket that,
Bool_t  log = kFALSE,
const Char_t *  thisName = "this",
const Char_t *  thatName = "that" 
) const
     Purpose:  Compare to another TDbiSqlValPacket
   
     Arguments:
       that         in    The other TDbiSqlValPacket to be compared.
       log          in    If true list differences to MSG("TDbi",kInfo)
       thisName     in    Optional name for this packet (default: this)
       thatName     in    Optional name for that packet (default: that)
   
     Return:    kIdentical   if identical (apart from InsertDate)
                kUpdate      "that" is more up to date
                kOutOfDate   "that" is out of date
                kConflict    records are incompatible
   
     Contact:   N. West
   

Definition at line 286 of file TDbiSqlValPacket.cxx.

References fSeqNo, fTableName, GetStmtValues(), IsEqual(), kConflict, kIdentical, kOutOfDate, kUpdate, and SK_DBI_Info.

00290                                                                {
00291 //
00292 //
00293 
00294   if ( this->IsEqual(that,log,thisName,thatName ) ) return kIdentical;
00295 
00296   if (    fSeqNo           != that.fSeqNo
00297        || fTableName       != that.fTableName     ) return kConflict;
00298 
00299   std::vector<std::string> valuesThis = this->GetStmtValues(0);
00300   std::vector<std::string> valuesThat = that.GetStmtValues(0);
00301 
00302   // Assume CreationDate is the 9th element (counting from 0).
00303   int comp = valuesThis[9].compare(valuesThat[9]);
00304 
00305   if ( comp < 0 ) {
00306     if ( log ) SK_DBI_Info(  "  Difference classified as Update" << "  ");;
00307     return kUpdate;
00308   }
00309   else if ( comp > 0 ) {
00310     if ( log ) SK_DBI_Info(  "  Difference classified as OutOfDate" << "  ");
00311     return kOutOfDate;
00312   }
00313   return kConflict;
00314 
00315 }

Here is the call graph for this function:

Bool_t TDbiSqlValPacket::CreateTable ( UInt_t  dbNo  )  const
   
     Purpose:  Create table in specified database.
   
     Arguments:
       dbNo         in    Number of database in the cascade.
   
     Return:    kTRUE if successfully created.
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o If SQL to create tables is available, use it to create
       the main and auxiliary tables and refresh the corresponding
       TDbiTableProxy.
   

Definition at line 337 of file TDbiSqlValPacket.cxx.

References CanBeStored(), fSqlMySqlMetaMain, fSqlMySqlMetaVld, fTableName, GetTableName(), TDbiDatabaseManager::Instance(), TDbiDatabaseManager::RefreshMetaData(), and SK_DBI_Warn.

00337                                                       {
00338 
00339 //  Program Notes:-
00340 //  =============
00341 
00342 //  None.
00343 
00344   if ( ! CanBeStored() ) return kFALSE;
00345 
00346   // Locate required TDbiStatement.
00347   auto_ptr<TDbiStatement> stmtDb(TDbiDatabaseManager::Instance()
00348                                .GetCascader()
00349                                .CreateStatement(dbNo));
00350   if ( ! stmtDb.get() ) {
00351     SK_DBI_Warn(  "Attempting to write to non-existant cascade entry " << dbNo
00352       << "  ");
00353     return kFALSE;
00354   }
00355   if ( fSqlMySqlMetaMain == "" || fSqlMySqlMetaVld  == "" ) {
00356     SK_DBI_Warn(  "No SQL available to create table " << fTableName
00357       << " in cascade entry: " << dbNo << "  ");
00358     return kFALSE;
00359   }
00360 
00361   stmtDb->ExecuteUpdate(fSqlMySqlMetaVld.c_str());
00362   if ( stmtDb->PrintExceptions() ) return kFALSE;
00363   stmtDb->ExecuteUpdate(fSqlMySqlMetaMain.c_str());
00364   if ( stmtDb->PrintExceptions() ) return kFALSE;
00365 
00366   TDbiDatabaseManager::Instance().RefreshMetaData(this->GetTableName());
00367 
00368   return kTRUE;
00369 
00370 }

Here is the call graph for this function:

Bool_t TDbiSqlValPacket::Fill ( std::ifstream &  is  ) 
TVldTimeStamp TDbiSqlValPacket::GetCreationDate (  )  const [inline]

Definition at line 76 of file TDbiSqlValPacket.hxx.

References fCreationDate.

00076 { return fCreationDate; }

UInt_t TDbiSqlValPacket::GetNumErrors (  )  const [inline]

Definition at line 73 of file TDbiSqlValPacket.hxx.

References fNumErrors.

00073 { return fNumErrors; }

UInt_t TDbiSqlValPacket::GetNumSqlStmts (  )  const [inline]

Definition at line 74 of file TDbiSqlValPacket.hxx.

References fNumStmts.

Referenced by AddDataRow(), AddRow(), CanBeStored(), GetStmtValues(), Print(), SetCreationDate(), SetEpoch(), and SetSeqNo().

00074 { return fNumStmts; }

Here is the caller graph for this function:

UInt_t TDbiSqlValPacket::GetSeqNo (  )  const [inline]

Definition at line 75 of file TDbiSqlValPacket.hxx.

References fSeqNo.

Referenced by AddRow(), and Write().

00075 { return fSeqNo; }

Here is the caller graph for this function:

string TDbiSqlValPacket::GetStmt ( UInt_t  stmtNo  )  const

Referenced by GetStmtValues().

Here is the caller graph for this function:

std::vector< std::string > TDbiSqlValPacket::GetStmtValues ( UInt_t  stmtNo  )  const
   
     Purpose:  Refill object from input string.
   
     Arguments:
         is    in/out    Input stream.
   
     Return:   kTRUE "is" object has been refilled.
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o Collect SQL statements, and possibly metadata (as SQL to
       create table) bracketed by >>>> ... <<<<< checking that
       the table name and SeqNos match.  Count and discard any data that
       looks bad. */

Bool_t TDbiSqlValPacket::Fill(std::ifstream& is) {

//  Program Notes:-
//  =============

//  None.




  enum { kLOOKING_FOR_HEADER,
         kLOOKING_FOR_TRAILER } state = kLOOKING_FOR_HEADER;


  enum { kMAXTABLENAMELEN        = TDbi::kMAXTABLENAMELEN,
         kHEADER_TRAILER_MAX_LEN = kMAXTABLENAMELEN + 20 };

  string nameHead;
  string nameTrail;
  UInt_t seqNoHead  = 0;
  UInt_t seqNoTrail = 0;

  string line;
  string msg;
  string sql;
  int lineNum = 0;

  this->Reset();
  //  Loop until EOF reading lines.

  while ( ! is.eof() ) {
    getline(is,line);
    ++lineNum;
    // Skip null lines.
    if (line.size() == 0 ) continue;

    // Look for header line
    if ( state == kLOOKING_FOR_HEADER ) {
      if ( line.substr(0,5) == ">>>>>" ) {
        if ( line.size() >= kHEADER_TRAILER_MAX_LEN ) {
          Report("Bad header",lineNum,line);
          continue;
	}

	// Look for optional metadata.
        if ( line.find("Metadata") != string::npos ) {
          getline(is,fSqlMySqlMetaVld);
          ++lineNum;
          getline(is,fSqlMySqlMetaMain);
          ++lineNum;
          getline(is,line);
          ++lineNum;
          if (   line.substr(0,5) != "<<<<<"
              || line.find("Metadata") == string::npos ) {
            Report("Bad metadata",lineNum,line);
            continue;
	  }
          getline(is,line);
          ++lineNum;
          if ( line.size() >= kHEADER_TRAILER_MAX_LEN ) {
            Report("Bad header",lineNum,line);
            continue;
	  }
	}

        //  Collect table name and SeqNo.
        istringstream istr(line.substr(5));
        istr.width(kMAXTABLENAMELEN);
	istr >> nameHead >> seqNoHead;
        if ( ! istr.eof() ) {
          Report("Input error",lineNum,line);
          continue;
	}

	// Header looks good, start to collect SQL.
        state = kLOOKING_FOR_TRAILER;
        sql = "";
      }
      else {
        Report("Not header",lineNum,line);
      }
    }

    //Look for trailer line.

    else {
      if ( line.substr(0,5) == "<<<<<" ) {
        if ( line.size() >= kHEADER_TRAILER_MAX_LEN
           ) msg = "Bad trailer";

        else {

	  //  Collect table name and SeqNo.
          istringstream istr(line.substr(5));
          istr.width(kMAXTABLENAMELEN);
	  istr >> nameTrail >> seqNoTrail;
          if ( ! istr.eof() ) msg = "Input error";

	  else if (    nameTrail != nameHead
                    || seqNoHead != seqNoTrail ) {
            msg = "Header/Trailer mismatch: Header: ";
            msg += istr.str();
	  }
	  else if ( GetNumSqlStmts() == 0
                  ) msg = "No SQL statements between Header/Trailer";
	  else {

 	    // Trailer looks good return with object filled.
            fSeqNo     = seqNoHead;
            fTableName = nameHead;

	    //Dig out the creation date from the first record.
            string date = this->GetStmtValues(0)[9];
	    //Remove the quotes.
            date.erase(0,1);
            date.erase(date.size()-1,1);
            fCreationDate = TDbi::MakeTimeStamp(date);
            return kTRUE;

	  }
	}

	// Trailer bad, start again!
        Report(msg.c_str(),lineNum,line);
        state = kLOOKING_FOR_HEADER;
      }

      // Not a trailer line, must be SQL, collect and append lines
      // until a trailing ; found.
      else {
        sql += line;
        if ( sql[sql.size()-1] == ';') {
          fSqlStmts.push_back(sql);
          ++fNumStmts;
          sql = "";
	}
      }
    }

  }

  if ( state != kLOOKING_FOR_HEADER
     ) Report("Unexpected EOF",lineNum,"EOF");
  this->Reset();
  return kFALSE;

}
//.....................................................................
/// Return a selected statment
string TDbiSqlValPacket::GetStmt(UInt_t stmtNo) const {
//
//
//  Purpose:  Return a selected statment

  if ( stmtNo >= this->GetNumSqlStmts() ) return "";

  // Locate statement
  std::list<std::string>::const_iterator itr = fSqlStmts.begin();
  while ( stmtNo ) { ++itr; --stmtNo; }

  return *itr;

}
//.....................................................................
/**\verbatim
   
     Purpose:  Return all the values associated with a selected statment
   
     Arguments:
       stmtNo       in    The statement number (starting at 0)
   
     Return:              vector of string values.
                          Empty vector if stmt does not exits.
   
     Contact:   N. West
   

Definition at line 568 of file TDbiSqlValPacket.cxx.

References GetNumSqlStmts(), GetStmt(), and UtilString::StringTok().

Referenced by Compare().

00568                                                                         {
00569 
00570 
00571   std::vector<std::string> vec;
00572   if ( stmtNo >= this->GetNumSqlStmts() ) return vec;
00573 
00574   // Locate statement
00575   std::string str = this->GetStmt(stmtNo);
00576 
00577   // Extract ...(list-of-values)... and parse it into tokens.
00578   std::string::size_type pos = str.find('(');
00579   ++pos;
00580   std::string::size_type n = str.find(')') - pos;
00581   UtilString::StringTok(vec,str.substr(pos,n),",");
00582 
00583   return vec;
00584 
00585 }

Here is the call graph for this function:

Here is the caller graph for this function:

const string& TDbiSqlValPacket::GetTableName (  )  const [inline]

Definition at line 79 of file TDbiSqlValPacket.hxx.

References fTableName.

Referenced by AddRow(), CreateTable(), SetMetaData(), Store(), and Write().

00079 { return fTableName; }

Here is the caller graph for this function:

Bool_t TDbiSqlValPacket::IsEqual ( const TDbiSqlValPacket that,
Bool_t  log = kFALSE,
const Char_t *  thisName = "this",
const Char_t *  thatName = "that" 
) const
     Purpose:  Test for equality to another TDbiSqlValPacket
   
     Arguments:
       that         in    The other TDbiSqlValPacket to be compared.
       log          in    If true list differences to MSG("TDbi",kInfo)
       thisName     in    Optional name for this packet (default: this)
       thatName     in    Optional name for that packet (default: that)
   
     Return:    kTRUE if identical (apart from InsertDate).
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o Compare to another TDbiSqlValPacket.
   
     Program Notes:-
     =============
   
     The InsertDate reflects the date when the data was written into the
    local database so has to be excluded from the comparison.
   

Definition at line 614 of file TDbiSqlValPacket.cxx.

References fNumStmts, fSeqNo, fSqlStmts, fTableName, SK_DBI_Info, and SK_DBI_Log.

Referenced by Compare().

00617                                                                {
00618 //
00619   if (    fSeqNo           != that.fSeqNo
00620        || fTableName       != that.fTableName
00621        || fNumStmts != that.fNumStmts ) {
00622     SK_DBI_Log("Conflict found:"
00623              << " for : " << thisName << " , " << thatName << " :-\n"
00624              << "  SeqNo " << fSeqNo << "," << that.fSeqNo
00625              << "\n  TableName " << fTableName << "," << that.fTableName
00626              << "\n  Size " << fNumStmts << ","
00627              << that.fNumStmts);
00628     return kFALSE;
00629   }
00630 
00631   list<string>::const_iterator itrThisBegin = fSqlStmts.begin();
00632   list<string>::const_iterator itrThisEnd   = fSqlStmts.end();
00633   list<string>::const_iterator itrThatBegin = that.fSqlStmts.begin();
00634   list<string>::const_iterator itrThatEnd   = that.fSqlStmts.end();
00635 
00636   list<string>::const_iterator itrThis = itrThisBegin;
00637   list<string>::const_iterator itrThat = itrThatBegin;
00638 
00639   Bool_t isEqual = kTRUE;
00640 
00641   // Strip off InsertDate from first statement (assume its
00642   // the last parameter in list).
00643 
00644   string strThis = (*itrThis).substr(0,(*itrThis).rfind(','));
00645   string strThat = (*itrThat).substr(0,(*itrThat).rfind(','));
00646   if ( strThis != strThat ) {
00647   if ( ! log ) return kFALSE;
00648   isEqual = kFALSE;
00649   SK_DBI_Info(  "Difference on VLD record " << ":-\n"
00650       << "  " << thisName << ": " << strThis  << "  "
00651       << "  " << thatName << ": " << strThat  << "  ");
00652   }
00653 
00654   // Rows can come in any order (after the first) so we have
00655   // to sort before comparing.  However, if we are lucky, they
00656   // may be in the same order or inverse order so do a quick
00657   // test to see if there are no conflicts assuming these
00658   // relative orderings.
00659 
00660   ++itrThis;
00661   ++itrThat;
00662   while ( itrThis != itrThisEnd && (*itrThis) == (*itrThat) ) {
00663 //     cout << "Debug: trying forward compare ..." << *itrThis
00664 //       << "::" << *itrThat << endl;
00665     ++itrThis;
00666     ++itrThat;
00667   }
00668   if ( itrThis == itrThisEnd ) return isEqual;
00669 
00670   itrThis = itrThisBegin;
00671   itrThat = itrThatEnd;
00672   ++itrThis;
00673   --itrThat;
00674 
00675   while ( itrThis != itrThisEnd &&  (*itrThis) == (*itrThat) ) {
00676 //   cout << "Debug: trying reverse compare ..." << *itrThis
00677 //       << "::" << *itrThat << endl;
00678     ++itrThis;
00679     --itrThat;
00680   }
00681   if ( itrThis == itrThisEnd ) return isEqual;
00682 
00683   // O.K., we are out of luck so set up pointers to both sets
00684   // and sort these.
00685 
00686   typedef vector<const string*>      shadow_list_t;
00687   typedef shadow_list_t::iterator  shadow_list_itr_t;
00688 
00689   shadow_list_t shadowThis;
00690   shadow_list_t shadowThat;
00691 
00692   itrThis = itrThisBegin;
00693   itrThat = itrThatBegin;
00694   ++itrThis;
00695   ++itrThat;
00696 
00697   while ( itrThis != itrThisEnd ) {
00698     shadowThis.push_back(&(*itrThis));
00699     shadowThat.push_back(&(*itrThat));
00700     ++itrThis;
00701     ++itrThat;
00702   }
00703 
00704   shadow_list_itr_t shadowThisItr    = shadowThis.begin();
00705   shadow_list_itr_t shadowThisItrEnd = shadowThis.end();
00706   shadow_list_itr_t shadowThatItr    = shadowThat.begin();
00707   shadow_list_itr_t shadowThatItrEnd = shadowThat.end();
00708 
00709   sort(shadowThisItr,shadowThisItrEnd,compStringPtrs);
00710   sort(shadowThatItr,shadowThatItrEnd,compStringPtrs);
00711 
00712   while ( shadowThisItr != shadowThisItrEnd ) {
00713     if ( (**shadowThisItr) != (**shadowThatItr) ){
00714       if ( ! log ) return kFALSE;
00715       isEqual = kFALSE;
00716       SK_DBI_Info( "Difference on data record "
00717          << ":-\n"
00718          << "  " << thisName << ": " << **shadowThisItr  << "  "
00719          << "  " << thatName << ": " << **shadowThatItr  << "  ");
00720     }
00721    ++shadowThisItr;
00722    ++shadowThatItr;
00723   }
00724 
00725   return isEqual;
00726 
00727 }

Here is the caller graph for this function:

void TDbiSqlValPacket::Print ( Option_t *  option = ""  )  const [virtual]

Print the current state.

Definition at line 731 of file TDbiSqlValPacket.cxx.

References fCreationDate, fNumErrors, fSeqNo, fSqlMySqlMetaMain, fSqlMySqlMetaVld, fSqlStmts, fTableName, GetNumSqlStmts(), and SK_DBI_Info.

00731                                                           {
00732 //
00733 //
00734 //  Purpose:  Print the current state.
00735 
00736   SK_DBI_Info(  "TDbiSQLValPacket:"
00737     << " table \"" << fTableName << "\" "
00738     << " SeqNo " << fSeqNo
00739     << " NumErrors " << fNumErrors
00740     << "  "
00741     << "   CreationDate " << fCreationDate
00742     << "  ");
00743 
00744   SK_DBI_Info(  "   MySQL Main table creation: \"" << fSqlMySqlMetaMain << "\"" << "  ");
00745 
00746   SK_DBI_Info(  "   MySQL VLD table creation: \"" << fSqlMySqlMetaVld << "\"" << "  ");
00747 
00748   if ( GetNumSqlStmts() > 0 ) {
00749     std::list<string>::const_iterator itr    = fSqlStmts.begin();
00750     std::list<string>::const_iterator itrEnd = fSqlStmts.end();
00751     for (; itr != itrEnd; ++itr)
00752       SK_DBI_Info(  "   SqlStmt \"" << *itr << "\"" << "  ");
00753   }
00754   else {
00755     SK_DBI_Info( "   No SqlStmts." << "  ");
00756   }
00757 
00758 }

Here is the call graph for this function:

void TDbiSqlValPacket::Recreate ( const string &  tableName,
const TVldRange vr,
Int_t  aggNo,
TDbi::Task  task = 0,
TVldTimeStamp  creationDate = TVldTimeStamp() 
)

Purpose: Recreate and define first row (VLD - the validity record).

Definition at line 764 of file TDbiSqlValPacket.cxx.

References AddRow(), Clear(), fNumErrors, fTableName, TDbiDatabaseManager::GetCascader(), TDbiOutRowStream::GetCSV(), TDbiTableProxy::GetMetaValid(), TDbiDatabaseManager::GetTableProxy(), TDbiDatabaseManager::Instance(), SetCreationDate(), SK_DBI_Severe, TDbiValidityRec::Store(), and TDbiCascader::TableExists().

Referenced by TDbiLogEntry::Write().

00767                                                                      : 0 */
00768                                TVldTimeStamp creationDate   /*  Default: now */
00769                                ) {
00770 //
00771 
00772 
00773 
00774   this->Clear();
00775 
00776   TDbiDatabaseManager& tablePR = TDbiDatabaseManager::Instance();
00777   if ( ! tablePR.GetCascader().TableExists(tableName) ) {
00778        SK_DBI_Severe( "Cannot create packet - table " << tableName
00779                            << " does not exist." << "  ");
00780     fNumErrors = 1;
00781     return;
00782   }
00783 
00784   fTableName = tableName;
00785 
00786 
00787   // Create a TDbiValidityRec from the supplied data.
00788   TDbiValidityRec vrec(vr,task,aggNo,0);
00789 
00790   //  Create a TDbiOutRowStream that can serialise this validity record
00791   TDbiConfigSet dummy;     // For validity row any TDbiTableRow will do.
00792   const TDbiTableMetaData&  metaValid = tablePR.GetTableProxy(tableName,&dummy)
00793                                               .GetMetaValid();
00794   TDbiOutRowStream buff(&metaValid);
00795 
00796   vrec.Store(buff,0);
00797   this->AddRow(buff.GetCSV());
00798   this->SetCreationDate(creationDate);
00799 
00800 }

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiSqlValPacket::Report ( const char *  msg,
UInt_t  lineNum,
const string &  line 
) [private]
     Purpose:  Report and count errors.
   
     Arguments:
       msg          in    Message to be reported.
       lineNum      in    Line number.
       line         in    Input line causing error.
   
     Return:
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o Reset object, report and count errors.
   

Definition at line 820 of file TDbiSqlValPacket.cxx.

References fNumErrors, Reset(), and SK_DBI_Severe.

00822                                                  {
00823 //
00824 
00825 //  Program Notes:-
00826 //  =============
00827 
00828 //  None.
00829 
00830      SK_DBI_Severe( " on line " << lineNum
00831                          <<":- \n  " << line << "  ");
00832   this->Reset();
00833   ++fNumErrors;
00834 
00835 }

Here is the call graph for this function:

void TDbiSqlValPacket::Reset (  ) 

Purpose: Clear out back to unfilled status except for fNumErrors.

Definition at line 839 of file TDbiSqlValPacket.cxx.

References fNumStmts, fSeqNo, fSqlMySqlMetaMain, fSqlMySqlMetaVld, fSqlStmts, and fTableName.

Referenced by Clear(), and Report().

00839                              {
00840 //
00841 //
00842 //
00843   fSeqNo       = 0;
00844   fSqlMySqlMetaMain = "";
00845   fSqlMySqlMetaVld  = "";
00846   fSqlStmts.clear();
00847   fNumStmts    = 0;
00848   fTableName   = "";
00849 
00850 }

Here is the caller graph for this function:

void TDbiSqlValPacket::SetCreationDate ( TVldTimeStamp  ts  ) 

Purpose: Set creation date.

Definition at line 853 of file TDbiSqlValPacket.cxx.

References TVldTimeStamp::AsString(), fCreationDate, fSqlStmts, and GetNumSqlStmts().

Referenced by Recreate().

00853                                                        {
00854 //
00855 //
00856 //
00857   fCreationDate = ts;
00858 
00859   //  Update the validity row assuming:  "...,'creationdate',insertdate);"
00860   if ( this->GetNumSqlStmts() == 0 ) return;
00861 
00862   string& vldRow = *fSqlStmts.begin();
00863   string::size_type locEnd = vldRow.rfind(',');
00864   if ( locEnd == string::npos ) return;
00865   locEnd -=2;
00866   string::size_type locStart = vldRow.rfind(',',locEnd);
00867   if ( locStart == string::npos ) return;
00868   locStart+=2;
00869   vldRow.replace(locStart,locEnd-locStart+1,ts.AsString("s"));
00870 
00871 }

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiSqlValPacket::SetEpoch ( UInt_t  epoch  ) 

Set EPOCH.

Definition at line 874 of file TDbiSqlValPacket.cxx.

References fSqlStmts, and GetNumSqlStmts().

00874                                             {
00875 //
00876 //
00877 //  Purpose:  Set EPOCH
00878 
00879   //  Update the validity row assuming:  "(seqno,timestart,timeend,epoch,....)
00880   if ( this->GetNumSqlStmts() == 0 ) return;
00881 
00882   string& vldRow = *fSqlStmts.begin();
00883   string::size_type locStart = 0;
00884   for (int field = 0; field < 3; ++field) {
00885     locStart = vldRow.find(',',locStart+1);
00886     if ( locStart == string::npos ) return;
00887   }
00888   string::size_type locEnd = vldRow.find(',',locStart+1);
00889   if ( locEnd == string::npos ) return;
00890   locEnd  -=1;
00891   locStart+=1;
00892   ostringstream epoch_str;
00893   epoch_str << epoch;
00894   vldRow.replace(locStart,locEnd-locStart+1,epoch_str.str());
00895 
00896 }

Here is the call graph for this function:

void TDbiSqlValPacket::SetMetaData (  )  const [private]

Purpose: Set up meta-data as SQL table creation statements.

Definition at line 901 of file TDbiSqlValPacket.cxx.

References fSqlMySqlMetaMain, fSqlMySqlMetaVld, TDbiDatabaseManager::GetCascader(), TDbiTableProxy::GetMetaData(), TDbiTableProxy::GetMetaValid(), TDbiCascader::GetTableDbNo(), GetTableName(), TDbiDatabaseManager::GetTableProxy(), TDbiDatabaseManager::Instance(), and TDbiTableMetaData::Sql().

Referenced by Write().

00901                                          {
00902 //
00903 //
00904 //
00905   TDbiDatabaseManager& tbprxreg = TDbiDatabaseManager::Instance();
00906 
00907   //  Locate the table in the cascade.
00908   TDbiCascader& cas = tbprxreg.GetCascader();
00909   Int_t dbNo = cas.GetTableDbNo(this->GetTableName());
00910   if ( dbNo < 0 ) return;
00911 
00912   //  Any table proxy will do to get the meta-data so use the one for a
00913   //  TDbiConfigSet;
00914   TDbiConfigSet dummy;
00915   const TDbiTableMetaData & metaVld =  tbprxreg.GetTableProxy(this->GetTableName(),&dummy)
00916                                      .GetMetaValid();
00917   const TDbiTableMetaData & metaMain = tbprxreg.GetTableProxy(this->GetTableName(),&dummy)
00918                                      .GetMetaData();
00919   fSqlMySqlMetaVld   = metaVld.Sql();
00920   fSqlMySqlMetaMain  = metaMain.Sql();
00921 
00922 }

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiSqlValPacket::SetSeqNo ( UInt_t  seqno  ) 

Set sequence number.

Definition at line 926 of file TDbiSqlValPacket.cxx.

References fSeqNo, fSqlStmts, GetNumSqlStmts(), and SetSeqNoOnRow().

Referenced by TDbiLogEntry::Write().

00926                                             {
00927 //
00928 //
00929 //  Purpose:  Set Sequence number.
00930 
00931   fSeqNo = seqno;
00932 
00933   //  Update all rows
00934   if ( this->GetNumSqlStmts() == 0 ) return;
00935 
00936   ostringstream tmp;
00937   tmp << seqno;
00938   const string seqnoStr = tmp.str();
00939 
00940   std::list<string>::iterator itr    = fSqlStmts.begin();
00941   std::list<string>::iterator itrEnd = fSqlStmts.end();
00942   for (; itr != itrEnd; ++itr) SetSeqNoOnRow(*itr,seqnoStr);
00943 
00944 
00945 }

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiSqlValPacket::SetSeqNoOnRow ( string &  row,
const string &  seqno 
) [private]

Purpose: Set Sequence number on supplied row.

Definition at line 949 of file TDbiSqlValPacket.cxx.

Referenced by AddRow(), and SetSeqNo().

00949                                                                     {
00950 //
00951 //
00952 
00953 //  Update row assuming:  "...(seqno, ...."
00954 
00955   string::size_type locStart = row.find('(');
00956   if ( locStart == string::npos ) return;
00957   ++locStart;
00958   string::size_type locEnd = row.find(',',locStart);
00959   if ( locEnd == string::npos ) return;
00960   row.replace(locStart,locEnd-locStart,seqno);
00961 
00962 }

Here is the caller graph for this function:

Bool_t TDbiSqlValPacket::Store ( UInt_t  dbNo,
Bool_t  replace = kFALSE 
) const
   
     Purpose:  Output validity packet to specified database.
   
     Arguments:
       dbNo         in    Number of database in the cascade.
       replace      in    If true replace existing SeqNo (default: kFALSE).
   
     Return:    kTRUE if successfully stored.
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o Output validity packet to specified database modifying
       InsertDate to be current date.
   

Definition at line 983 of file TDbiSqlValPacket.cxx.

References CanBeStored(), fSqlStmts, TDbiTableProxy::GetDBProxy(), GetTableName(), TDbiDatabaseManager::GetTableProxy(), TDbiDatabaseManager::Instance(), TDbi::MakeDateTimeString(), TDbiDBProxy::RemoveSeqNo(), SK_DBI_Severe, and SK_DBI_Warn.

Referenced by TDbiLogEntry::Write().

00983                                                                 {
00984 
00985 
00986   if ( ! CanBeStored() ) return kFALSE;
00987 
00988   //Just use any old table row object just to get a TDbiDBProxy.
00989   TDbiConfigSet pet;
00990   TDbiTableProxy& tp =  TDbiDatabaseManager::Instance()
00991                       .GetTableProxy(this->GetTableName(),&pet);
00992   if ( replace ) {
00993     const TDbiDBProxy & proxy = tp.GetDBProxy();
00994     if ( ! proxy.RemoveSeqNo(this->GetSeqNo(),dbNo) ) return kFALSE;
00995   }
00996 
00997   // Locate required TDbiStatement.
00998   auto_ptr<TDbiStatement> stmtDb(TDbiDatabaseManager::Instance()
00999                                .GetCascader()
01000                                .CreateStatement(dbNo));
01001   if ( ! stmtDb.get() ) {
01002     SK_DBI_Warn(  "Attempting to write to non-existant cascade entry " << dbNo
01003       << "  ");
01004     return kFALSE;
01005   }
01006 
01007 
01008   // Loop processing all SQL statements
01009   Bool_t first = kTRUE;
01010   int combineInserts = 0;
01011   int maxInserts = 20;
01012   string sqlInserts;
01013 
01014   for (list<string>::const_iterator itr = fSqlStmts.begin();
01015        itr != fSqlStmts.end();
01016        ++itr) {
01017     if ( first ) {
01018 //    On first statement replace InsertDate by current datetime.
01019       string sql = *itr;
01020       list<string>::size_type locDate = sql.rfind(",\'");
01021       if ( locDate !=  string::npos ) {
01022         TVldTimeStamp now;
01023         sql.replace(locDate+2,19,TDbi::MakeDateTimeString(now));
01024       }
01025       stmtDb->ExecuteUpdate(sql.c_str());
01026       if ( stmtDb->PrintExceptions() ) return kFALSE;
01027       first = kFALSE;
01028       continue;
01029     }
01030 
01031     string sql = *itr;
01032 
01033 //  Reduce database I/O by combining groups of insert commands.
01034 
01035     string::size_type insertIndex = sql.find("VALUES (");
01036     if ( insertIndex == string::npos) {
01037          SK_DBI_Severe( "Unexpected SQL : " << sql
01038                              << "\n  should be of form INSERT INTO ... VALUES (...);" << "  ");
01039       return kFALSE;
01040     }
01041     ++combineInserts;
01042     if ( combineInserts == 1 ) sqlInserts = sql;
01043     else {
01044       sqlInserts[sqlInserts.size()-1] = ',';
01045       sqlInserts += sql.substr(insertIndex+7);
01046     }
01047     if ( combineInserts >= maxInserts ) {
01048       stmtDb->ExecuteUpdate(sqlInserts.c_str());
01049       if ( stmtDb->PrintExceptions() ) return kFALSE;
01050       combineInserts = 0;
01051     }
01052   }
01053 
01054 // Deal with last group of inserts.
01055   if ( combineInserts ) {
01056     stmtDb->ExecuteUpdate(sqlInserts.c_str());
01057     combineInserts = 0;
01058     if ( stmtDb->PrintExceptions() ) return kFALSE;
01059   }
01060 
01061   return kTRUE;
01062 
01063 }

Here is the call graph for this function:

Here is the caller graph for this function:

Bool_t TDbiSqlValPacket::Write ( std::ofstream &  ios,
Bool_t  addMetadata = kFALSE 
) const
     Purpose:  Export to an iostream.
   
     Arguments:
        ios          in/out    Output stream.
        addMetadata  in        if kTRUE, output SQL metadata (in form
                               of a create table SQL)
   
     Return:    kTRUE is I/O successful.
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o Export to an iostream.
   

Definition at line 1083 of file TDbiSqlValPacket.cxx.

References CanBeStored(), fSqlMySqlMetaMain, fSqlMySqlMetaVld, fSqlStmts, GetSeqNo(), GetTableName(), SetMetaData(), and SK_DBI_Warn.

01084                                                         {
01085 
01086 //  Program Notes:-
01087 //  =============
01088 
01089 //  None.
01090 
01091   if ( ! CanBeStored() ) return kFALSE;
01092   if ( addMetadata ) {
01093     if ( fSqlMySqlMetaMain.size() == 0 ) this->SetMetaData();
01094     if ( fSqlMySqlMetaMain.size() == 0 ) {
01095       SK_DBI_Warn(  "Cannot write metadata; no associated TDbiTableProxy "
01096       << "  ");
01097     }
01098     else {
01099 
01100 
01101       ios << ">>>>>" << GetTableName() << " Metadata [MySQL]" << endl;
01102       ios << fSqlMySqlMetaVld   << endl;
01103       ios << fSqlMySqlMetaMain  << endl;
01104       ios << "<<<<<" << GetTableName() << " Metadata" << endl;
01105     }
01106   }
01107 
01108   ios << ">>>>>" << GetTableName() << "  " << GetSeqNo() << endl;
01109 
01110   for ( list<string>::const_iterator itr = fSqlStmts.begin();
01111         itr != fSqlStmts.end();
01112         ++itr) ios << (*itr) << endl;
01113 
01114   ios << "<<<<<" << GetTableName() << "  " << GetSeqNo() << endl;
01115 
01116   return kTRUE;
01117 
01118 }

Here is the call graph for this function:


Member Data Documentation

Creation date, or object creation date if unfilled.

Definition at line 150 of file TDbiSqlValPacket.hxx.

Referenced by GetCreationDate(), Print(), and SetCreationDate().

UInt_t TDbiSqlValPacket::fNumErrors [private]

Number of error encountered while filling.

Definition at line 129 of file TDbiSqlValPacket.hxx.

Referenced by AddDataRow(), AddRow(), CanBeStored(), Clear(), GetNumErrors(), Print(), Recreate(), and Report().

UInt_t TDbiSqlValPacket::fNumStmts [private]

Number of statements.

Definition at line 144 of file TDbiSqlValPacket.hxx.

Referenced by AddRow(), GetNumSqlStmts(), IsEqual(), and Reset().

UInt_t TDbiSqlValPacket::fSeqNo [private]

Sequence number or 0 if not filled.

Definition at line 132 of file TDbiSqlValPacket.hxx.

Referenced by CanBeStored(), Compare(), GetSeqNo(), IsEqual(), Print(), Reset(), and SetSeqNo().

string TDbiSqlValPacket::fSqlMySqlMetaMain [mutable, private]

MySQL SQL to create main table. May be empty until needed.

Definition at line 135 of file TDbiSqlValPacket.hxx.

Referenced by CreateTable(), Print(), Reset(), SetMetaData(), and Write().

string TDbiSqlValPacket::fSqlMySqlMetaVld [mutable, private]

As fSqlMySqlMetaMain but for aux. table.

Definition at line 138 of file TDbiSqlValPacket.hxx.

Referenced by CreateTable(), Print(), Reset(), SetMetaData(), and Write().

std::list<string> TDbiSqlValPacket::fSqlStmts [private]

Set of SQL statements to generate packet.

Definition at line 141 of file TDbiSqlValPacket.hxx.

Referenced by AddRow(), IsEqual(), Print(), Reset(), SetCreationDate(), SetEpoch(), SetSeqNo(), Store(), and Write().

string TDbiSqlValPacket::fTableName [private]

Table name or null if not filled.

Definition at line 147 of file TDbiSqlValPacket.hxx.

Referenced by Compare(), CreateTable(), GetTableName(), IsEqual(), Print(), Recreate(), and Reset().


The documentation for this class was generated from the following files:

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1