TDbiCascader Class Reference

Concept A cascade (prioritorised list) of TDbiConnection s, one for each database in the cascade. More...

#include <TDbiCascader.hxx>

Collaboration diagram for TDbiCascader:
Collaboration graph
[legend]

List of all members.

Classes

class  Lock
 Private Locker object used by TDbiCascader. More...

Public Types

enum  Status { kFailed, kClosed, kOpen }

Public Member Functions

TDbiStatementCreateStatement (UInt_t dbNo) const
 Create a TDbiStatement. Caller must delete.
const TDbiConnectionGetConnection (UInt_t dbNo) const
 Return associated TDbiConnection. TDbiCascader retains ownership.
TDbiConnectionGetConnection (UInt_t dbNo)
string GetDbName (UInt_t dbNo) const
 Purpose: Return Database Name for cascade entry number.
Int_t GetDbNo (const string &dbName) const
Int_t GetStatus (UInt_t dbNo) const
string GetStatusAsString (UInt_t dbNo) const
string GetURL (UInt_t dbNo) const
Bool_t IsTemporaryTable (const string &tableName, Int_t dbNo) const
 Purpose: Return kTRUE if tableName is temporary in cascade member dbNo.
Int_t AllocateSeqNo (const string &tableName, Int_t requireGlobal=0, Int_t dbNo=0) const
Int_t GetAuthorisingDbNo () const
UInt_t GetNumDb () const
Int_t GetTableDbNo (const string &tableName, Int_t selectDbNo=-1) const
Bool_t TableExists (const string &tableName, Int_t selectDbNo=-1) const
Int_t CreateTemporaryTable (const string &tableName, const string &tableDescr)
void HoldConnections ()
void ReleaseConnections ()
void SetPermanent (UInt_t dbNo, Bool_t permanent=true)
 Purpose: Set connection permanent.

Static Public Member Functions

static bool canConnect ()

Private Member Functions

Int_t ReserveNextSeqNo (const string &tableName, Bool_t isGlobal, UInt_t dbNo) const
void SetAuthorisingEntry (Int_t entry)
 TDbiCascader (bool beQuiet=false)
virtual ~TDbiCascader ()
 TDbiCascader (const TDbiCascader &)

Private Attributes

Int_t fGlobalSeqNoDbNo
 1st db in cascade with GlobalSeqNo table
vector< TDbiConnection * > fConnections
 Vector of TDbiConnections, one for each DB.
std::map< string, Int_t > fTemporaryTables
 Mapping Name->DbNo for temporary tables.

Friends

class TDbiDatabaseManager
class TDbiValidate
ostream & operator<< (ostream &s, const TDbiCascader &cascader)

Detailed Description

Concept A cascade (prioritorised list) of TDbiConnection s, one for each database in the cascade.

Purpose Implements the concept of a cascade allowing user to overrride parts of the standard database by introducing higher priority non-standard ones above it in a cascade. Contact: A.Finch@lancaster.ac.uk

Definition at line 48 of file TDbiCascader.hxx.


Member Enumeration Documentation

Enumerator:
kFailed 
kClosed 
kOpen 

Definition at line 62 of file TDbiCascader.hxx.

00062 { kFailed, kClosed, kOpen };


Constructor & Destructor Documentation

TDbiCascader::TDbiCascader ( bool  beQuiet = false  )  [private]
TDbiCascader::~TDbiCascader (  )  [private, virtual]

Definition at line 174 of file TDbiCascader.cxx.

References fConnections, GetNumDb(), and SK_DBI_Trace.

00174                             {
00175 //
00176 //
00177 //  Purpose: Destructor
00178 //
00179 
00180 
00181   SK_DBI_Trace( "Destroying TDbiCascader" << "  ");
00182 
00183   for (Int_t dbNo = this->GetNumDb()-1; dbNo >= 0; --dbNo) delete fConnections[dbNo];
00184 
00185 }

Here is the call graph for this function:

TDbiCascader::TDbiCascader ( const TDbiCascader  )  [private]

Member Function Documentation

Int_t TDbiCascader::AllocateSeqNo ( const string &  tableName,
Int_t  requireGlobal = 0,
Int_t  dbNo = 0 
) const
   
     Purpose:  Allocate a unique (either locally or globally) SEQNO.
   
     Arguments:
      tableName       in    The table for which the SEQNO is required.
      requireGlobal   in    The type of SEQNO required:-
                              > 0  Must be global
                              = 0  Must be global if supplied dbNo is authorising
                                   and table isn't temporary otherwise local
                              < 0  Must be local
      dbNo            in     The entry in the cascade for which the SEQNO is required
   
     Return:    The allocated SEQNO or 0 if failure.
   
     Contact:   N. West
   
     Program Notes:-
     =============
   
     Requests for SEQNOs take account of any pre-existing entries; local entries
     should only be used for development and this allows for the LOCALSEQNO table
     and the local data to be wiped at different times without causing conflicts.
     Global entries should not be a problem as the GLOBALSEQNO table isn't wiped
     but it provides protection in case the table is damaged (which has happened!).
   

Definition at line 269 of file TDbiCascader.cxx.

References fGlobalSeqNoDbNo, IsTemporaryTable(), ReserveNextSeqNo(), and SK_DBI_Warn.

Referenced by TSeqNoAllocator::GetSeqNo(), TDbiLogEntry::Write(), and TDbiConfigStream::Write().

00271                                                               {
00272 
00273 
00274 
00275   bool isTemporary = IsTemporaryTable(tableName,dbNo);
00276 
00277   //  Deal with global requests.
00278 
00279   if (     requireGlobal > 0
00280       || ( requireGlobal == 0 && dbNo == fGlobalSeqNoDbNo && ! isTemporary ) ) {
00281     if ( fGlobalSeqNoDbNo < 0 ) {
00282       SK_DBI_Warn( "Unable to issue global SEQNO - no authorising DB in cascade\n"
00283                                << "  will issue local one instead" << "  ");
00284     }
00285     else if ( isTemporary ) {
00286       SK_DBI_Warn( "Unable to issue global SEQNO - " << tableName << " is temporary\n"
00287                                << "  will issue local one instead" << "  ");
00288     }
00289     else return this->ReserveNextSeqNo(tableName,true,fGlobalSeqNoDbNo);
00290   }
00291 
00292   // Deal with local requests
00293 
00294   return this->ReserveNextSeqNo(tableName,false,dbNo);
00295 
00296 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool TDbiCascader::canConnect (  )  [static]

Check we can connect to the database defined in the environment variables. Allows a user program to skip using the database if it doesn't need to and it is not there, or if it does need it then die in a civilised manner.

Definition at line 225 of file TDbiCascader.cxx.

References SK_DBI_Trace.

00226 {
00227   SK_DBI_Trace(" bool TDbiCascader::canConnect() started");
00228 
00229   try
00230     {
00231       TDbiCascader test(false);
00232       //   test.NOOP();
00233       SK_DBI_Trace(" bool TDbiCascader::canConnect() return true");
00234       return true;
00235     }
00236   catch(...)
00237     {
00238       SK_DBI_Trace(" bool TDbiCascader::canConnect() return false");
00239       return false;
00240     }
00241 }

TDbiStatement * TDbiCascader::CreateStatement ( UInt_t  dbNo  )  const

Create a TDbiStatement. Caller must delete.

   
     Purpose:  Return a Statement to caller.
   
     Arguments:
       dbNo     in    Database no. in cascade for which statement
                      is required.
   
     Return:    Created statement (or 0 if creation failed).
                User must delete.
     Program Notes:-
     =============
   
     As the caller is responsible for destroying the statement after use
     consider:-
   
     #include <memory>
     using std::auto_ptr;
   
     ...
   
     auto_ptr<TDbiStatement> stmt(cascader.CreateStatement(dbNo));
   

Definition at line 322 of file TDbiCascader.cxx.

References fConnections, GetStatus(), kFailed, and TDbiStatement::PrintExceptions().

Referenced by CreateTemporaryTable(), TDbiDBProxy::FindTimeBoundaries(), TDbiDBProxy::QueryAllValidities(), TDbiDBProxy::QuerySeqNo(), TDbiDBProxy::QuerySeqNos(), TDbiDBProxy::QueryValidity(), TDbiDBProxy::RemoveSeqNo(), TDbiDBProxy::ReplaceInsertDate(), TDbiDBProxy::ReplaceSeqNo(), and ReserveNextSeqNo().

00322                                                               {
00323 
00324 
00325   if ( this->GetStatus(dbNo) == kFailed ) return 0;
00326   TDbiConnection& conDb = *fConnections[dbNo];
00327   TDbiStatement* stmtDb = new TDbiStatement(conDb);
00328   stmtDb->PrintExceptions();
00329   return stmtDb;
00330 
00331 }

Here is the call graph for this function:

Here is the caller graph for this function:

Int_t TDbiCascader::CreateTemporaryTable ( const string &  tableNameMc,
const string &  tableDescr 
)
   
     Purpose:  Creat temporary table with associated validity table
   
     Arguments:
       tableNameMc  in    Table name
       tableDescr   in    Table description as parenthesised comma
                          separated list e.g.:-
                          "(MyInt int, MyFloat float, MyString text)"
   
     Return:    The database cascade number on which the table was
                created or = -1 if unable to create.
   
     Contact:   N. West
   
     Specification:-
     =============
   
     o Loop over all databases in cascade, starting at the highest
       priority i.e. entry 0 and find the first that will accept create
       temporary table requests.  Return -1 if none will.
   
     o Make connection permanent so that temporary data won't be lost.
   
     o Generate and submit requests to create temporary table with
       associated validity table and return the cascade number of
       the database that has accepted the tables, recording table
       name in fTemporaryTables.
   
   

Definition at line 363 of file TDbiCascader.cxx.

References CreateStatement(), fConnections, fTemporaryTables, GetConnection(), TDbiConnection::GetUrl(), TDbi::GetVldDescr(), TDbiConnection::IsTemporary(), TDbiConnection::SetPermanent(), TDbiConnection::SetTableExists(), SK_DBI_Info, SK_DBI_Log, SK_DBI_Severe, and UtilString::ToUpper().

00364                                                                  {
00365 
00366 
00367 //  Check that input args look plausible.
00368 
00369   string tableName = UtilString::ToUpper(tableNameMc);
00370   if (    tableName == ""
00371        || tableDescr[0] != '('
00372        || tableDescr[tableDescr.size()-1] != ')' ) {
00373        SK_DBI_Severe( "Illegal input args:-" << "  "
00374                            << "     Table Name: " << tableName
00375                            << "  Table Description: " << tableDescr
00376                            <<"  ");
00377     return -1;
00378   }
00379 
00380 // Find a DB that will accept the command.
00381   string sqlMakeTable;
00382 
00383   Int_t dbNoAcc       = -1;
00384   auto_ptr<TDbiStatement> stmtDb;
00385   for (UInt_t dbNoTry = 0; dbNoTry < fConnections.size(); ++dbNoTry ) {
00386     stmtDb.reset(this->CreateStatement(dbNoTry));
00387     if ( stmtDb.get() ) {
00388       sqlMakeTable = " create temporary table ";
00389       sqlMakeTable += tableName;
00390       sqlMakeTable += " ";
00391       sqlMakeTable += tableDescr;
00392       sqlMakeTable += ";";
00393       stmtDb->ExecuteUpdate(sqlMakeTable.c_str());
00394       if ( stmtDb->GetExceptionLog().IsEmpty() ) {
00395         dbNoAcc = dbNoTry;
00396         this->GetConnection(dbNoAcc)->SetTableExists(tableName);
00397         break;
00398       }
00399         stmtDb->PrintExceptions();
00400    }
00401   }
00402 
00403   if ( dbNoAcc < 0 ) {
00404     if ( stmtDb.get()) stmtDb->PrintExceptions();
00405     return -1;
00406   }
00407 
00408 // Make connection permanent if not already.
00409   TDbiConnection& conDb = *fConnections[dbNoAcc];
00410   if ( conDb.IsTemporary() ) {
00411     conDb.SetPermanent();
00412     SK_DBI_Info( "Making connection: " << conDb.GetUrl()
00413                            << " permanent to preserve temporary tables." << "  ");
00414   }
00415 
00416 // Create SQL to create auxillary validity table and write to same Db.
00417   sqlMakeTable = TDbi::GetVldDescr(tableName.c_str(),true);
00418 
00419   SK_DBI_Log( "Validity Table creation: "
00420                          << " Database: " << dbNoAcc << " "
00421                          << sqlMakeTable << "  ");
00422   stmtDb->ExecuteUpdate(sqlMakeTable.c_str());
00423   if ( stmtDb->PrintExceptions() ) return -1;
00424   this->GetConnection(dbNoAcc)->SetTableExists(tableName+"VLD");
00425   fTemporaryTables[tableName] = dbNoAcc;
00426   return dbNoAcc;
00427 
00428 }

Here is the call graph for this function:

Int_t TDbiCascader::GetAuthorisingDbNo (  )  const [inline]

Definition at line 92 of file TDbiCascader.hxx.

References fGlobalSeqNoDbNo.

00092 { return fGlobalSeqNoDbNo; }

TDbiConnection * TDbiCascader::GetConnection ( UInt_t  dbNo  ) 

Purpose: Return a connection to caller (TDbiCascader retains ownership)

Definition at line 447 of file TDbiCascader.cxx.

References fConnections, GetStatus(), and kFailed.

00447                                                        {
00448 
00449 
00450   if ( this->GetStatus(dbNo) == kFailed ) return 0;
00451   return fConnections[dbNo];
00452 
00453 }

Here is the call graph for this function:

const TDbiConnection * TDbiCascader::GetConnection ( UInt_t  dbNo  )  const

Return associated TDbiConnection. TDbiCascader retains ownership.

Purpose: Return a connection to caller (TDbiCascader retains ownership)

Definition at line 435 of file TDbiCascader.cxx.

References fConnections, GetStatus(), and kFailed.

Referenced by CreateTemporaryTable(), GetTableDbNo(), TDbiDBProxy::ReplaceSeqNo(), and TDbiDBProxy::StoreMetaData().

00435                                                                   {
00436 
00437 
00438   if ( this->GetStatus(dbNo) == kFailed ) return 0;
00439   return fConnections[dbNo];
00440 
00441 }

Here is the call graph for this function:

Here is the caller graph for this function:

string TDbiCascader::GetDbName ( UInt_t  dbNo  )  const

Purpose: Return Database Name for cascade entry number.

Definition at line 458 of file TDbiCascader.cxx.

References fConnections, GetNumDb(), and SK_DBI_Warn.

Referenced by GetDbNo().

00458                                                 {
00459 //
00460 //
00461 
00462   string dbName;
00463 
00464   if ( dbNo < this->GetNumDb() ) dbName = fConnections[dbNo]->GetDbName();
00465   else SK_DBI_Warn( "Database does not contain entry " << dbNo << "  ");
00466   return dbName;
00467 
00468 }

Here is the call graph for this function:

Here is the caller graph for this function:

Int_t TDbiCascader::GetDbNo ( const string &  dbName  )  const

Purpose: Return number of first DB in cascade with name dbName.

Return: Database number corresponding to dbName or -1 if none.

Definition at line 476 of file TDbiCascader.cxx.

References fConnections, GetDbName(), GetNumDb(), and SK_DBI_Warn.

00476                                                       {
00477 
00478 
00479   for ( unsigned dbNo = 0; dbNo < this->GetNumDb(); ++dbNo) {
00480     if ( dbName == fConnections[dbNo]->GetDbName() ) return dbNo;
00481   }
00482 
00483   SK_DBI_Warn( "Database does not contain entry " << dbName << "  ");
00484   return -1;
00485 
00486 }

Here is the call graph for this function:

UInt_t TDbiCascader::GetNumDb (  )  const [inline]

Definition at line 93 of file TDbiCascader.hxx.

References fConnections.

Referenced by TDbiDatabaseManager::Config(), GetDbName(), GetDbNo(), TDbiDBProxy::GetNumDb(), GetStatus(), GetURL(), operator<<(), TDbiDBProxy::StoreMetaData(), and ~TDbiCascader().

00093 {return fConnections.size();}

Here is the caller graph for this function:

Int_t TDbiCascader::GetStatus ( UInt_t  dbNo  )  const [inline]

Definition at line 79 of file TDbiCascader.hxx.

References fConnections, GetNumDb(), kClosed, kFailed, and kOpen.

Referenced by CreateStatement(), GetConnection(), and GetStatusAsString().

00079                                             {
00080                  if ( dbNo >= GetNumDb() || ! fConnections[dbNo]  ) return kFailed;
00081                  return fConnections[dbNo]->IsClosed() ? kClosed : kOpen; }

Here is the call graph for this function:

Here is the caller graph for this function:

string TDbiCascader::GetStatusAsString ( UInt_t  dbNo  )  const

Purpose: Return DB connection status as a string.

Arguments: dbNo in Database number (0..GetNumDb()-1)

Definition at line 495 of file TDbiCascader.cxx.

References GetStatus(), kClosed, and kOpen.

Referenced by operator<<().

00495                                                         {
00496 
00497 
00498   Int_t status = GetStatus(dbNo);
00499 
00500   switch ( status ) {
00501   case kClosed:  return "Closed";
00502   case kOpen:    return "Open  ";
00503   default:       return "Failed";
00504   }
00505 
00506 }

Here is the call graph for this function:

Here is the caller graph for this function:

Int_t TDbiCascader::GetTableDbNo ( const string &  tableName,
Int_t  selectDbNo = -1 
) const

Purpose: Return cascade number of first database that holds table or -1 if none.

Definition at line 512 of file TDbiCascader.cxx.

References fConnections, GetConnection(), and TDbiConnection::TableExists().

Referenced by TDbiSqlValPacket::SetMetaData(), and TableExists().

00513                                                                  {
00514 
00515 
00516 // If selectDbNo >= 0 only look in this entry in the cascade.
00517 
00518 // If table name has any lower case letters then fail.
00519   string::const_iterator itr    = tableName.begin();
00520   string::const_iterator itrEnd = tableName.end();
00521   while ( itr != itrEnd ) if ( islower(*itr++) ) return -1;
00522 
00523 // Loop over cascade looking for table.
00524 
00525   for (UInt_t dbNoTry = 0; dbNoTry < fConnections.size(); ++dbNoTry ) {
00526     if ( selectDbNo >= 0 && (UInt_t) selectDbNo != dbNoTry ) continue;
00527     const TDbiConnection* con =  this->GetConnection(dbNoTry);
00528     if ( con && con->TableExists(tableName) ) return dbNoTry;
00529   }
00530 
00531   return -1;
00532 
00533 }

Here is the call graph for this function:

Here is the caller graph for this function:

string TDbiCascader::GetURL ( UInt_t  dbNo  )  const [inline]

Definition at line 83 of file TDbiCascader.hxx.

References fConnections, and GetNumDb().

Referenced by operator<<(), and TDbiLogEntry::SetServerName().

00083                                          {
00084                       return ( dbNo < GetNumDb() ) ? fConnections[dbNo]-> GetUrl(): ""; }

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiCascader::HoldConnections (  ) 
   
     Purpose: Hold temporary connections open
   
     Specification:-
     =============
   
     Hold all connections open by telling them that they have a
     connected statement.
   
     Program Notes:-
     =============
   
     See TDbiConnectionMaintainer for use.
   

Definition at line 550 of file TDbiCascader.cxx.

References fConnections.

00550                                    {
00551 
00552 
00553   for (UInt_t dbNo = 0; dbNo < fConnections.size(); ++dbNo )
00554     fConnections[dbNo]->ConnectStatement();
00555 }

Bool_t TDbiCascader::IsTemporaryTable ( const string &  tableName,
Int_t  dbNo 
) const

Purpose: Return kTRUE if tableName is temporary in cascade member dbNo.

Definition at line 559 of file TDbiCascader.cxx.

References fTemporaryTables.

Referenced by AllocateSeqNo(), and ReserveNextSeqNo().

00560                                                        {
00561 //
00562 //
00563 
00564 
00565   map<string,Int_t>::const_iterator itr
00566                                      = fTemporaryTables.find(tableName);
00567   return (     itr != fTemporaryTables.end()
00568            &&  (*itr).second == dbNo );
00569 
00570 }

Here is the caller graph for this function:

void TDbiCascader::ReleaseConnections (  ) 
   
     Purpose: Release temporary connections held open by HoldConnections.
   
   
     Specification:-
     =============
   
     Undo HoldConnections() by telling all connections that they no longer
    have a connected statement.
   
     Program Notes:-
     =============
   
     See TDbiConnectionMaintainer for use.
   

Definition at line 665 of file TDbiCascader.cxx.

References fConnections.

Referenced by TDbiConnectionMaintainer::~TDbiConnectionMaintainer().

00665                                       {
00666 
00667 
00668   for (UInt_t dbNo = 0; dbNo < fConnections.size(); ++dbNo )
00669     fConnections[dbNo]->DisConnectStatement();
00670 }

Here is the caller graph for this function:

Int_t TDbiCascader::ReserveNextSeqNo ( const string &  tableName,
Bool_t  isGlobal,
UInt_t  dbNo 
) const [private]
   
     Purpose:  Reserve the next higher available unique (either locally or globally) SEQNO.
               in the appropriate SEQNO table.
   
     Arguments:
      tableName       in    The table for which the SEQNO is required.
      isGlobal        in    = true - reserve in GLOBALSEQNO table(dbNo must be authorizing)
                            = false - reserve in LOCALSEQNO table (creating if required)
      dbNo            in    The entry in the cascade holding the SEQNO table.
   
     Return:    The allocated SEQNO or 0 if failure.
   
     Contact:   N. West
   
     Program Notes:-
     =============
   
     Requests for local SEQNOs may result in the creation of a LOCALSEQNO table.
   

Definition at line 692 of file TDbiCascader.cxx.

References TDbiString::c_str(), TDbiString::Clear(), CreateStatement(), TDbiCascader::Lock::IsLocked(), IsTemporaryTable(), TDbi::kMAXLOCALSEQNO, SK_DBI_Log, SK_DBI_Severe, and TableExists().

Referenced by AllocateSeqNo().

00694                                                        {
00695 
00696 
00697   TDbiString sql;
00698 
00699   string seqnoTableName = isGlobal ? "GLOBALSEQNO" : "LOCALSEQNO";
00700   bool seqnoTableNameExists = this->TableExists(seqnoTableName,dbNo);
00701   bool tableNameExists      = this->TableExists(tableName,dbNo);
00702 
00703   auto_ptr<TDbiStatement> stmtDb(this->CreateStatement(dbNo) );
00704   if ( ! stmtDb.get() ) return 0;
00705 
00706   // Check that required SEQNO table exists.
00707 
00708   if ( isGlobal ) {
00709     if ( ! seqnoTableNameExists ) {
00710          SK_DBI_Severe( "Unable to issue global SEQNO - " << dbNo
00711                                << " is not an authorising DB" << "  ");
00712       return 0;
00713     }
00714   }
00715   else {
00716     if ( ! seqnoTableNameExists ) {
00717       sql.Clear();
00718       sql << "CREATE TABLE " << seqnoTableName
00719           << "(TABLENAME      CHAR(64) NOT NULL PRIMARY KEY,\n"
00720           << " LASTUSEDSEQNO  INT )";
00721 
00722       SK_DBI_Log( "Database: " << dbNo
00723                              << " create local SEQNO table query: " << sql.c_str() << "  ");
00724       stmtDb->ExecuteUpdate(sql.c_str());
00725       if ( stmtDb->PrintExceptions() ) return 0;
00726       sql.Clear();
00727       sql << "INSERT INTO " <<  seqnoTableName << " VALUES ('*',0)";
00728       SK_DBI_Log( "Database: " << dbNo
00729                              << " prime local SEQNO table query: " << sql.c_str() << "  ");
00730       stmtDb->ExecuteUpdate(sql.c_str());
00731       if ( stmtDb->PrintExceptions() ) return 0;
00732     }
00733   }
00734 
00735 // Lock seqno table by creating a lock object on the stack.
00736 // Table will be unlocked when lock object destroyed.
00737 
00738   string dataTable;
00739 // Only pass in table name if it's not temporary and exists in
00740 // the selected DB otherwise Lock will try to lock a non-existent table.
00741   if (  ! this->IsTemporaryTable(tableName,dbNo)
00742        && tableNameExists ) dataTable = tableName;
00743   Lock lock(this->CreateStatement(dbNo),seqnoTableName,dataTable);
00744   if ( ! lock.IsLocked() ) {
00745        SK_DBI_Severe( "Unable to lock " << seqnoTableName << "  ");
00746     return 0;
00747   }
00748 
00749 // Find row containing last used SeqNo for this table.
00750 // Not that comparison is case insensitive.
00751   sql.Clear();
00752   sql << "select * from " << seqnoTableName << " where TABLENAME = '*' or TABLENAME = '";
00753   sql << tableName + "' order by TABLENAME";
00754   SK_DBI_Log( " query: " << sql.c_str() << "  ");
00755   TSQLStatement* stmt = stmtDb->ExecuteQuery(sql.c_str());
00756 
00757   Int_t seqNoDefault = 0;
00758   if ( stmt && stmt->NextResultRow() ) {
00759     seqNoDefault = stmt->GetInt(1);
00760   }
00761   else {
00762        SK_DBI_Severe( "Unable to find default SeqNo"
00763                            << " due to above error" << "  ");
00764     delete stmt;
00765     stmt = 0;
00766     return 0;
00767   }
00768   Int_t seqNoTable = seqNoDefault;
00769   if ( stmt->NextResultRow() ) {
00770     seqNoTable = stmt->GetInt(1);
00771   }
00772   delete stmt;
00773   stmt = 0;
00774   SK_DBI_Log( "  query returned last used seqno: " << seqNoTable << "  ");
00775 
00776 //  If the table exists, make sure that the seqNo hasn't already been used.
00777 //  This is paranoia code and expensive, so only do the check once for
00778 //  each tableName/isGlobal/dbNo combination.
00779 
00780   static std::string checkedCombinations;
00781   ostringstream combination;
00782   combination << ":" << tableName << isGlobal << dbNo << ":";
00783   bool notChecked = checkedCombinations.find(combination.str()) == std::string::npos;
00784   if ( notChecked ) checkedCombinations += combination.str();
00785   if ( tableNameExists && notChecked ) {
00786     Int_t seqNoMin = seqNoDefault;
00787     Int_t seqNoMax = seqNoDefault + TDbi::kMAXLOCALSEQNO;
00788     sql.Clear();
00789     sql << "select max(SEQNO) from " << tableName << "VLD"
00790         << " where SEQNO between " << seqNoMin << " and " << seqNoMax;
00791     SK_DBI_Log( "Database: " << dbNo
00792                          << " max  SEQNO query: " << sql.c_str() << "  ");
00793     stmt  =  stmtDb->ExecuteQuery(sql.c_str());
00794     if ( stmtDb->PrintExceptions() ) return 0;
00795     Int_t  minValue = 0;
00796     // Queries returning group function results can be null.
00797     if (  stmt && stmt->NextResultRow() && ! stmt->IsNull(0) ) {
00798       minValue = stmt->GetInt(0);
00799      if ( minValue <= 0 ) minValue = 0;  // Should never happen.
00800     }
00801     delete stmt;
00802     stmt = 0;
00803 
00804     if ( minValue > seqNoTable ) {
00805          SK_DBI_Severe(  "Database: " << dbNo << " "
00806           << seqnoTableName << " has last used SEQNO of "
00807           << seqNoTable << " for table " << tableName
00808           << ",\n    but the highest SEQNO in the band " << seqNoMin << " to " << seqNoMax
00809           << " is " <<  minValue << " for that table\n    "
00810           << seqnoTableName << " is out of date! It will be updated for " << tableName << "  ");
00811         seqNoTable = minValue;
00812     }
00813   }
00814 
00815 
00816 //  Update last used SeqNo and record in table.
00817   sql.Clear();
00818   sql << "delete from " << seqnoTableName << " where TABLENAME='";
00819   sql << tableName + "'";
00820   SK_DBI_Log( "SEQNO entry removal: " << sql.c_str() << "  ");
00821   stmtDb->ExecuteUpdate(sql.c_str());
00822   if ( stmtDb->PrintExceptions() ) return 0;
00823 
00824   seqNoTable++;
00825 
00826   sql.Clear();
00827   sql << "insert into  " << seqnoTableName << " values('";
00828   sql << tableName + "'," << seqNoTable << ")";
00829   SK_DBI_Log( "SEQNO entry add: " << sql.c_str() << "  ");
00830   stmtDb->ExecuteUpdate(sql.c_str());
00831   if ( stmtDb->PrintExceptions() ) return 0;
00832 
00833   return seqNoTable;
00834 
00835 }

Here is the call graph for this function:

Here is the caller graph for this function:

void TDbiCascader::SetAuthorisingEntry ( Int_t  entry  )  [inline, private]

Definition at line 113 of file TDbiCascader.hxx.

References fGlobalSeqNoDbNo.

00113 {fGlobalSeqNoDbNo = entry;}

void TDbiCascader::SetPermanent ( UInt_t  dbNo,
Bool_t  permanent = true 
)

Purpose: Set connection permanent.

Definition at line 838 of file TDbiCascader.cxx.

References fConnections.

Referenced by TDbiDatabaseManager::Config().

00839                                                                {
00840 //
00841 //
00842 
00843 
00844   if ( dbNo < fConnections.size() ) fConnections[dbNo]->SetPermanent(permanent);
00845 
00846 }

Here is the caller graph for this function:

Bool_t TDbiCascader::TableExists ( const string &  tableName,
Int_t  selectDbNo = -1 
) const [inline]

Definition at line 95 of file TDbiCascader.hxx.

References GetTableDbNo().

Referenced by TDbiSqlValPacket::Recreate(), ReserveNextSeqNo(), and TDbiDBProxy::TableExists().

00095                                                                                  {
00096                             return this->GetTableDbNo(tableName,selectDbNo) >= 0; }

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

ostream& operator<< ( ostream &  s,
const TDbiCascader cascader 
) [friend]
friend class TDbiDatabaseManager [friend]

Definition at line 51 of file TDbiCascader.hxx.

friend class TDbiValidate [friend]

Definition at line 60 of file TDbiCascader.hxx.


Member Data Documentation

1st db in cascade with GlobalSeqNo table

Definition at line 123 of file TDbiCascader.hxx.

Referenced by AllocateSeqNo(), GetAuthorisingDbNo(), operator<<(), and SetAuthorisingEntry().

std::map<string,Int_t> TDbiCascader::fTemporaryTables [private]

Mapping Name->DbNo for temporary tables.

Definition at line 129 of file TDbiCascader.hxx.

Referenced by CreateTemporaryTable(), and IsTemporaryTable().


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

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1