DbiCascader Class Reference

#include <DbiCascader.h>

List of all members.

Classes

class  Lock

Public Types

enum  Status { kFailed, kClosed, kOpen }

Public Member Functions

DbiStatementCreateStatement (UInt_t dbNo) const
 Create a DbiStatement. Caller must delete.
const DbiConnectionGetConnection (UInt_t dbNo) const
 Return associated DbiConnection. DbiCascader retains ownership.
DbiConnectionGetConnection (UInt_t dbNo)
string GetDbName (UInt_t dbNo) const
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
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)

Private Member Functions

Int_t ReserveNextSeqNo (const string &tableName, Bool_t isGlobal, UInt_t dbNo) const
void SetAuthorisingEntry (Int_t entry)
 DbiCascader ()
virtual ~DbiCascader ()
 DbiCascader (const DbiCascader &)

Private Attributes

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

Friends

class DbiTableProxyRegistry
class DbiValidate
ostream & operator<< (ostream &s, const DbiCascader &cascader)

Detailed Description

Id
DbiCascader.h,v 1.28 2008/08/22 10:27:29 nwest Exp

Definition at line 51 of file DbiCascader.h.


Member Enumeration Documentation

Enumerator:
kFailed 
kClosed 
kOpen 

Definition at line 61 of file DbiCascader.h.

00061 { kFailed, kClosed, kOpen };


Constructor & Destructor Documentation

DbiCascader::DbiCascader (  )  [private]

Definition at line 38 of file DbiCascader.cxx.

References exit(), gSystem(), Msg::kFatal, Msg::kInfo, Msg::kVerbose, LEA_CTOR, MSG, DbiConnection::Open(), and UtilString::StringTok().

00038                         :
00039 fGlobalSeqNoDbNo(-1)
00040 {
00041 //
00042 //
00043 //  Purpose:  Default constructor
00044 //
00045 //  Arguments:
00046 //
00047 //  Return:    n/a
00048 //
00049 //  Contact:   N. West
00050 //
00051 //  Specification:-
00052 //  =============
00053 //
00054 //  o  Create Cascader.
00055 
00056 
00057 //  Program Notes:-
00058 //  =============
00059 
00060 //  Current cascader configuration comes from 3 environmental
00061 //  variables:-
00062 //
00063 //    ENV_TSQL_URL             a semi-colon separated list of URLs
00064 //    ENV_TSQL_USER            user name (one or a semi-colon separated list)
00065 //    ENV_TSQL_PSWD            password (one or a semi-colon separated list)
00066 //   
00067 //    or the _UPDATE alternatives e.g. ENV_TSQL_UPDATE_USER
00068 //   
00069 // The _UPDATE versions take priority.
00070 
00071   LEA_CTOR    //Leak Checker
00072 
00073   MSG("Dbi", Msg::kVerbose) << "Creating DbiCascader" << endl;
00074 
00075 // Extract args from  ENV_TSQL environmental variables
00076   const char*      strUser = gSystem->Getenv("ENV_TSQL_UPDATE_USER");
00077   if ( ! strUser ) strUser = gSystem->Getenv("ENV_TSQL_USER");
00078   const char*      strPswd = gSystem->Getenv("ENV_TSQL_UPDATE_PSWD");
00079   if ( ! strPswd ) strPswd = gSystem->Getenv("ENV_TSQL_PSWD");
00080   const char*       strUrl = gSystem->Getenv("ENV_TSQL_UPDATE_URL");
00081   if ( !strUrl )    strUrl = gSystem->Getenv("ENV_TSQL_URL");
00082   string userList     = ( strUser ) ? strUser : "";
00083   string pswdList     = ( strPswd ) ? strPswd : "";
00084   string urlList      = ( strUrl  ) ? strUrl  : "";
00085 
00086   if ( urlList == "" || userList == "" || pswdList == "" ) {
00087      MSG("Dbi",Msg::kFatal) 
00088         << "Cannnot open a Database cascade;\n"
00089         << "   the environmental variables ENV_TSQL_*:-" << endl
00090         << "USER: \"" << userList << "\" PSWD:\"" << pswdList 
00091         << "\" URL:\"" << urlList << endl
00092         << " are either not defined or empty.\n"
00093         << "   Please check your settings of ENV_TSQL_USER,"
00094         << " ENV_TSQL_PSWD and ENV_TSQL_URL\n" 
00095         << "Aborting due to above errors" << endl;
00096       exit(1);
00097   }
00098 
00099   std::vector<std::string> users, pswds, urls;
00100   UtilString::StringTok(users, userList, ";");
00101   UtilString::StringTok(pswds, pswdList, ";");
00102   UtilString::StringTok(urls,  urlList,  ";");
00103 
00104   bool fail = false;
00105 
00106   for (unsigned entry = 0; entry < urls.size(); ++entry ) { 
00107     string url  = urls[entry];
00108     string user = ( entry >= users.size() ) ? users[0] : users[entry];
00109     string pswd = ( entry >= pswds.size() ) ? pswds[0] : pswds[entry];
00110 
00111     // Handle empty password designated as '\0' (an empty null terminated character string)
00112     if ( pswd == "\\0" ) pswd = "";
00113 
00114     DbiConnection* con = new DbiConnection(url,user,pswd);
00115     fConnections.push_back(con);
00116     if ( ! con->Open() ) {
00117       fail = true;
00118       continue;
00119     }
00120 
00121 //  Attempt to locate first GlobalSeqNo/GLOBALSEQNO table.
00122     if ( fGlobalSeqNoDbNo != -1 ) continue;
00123     auto_ptr<DbiStatement>  stmtDb(new DbiStatement(*con));
00124     if ( ! stmtDb.get() ) continue;
00125     TSQLStatement* stmt = stmtDb->ExecuteQuery("Select * from GLOBALSEQNO where 1=0");
00126     if ( stmt ) {
00127       fGlobalSeqNoDbNo = fConnections.size()-1;
00128       delete stmt;
00129       stmt = 0;
00130     }
00131    
00132 //  Check for presence of a DBI_STATE_FLAG table
00133 
00134     if ( this->GetTableDbNo("DBI_STATE_FLAGS",entry) != -1 ) {
00135       MSG("Dbi",Msg::kFatal) << "  POSSIBLE VERSION SHEAR DETECTED !!!\n"
00136         << "    The DBI_STATE_FLAGS table is present on cascade entry " << entry << ".  This table will\n"
00137         << "    only be introduced to manage backward incompatible changes that could lead\n"
00138         << "    to version shear between the code and the database.  This version of the\n"
00139         << "    code does not support the change the presence of that table indicates\n"
00140         << "    so has to shut down. \n";
00141         fail = true;
00142     }
00143   }
00144 
00145   MSG("Dbi",Msg::kInfo) << *this;
00146  
00147 //  Abort, if there have been any failures.
00148   if ( fail ) {
00149     MSG("Dbi",Msg::kFatal)
00150         << "Aborting due to above errors" << endl;
00151     exit(1);
00152   }
00153 
00154 }

DbiCascader::~DbiCascader (  )  [private, virtual]

Definition at line 158 of file DbiCascader.cxx.

References fConnections, GetNumDb(), Msg::kVerbose, LEA_DTOR, and MSG.

00158                           {
00159 //
00160 //
00161 //  Purpose: Destructor
00162 //
00163 
00164   LEA_DTOR    //Leak Checker
00165 
00166   MSG("Dbi", Msg::kVerbose) << "Destroying DbiCascader" << endl;
00167 
00168   for (Int_t dbNo = this->GetNumDb()-1; dbNo >= 0; --dbNo) delete fConnections[dbNo];
00169 
00170 }

DbiCascader::DbiCascader ( const DbiCascader  )  [private]

Member Function Documentation

Int_t DbiCascader::AllocateSeqNo ( const string &  tableName,
Int_t  requireGlobal = 0,
Int_t  dbNo = 0 
) const

Definition at line 212 of file DbiCascader.cxx.

References fGlobalSeqNoDbNo, IsTemporaryTable(), Msg::kWarning, MSG, and ReserveNextSeqNo().

Referenced by DbiWriter< T >::Close(), DbiLogEntry::Write(), and DbiConfigStream::Write().

00214                                                               {
00215 //
00216 //
00217 //  Purpose:  Allocate a unique (either locally or globally) SEQNO.
00218 //
00219 //  Arguments: 
00220 //   tableName       in    The table for which the SEQNO is required.
00221 //   requireGlobal   in    The type of SEQNO required:-
00222 //                           > 0  Must be global
00223 //                           = 0  Must be global if supplied dbNo is authorising
00224 //                                and table isn't temporary otherwise local
00225 //                           < 0  Must be local
00226 //   dbNo            in     The entry in the cascade for which the SEQNO is required
00227 // 
00228 //  Return:    The allocated SEQNO or 0 if failure.
00229 //
00230 //  Contact:   N. West
00231 
00232 //  Program Notes:-
00233 //  =============
00234 
00235 //  Requests for SEQNOs take account of any pre-existing entries; local entries
00236 //  should only be used for development and this allows for the LOCALSEQNO table 
00237 //  and the local data to be wiped at different times without causing conflicts.
00238 //  Global entries should not be a problem as the GLOBALSEQNO table isn't wiped
00239 //  but it provides protection in case the table is damaged (which has happened!).
00240 
00241   bool isTemporary = IsTemporaryTable(tableName,dbNo);
00242 
00243   //  Deal with global requests.
00244 
00245   if (     requireGlobal > 0
00246       || ( requireGlobal == 0 && dbNo == fGlobalSeqNoDbNo && ! isTemporary ) ) {
00247     if ( fGlobalSeqNoDbNo < 0 ) {
00248       MSG("Dbi",Msg::kWarning) << "Unable to issue global SEQNO - no authorising DB in cascade\n"
00249                                << "  will issue local one instead" << endl;
00250     }
00251     else if ( isTemporary ) {
00252       MSG("Dbi",Msg::kWarning) << "Unable to issue global SEQNO - " << tableName << " is temporary\n"
00253                                << "  will issue local one instead" << endl;
00254     }
00255     else return this->ReserveNextSeqNo(tableName,true,fGlobalSeqNoDbNo);
00256   }
00257 
00258   // Deal with local requests
00259 
00260   return this->ReserveNextSeqNo(tableName,false,dbNo);
00261 
00262 }

DbiStatement * DbiCascader::CreateStatement ( UInt_t  dbNo  )  const

Create a DbiStatement. Caller must delete.

Definition at line 266 of file DbiCascader.cxx.

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

Referenced by DbuDaqFileModule::BeginJob(), createSpillTables(), InfoChain::CreateTables(), PhotonStatSummarizer::CreateTables(), CreateTemporaryTable(), DbmValidate::DbmValidate(), DTFtest(), DbiDBProxy::FindTimeBoundaries(), DbmModule::Import(), DbuDaqMonitorModule::InitTSQLConnection(), DbmModule::ListTables(), DbiDBProxy::QueryAllValidities(), DbiDBProxy::QuerySeqNo(), DbiDBProxy::QuerySeqNos(), DbiDBProxy::QueryValidity(), DbiDBProxy::RemoveSeqNo(), DbiDBProxy::ReplaceInsertDate(), DbiDBProxy::ReplaceSeqNo(), DbiDBProxy::ReplaceSeqNoOracle(), and ReserveNextSeqNo().

00266                                                             {
00267 //
00268 //
00269 //  Purpose:  Return a Statement to caller.
00270 //
00271 //  Arguments: 
00272 //    dbNo     in    Database no. in cascade for which statement
00273 //                   is required.
00274 //
00275 //  Return:    Created statement (or 0 if creation failed). 
00276 //             User must delete.
00277 //  Program Notes:-
00278 //  =============
00279 
00280 //  As the caller is responsible for destroying the statement after use
00281 //  consider:-
00282 //  
00283 //  #include <memory>
00284 //  using std::auto_ptr;
00285 //  
00286 //  ...
00287 //  
00288 //  auto_ptr<DbiStatement> stmt(cascader.CreateStatement(dbNo));
00289 
00290 
00291   if ( this->GetStatus(dbNo) == kFailed ) return 0;
00292   DbiConnection& conDb = *fConnections[dbNo];
00293   DbiStatement* stmtDb = new DbiStatement(conDb);
00294   stmtDb->PrintExceptions();
00295   return stmtDb;
00296 
00297 }

Int_t DbiCascader::CreateTemporaryTable ( const string &  tableName,
const string &  tableDescr 
)

Definition at line 300 of file DbiCascader.cxx.

References CreateStatement(), fConnections, fTemporaryTables, GetConnection(), DbiConnection::GetUrl(), Dbi::GetVldDescr(), MsgService::Instance(), DbiConnection::IsTemporary(), Msg::kError, Msg::kInfo, Msg::kSynopsis, MAXMSG, MSG, DbiConnection::SetPermanent(), DbiConnection::SetTableExists(), and UtilString::ToUpper().

Referenced by DetailedTimeCal(), load_better_mipcal(), load_mc_mipcal(), LoadBeamMomentum(), LoadCERRange(), LoadCERTimeWin(), LoadOverlapWin(), LoadTOFRange(), main(), MakeFilterChannelList(), UgliGeometryReroot::MakeTempDbiGeometry(), UgliGeometryReroot::MakeTempDbiPosInfo(), UgliGeometryReroot::MakeTempDbiScintStruct(), MakeTimeCal(), AutoPIDMaker::Reco(), FillSpillServerMon::WriteToDatabase(), FillFarRunQuality::WriteToDatabase(), FillHvFromSingles::WriteToDatabase(), and FillNearRunQuality::WriteToDatabase().

00301                                                                  {
00302 //
00303 //
00304 //  Purpose:  Creat temporary table with associated validity table
00305 //
00306 //  Arguments: 
00307 //    tableNameMc  in    Table name
00308 //    tableDescr   in    Table description as parenthesised comma 
00309 //                       separated list e.g.:-
00310 //                       "(MyInt int, MyFloat float, MyString text)"
00311 //
00312 //  Return:    The database cascade number on which the table was
00313 //             created or = -1 if unable to create.
00314 //
00315 //  Contact:   N. West
00316 //
00317 //  Specification:-
00318 //  =============
00319 //
00320 //  o Loop over all databases in cascade, starting at the highest
00321 //    priority i.e. entry 0 and find the first that will accept create 
00322 //    temporary table requests.  Return -1 if none will.
00323 //
00324 //  o Make connection permanent so that temporary data won't be lost.
00325 //
00326 //  o Generate and submit requests to create temporary table with
00327 //    associated validity table and return the cascade number of
00328 //    the database that has accepted the tables, recording table
00329 //    name in fTemporaryTables.
00330 //
00331 
00332   
00333 //  Check that input args look plausible.
00334 
00335   string tableName = UtilString::ToUpper(tableNameMc);
00336   if (    tableName == "" 
00337        || tableDescr[0] != '(' 
00338        || tableDescr[tableDescr.size()-1] != ')' ) {
00339     MAXMSG("Dbi",Msg::kError,20) << "Illegal input args:-" << endl
00340                            << "     Table Name: " << tableName
00341                            << "  Table Description: " << tableDescr
00342                            <<endl;
00343     return -1;
00344   }
00345   
00346 // Find a DB that will accept the command.
00347   string sqlMakeTable;
00348 
00349   Int_t dbNoAcc       = -1;
00350   auto_ptr<DbiStatement> stmtDb; 
00351   for (UInt_t dbNoTry = 0; dbNoTry < fConnections.size(); ++dbNoTry ) {
00352     stmtDb.reset(this->CreateStatement(dbNoTry));    
00353     if ( stmtDb.get() ) {
00354       sqlMakeTable = " create temporary table ";
00355       sqlMakeTable += tableName;
00356       sqlMakeTable += " ";
00357       sqlMakeTable += tableDescr;
00358       sqlMakeTable += ";";
00359       stmtDb->ExecuteUpdate(sqlMakeTable.c_str());
00360       if ( stmtDb->GetExceptionLog().IsEmpty() ) {
00361         dbNoAcc = dbNoTry;
00362         this->GetConnection(dbNoAcc)->SetTableExists(tableName);
00363         break;
00364       }
00365       if ( MsgService::Instance()->IsActive("Dbi",Msg::kSynopsis) )stmtDb->PrintExceptions();
00366    }
00367   }
00368 
00369   if ( dbNoAcc < 0 ) {
00370     if ( stmtDb.get()) stmtDb->PrintExceptions();
00371     return -1;
00372   }
00373 
00374 // Make connection permanent if not already.
00375   DbiConnection& conDb = *fConnections[dbNoAcc];
00376   if ( conDb.IsTemporary() ) {
00377     conDb.SetPermanent();
00378     MSG("Dbi",Msg::kInfo)  << "Making connection: " << conDb.GetUrl() 
00379                            << " permanent to preserve temporary tables." << endl;
00380   }
00381 
00382 // Create SQL to create auxillary validity table and write to same Db.
00383   sqlMakeTable = Dbi::GetVldDescr(tableName.c_str(),true);
00384 
00385   MSG("Dbi",Msg::kSynopsis) << "Validity Table creation: "
00386                          << " Database: " << dbNoAcc << " "
00387                          << sqlMakeTable << endl;
00388   stmtDb->ExecuteUpdate(sqlMakeTable.c_str());
00389   if ( stmtDb->PrintExceptions() ) return -1;
00390   this->GetConnection(dbNoAcc)->SetTableExists(tableName+"VLD");
00391   fTemporaryTables[tableName] = dbNoAcc;
00392   return dbNoAcc;
00393 
00394 }

Int_t DbiCascader::GetAuthorisingDbNo (  )  const [inline]

Definition at line 91 of file DbiCascader.h.

References fGlobalSeqNoDbNo.

Referenced by DbiWriter< T >::WritingToMaster().

00091 { return fGlobalSeqNoDbNo; }

DbiConnection * DbiCascader::GetConnection ( UInt_t  dbNo  ) 

Definition at line 410 of file DbiCascader.cxx.

References fConnections, GetStatus(), and kFailed.

00410                                                      {
00411 //
00412 //
00413 //  Purpose:  Return a connection to caller (DbiCascader retains ownership)
00414 
00415 
00416   if ( this->GetStatus(dbNo) == kFailed ) return 0;
00417   return fConnections[dbNo];
00418 
00419 }

const DbiConnection * DbiCascader::GetConnection ( UInt_t  dbNo  )  const

Return associated DbiConnection. DbiCascader retains ownership.

Definition at line 398 of file DbiCascader.cxx.

References fConnections, GetStatus(), and kFailed.

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

00398                                                                 {
00399 //
00400 //
00401 //  Purpose:  Return a connection to caller (DbiCascader retains ownership)
00402 
00403 
00404   if ( this->GetStatus(dbNo) == kFailed ) return 0;
00405   return fConnections[dbNo];
00406 
00407 }

string DbiCascader::GetDbName ( UInt_t  dbNo  )  const

Definition at line 424 of file DbiCascader.cxx.

References fConnections, GetNumDb(), Msg::kWarning, and MSG.

Referenced by GetDbNo().

00424                                                {
00425 //
00426 //
00427 //  Purpose:  Return Database Name for cascade entry number.
00428 
00429   string dbName;
00430 
00431   if ( dbNo < this->GetNumDb() ) dbName = fConnections[dbNo]->GetDbName();
00432   else MSG("Dbi",Msg::kWarning) << "Database does not contain entry " << dbNo << endl;
00433   return dbName;
00434 
00435 }

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

Definition at line 439 of file DbiCascader.cxx.

References fConnections, GetDbName(), GetNumDb(), Msg::kWarning, and MSG.

Referenced by DbiWriter< T >::SetDbName().

00439                                                      {
00440 //
00441 //
00442 //  Purpose:  Return number of first DB in cascade with name dbName.
00443 //
00444 //  Return:   Database number corresponding to dbName or -1 if none.   
00445 
00446   for ( unsigned dbNo = 0; dbNo < this->GetNumDb(); ++dbNo) {
00447     if ( dbName == fConnections[dbNo]->GetDbName() ) return dbNo;
00448   }
00449 
00450   MSG("Dbi",Msg::kWarning) << "Database does not contain entry " << dbName << endl;
00451   return -1;
00452 
00453 }

UInt_t DbiCascader::GetNumDb (  )  const [inline]
Int_t DbiCascader::GetStatus ( UInt_t  dbNo  )  const [inline]

Definition at line 78 of file DbiCascader.h.

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

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

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

string DbiCascader::GetStatusAsString ( UInt_t  dbNo  )  const

Definition at line 457 of file DbiCascader.cxx.

References GetStatus(), kClosed, and kOpen.

Referenced by operator<<().

00457                                                        {
00458 //
00459 //
00460 //  Purpose:  Return DB connection status as a string.
00461 //
00462 //  Arguments: 
00463 //    dbNo         in    Database number (0..GetNumDb()-1)
00464 
00465   Int_t status = GetStatus(dbNo);
00466 
00467   switch ( status ) {
00468   case kClosed:  return "Closed";
00469   case kOpen:    return "Open  ";
00470   default:       return "Failed";
00471   }
00472 
00473 }

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

Definition at line 476 of file DbiCascader.cxx.

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

Referenced by DbmModule::LogEntry(), DbiSqlValPacket::SetMetaData(), and TableExists().

00477                                                                  {
00478 //
00479 //
00480 //  Purpose:  Return cascade number of first database that holds table 
00481 //            or -1 if none.
00482 
00483 // If selectDbNo >= 0 only look in this entry in the cascade.
00484 
00485 // If table name has any lower case letters then fail.  
00486 // Lower case are not allowed by ORACLE which kindly 
00487 // converts to upper case so SQL would pass if upper case version
00488 // exists.
00489   string::const_iterator itr    = tableName.begin();
00490   string::const_iterator itrEnd = tableName.end();
00491   while ( itr != itrEnd ) if ( islower(*itr++) ) return -1;
00492 
00493 // Loop over cascade looking for table.
00494 
00495   for (UInt_t dbNoTry = 0; dbNoTry < fConnections.size(); ++dbNoTry ) {
00496     if ( selectDbNo >= 0 && (UInt_t) selectDbNo != dbNoTry ) continue;
00497     const DbiConnection* con =  this->GetConnection(dbNoTry);
00498     if ( con && con->TableExists(tableName) ) return dbNoTry;
00499   }
00500 
00501   return -1;
00502 
00503 }

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

Definition at line 82 of file DbiCascader.h.

References fConnections, and GetNumDb().

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

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

void DbiCascader::HoldConnections (  ) 

Definition at line 506 of file DbiCascader.cxx.

References fConnections.

00506                                   {
00507 //
00508 //
00509 //  Purpose: Hold temporary connections open 
00510 
00511 //  Specification:-
00512 //  =============
00513 
00514 //  Hold all connections open by telling them that they have a 
00515 //  connected statement. 
00516 
00517 //  Program Notes:-
00518 //  =============
00519 
00520 //  See DbiConnectionMaintainer for use.
00521 
00522   for (UInt_t dbNo = 0; dbNo < fConnections.size(); ++dbNo ) 
00523     fConnections[dbNo]->ConnectStatement();
00524 }

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

Definition at line 528 of file DbiCascader.cxx.

References fTemporaryTables.

Referenced by AllocateSeqNo(), ReserveNextSeqNo(), and DbiWriter< T >::WritingToMaster().

00529                                                        {
00530 //
00531 //
00532 //  Purpose:  Return kTRUE if tableName is temporary in cascade member dbNo
00533 
00534   map<string,Int_t>::const_iterator itr
00535                                      = fTemporaryTables.find(tableName);
00536   return (     itr != fTemporaryTables.end() 
00537            &&  (*itr).second == dbNo );
00538 
00539 }

void DbiCascader::ReleaseConnections (  ) 

Definition at line 626 of file DbiCascader.cxx.

References fConnections.

Referenced by DbiConnectionMaintainer::~DbiConnectionMaintainer().

00626                                      {
00627 //
00628 //
00629 //  Purpose: Release temporary connections held open by HoldConnections. 
00630 
00631 
00632 //  Specification:-
00633 //  =============
00634 
00635 //  Undo HoldConnections() by telling all connections that they no longer
00636 // have a connected statement.
00637 
00638 //  Program Notes:-
00639 //  =============
00640 
00641 //  See DbiConnectionMaintainer for use.
00642 
00643   for (UInt_t dbNo = 0; dbNo < fConnections.size(); ++dbNo ) 
00644     fConnections[dbNo]->DisConnectStatement();
00645 }

Int_t DbiCascader::ReserveNextSeqNo ( const string &  tableName,
Bool_t  isGlobal,
UInt_t  dbNo 
) const [private]

Definition at line 648 of file DbiCascader.cxx.

References DbiString::c_str(), DbiString::Clear(), CreateStatement(), DbiCascader::Lock::IsLocked(), IsTemporaryTable(), Msg::kDebug, Msg::kError, Dbi::kMAXLOCALSEQNO, Msg::kSynopsis, MAXMSG, MSG, and TableExists().

Referenced by AllocateSeqNo().

00650                                                        {
00651 //
00652 //
00653 //  Purpose:  Reserve the next higher available unique (either locally or globally) SEQNO.
00654 //            in the appropriate SEQNO table.
00655 //
00656 //  Arguments: 
00657 //   tableName       in    The table for which the SEQNO is required.
00658 //   isGlobal        in    = true - reserve in GLOBALSEQNO table(dbNo must be authorizing)
00659 //                         = false - reserve in LOCALSEQNO table (creating if required)
00660 //   dbNo            in    The entry in the cascade holding the SEQNO table.
00661 //
00662 //  Return:    The allocated SEQNO or 0 if failure.
00663 //
00664 //  Contact:   N. West
00665 
00666 //  Program Notes:-
00667 //  =============
00668 
00669 //  Requests for local SEQNOs may result in the creation of a LOCALSEQNO table.
00670 
00671   DbiString sql;
00672 
00673   string seqnoTableName = isGlobal ? "GLOBALSEQNO" : "LOCALSEQNO";
00674   bool seqnoTableNameExists = this->TableExists(seqnoTableName,dbNo);
00675   bool tableNameExists      = this->TableExists(tableName,dbNo);
00676 
00677   auto_ptr<DbiStatement> stmtDb(this->CreateStatement(dbNo) );
00678   if ( ! stmtDb.get() ) return 0;
00679 
00680   // Check that required SEQNO table exists.
00681 
00682   if ( isGlobal ) {
00683     if ( ! seqnoTableNameExists ) {
00684       MAXMSG("Dbi",Msg::kError,20) << "Unable to issue global SEQNO - " << dbNo
00685                                << " is not an authorising DB" << endl;
00686       return 0;
00687     }
00688   }
00689   else {
00690     if ( ! seqnoTableNameExists ) {
00691       sql.Clear();
00692       sql << "CREATE TABLE " << seqnoTableName 
00693           << "(TABLENAME      CHAR(64) NOT NULL PRIMARY KEY,\n"
00694           << " LASTUSEDSEQNO  INT )";
00695 
00696       MSG("Dbi",Msg::kSynopsis) << "Database: " << dbNo
00697                              << " create local SEQNO table query: " << sql.c_str() << endl;
00698       stmtDb->ExecuteUpdate(sql.c_str());
00699       if ( stmtDb->PrintExceptions() ) return 0;
00700       sql.Clear();
00701       sql << "INSERT INTO " <<  seqnoTableName << " VALUES ('*',0)";
00702       MSG("Dbi",Msg::kSynopsis) << "Database: " << dbNo
00703                              << " prime local SEQNO table query: " << sql.c_str() << endl;
00704       stmtDb->ExecuteUpdate(sql.c_str());
00705       if ( stmtDb->PrintExceptions() ) return 0;
00706     }
00707   }
00708  
00709 // Lock seqno table by creating a lock object on the stack.
00710 // Table will be unlocked when lock object destroyed.
00711 
00712   string dataTable;
00713 // Only pass in table name if it's not temporary and exists in
00714 // the selected DB otherwise Lock will try to lock a non-existent table.
00715   if (  ! this->IsTemporaryTable(tableName,dbNo)
00716        && tableNameExists ) dataTable = tableName;
00717   Lock lock(this->CreateStatement(dbNo),seqnoTableName,dataTable);
00718   if ( ! lock.IsLocked() ) {
00719     MAXMSG("Dbi",Msg::kError,20) << "Unable to lock " << seqnoTableName << endl;
00720     return 0;
00721   }
00722 
00723 // Find row containing last used SeqNo for this table.
00724 // Not that comparison is case insensitive.
00725   sql.Clear();
00726   sql << "select * from " << seqnoTableName << " where TABLENAME = '*' or TABLENAME = '";
00727   sql << tableName + "' order by TABLENAME";
00728   MSG("Dbi",Msg::kSynopsis) << seqnoTableName << " query: " << sql.c_str() << endl;
00729   TSQLStatement* stmt = stmtDb->ExecuteQuery(sql.c_str());
00730   stmtDb->PrintExceptions(Msg::kDebug);
00731   Int_t seqNoDefault = 0;
00732   if ( stmt && stmt->NextResultRow() ) {
00733     seqNoDefault = stmt->GetInt(1);
00734   }
00735   else {
00736     MAXMSG("Dbi",Msg::kError,20) << "Unable to find default SeqNo"
00737                            << " due to above error" << endl;
00738     delete stmt;
00739     stmt = 0;
00740     return 0;
00741   }
00742   Int_t seqNoTable = seqNoDefault;
00743   if ( stmt->NextResultRow() ) {
00744     seqNoTable = stmt->GetInt(1);
00745   }
00746   delete stmt;
00747   stmt = 0;
00748   MSG("Dbi",Msg::kSynopsis) << "  query returned last used seqno: " << seqNoTable << endl;
00749 
00750 //  If the table exists, make sure that the seqNo hasn't already been used.
00751 //  This is paranoia code and expensive, so only do the check once for
00752 //  each tableName/isGlobal/dbNo combination.
00753 
00754   static std::string checkedCombinations;
00755   ostringstream combination;
00756   combination << ":" << tableName << isGlobal << dbNo << ":";
00757   bool notChecked = checkedCombinations.find(combination.str()) == std::string::npos;
00758   if ( notChecked ) checkedCombinations += combination.str();
00759   if ( tableNameExists && notChecked ) {
00760     Int_t seqNoMin = seqNoDefault;
00761     Int_t seqNoMax = seqNoDefault + Dbi::kMAXLOCALSEQNO;
00762     sql.Clear();
00763     sql << "select max(SEQNO) from " << tableName << "VLD"
00764         << " where SEQNO between " << seqNoMin << " and " << seqNoMax;
00765     MSG("Dbi",Msg::kSynopsis) << "Database: " << dbNo
00766                          << " max  SEQNO query: " << sql.c_str() << endl;
00767     stmt  =  stmtDb->ExecuteQuery(sql.c_str());
00768     if ( stmtDb->PrintExceptions() ) return 0;
00769     Int_t  minValue = 0;
00770     // Queries returning group function results can be null.
00771     if (  stmt && stmt->NextResultRow() && ! stmt->IsNull(0) ) {
00772       minValue = stmt->GetInt(0);
00773      if ( minValue <= 0 ) minValue = 0;  // Should never happen.
00774     }
00775     delete stmt;
00776     stmt = 0;
00777 
00778     if ( minValue > seqNoTable ) {
00779       MAXMSG("Dbi",Msg::kError,20) 
00780           << "Database: " << dbNo << " "
00781           << seqnoTableName << " has last used SEQNO of "
00782           << seqNoTable << " for table " << tableName
00783           << ",\n    but the highest SEQNO in the band " << seqNoMin << " to " << seqNoMax
00784           << " is " <<  minValue << " for that table\n    "
00785           << seqnoTableName << " is out of date! It will be updated for " << tableName << endl;
00786         seqNoTable = minValue;
00787     }
00788   }
00789 
00790   
00791 //  Update last used SeqNo and record in table.
00792   sql.Clear();
00793   sql << "delete from " << seqnoTableName << " where TABLENAME='";
00794   sql << tableName + "'";
00795   MSG("Dbi",Msg::kSynopsis) << "SEQNO entry removal: " << sql.c_str() << endl;
00796   stmtDb->ExecuteUpdate(sql.c_str());
00797   if ( stmtDb->PrintExceptions() ) return 0;
00798 
00799   seqNoTable++;
00800 
00801   sql.Clear();
00802   sql << "insert into  " << seqnoTableName << " values('";
00803   sql << tableName + "'," << seqNoTable << ")";
00804   MSG("Dbi",Msg::kSynopsis) << "SEQNO entry add: " << sql.c_str() << endl;
00805   stmtDb->ExecuteUpdate(sql.c_str());
00806   if ( stmtDb->PrintExceptions() ) return 0;
00807 
00808   return seqNoTable;
00809 
00810 }

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

Definition at line 112 of file DbiCascader.h.

References fGlobalSeqNoDbNo.

00112 {fGlobalSeqNoDbNo = entry;}

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

Definition at line 813 of file DbiCascader.cxx.

References fConnections.

Referenced by DbiTableProxyRegistry::Config(), and main().

00814                                                                {
00815 //
00816 //
00817 //  Purpose: Set connection permanent. 
00818 
00819   if ( dbNo < fConnections.size() ) fConnections[dbNo]->SetPermanent(permanent);
00820 
00821 }

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

Friends And Related Function Documentation

friend class DbiTableProxyRegistry [friend]

Definition at line 54 of file DbiCascader.h.

friend class DbiValidate [friend]

Definition at line 59 of file DbiCascader.h.

ostream& operator<< ( ostream &  s,
const DbiCascader cascader 
) [friend]

Member Data Documentation

1st db in cascade with GlobalSeqNo table

Definition at line 122 of file DbiCascader.h.

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

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

Mapping Name->DbNo for temporary tables.

Definition at line 128 of file DbiCascader.h.

Referenced by CreateTemporaryTable(), and IsTemporaryTable().


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

Generated on 22 Nov 2017 for loon by  doxygen 1.6.1