Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DbiConnection Class Reference

Concept A managed TSQLServer connection- dropped when idle. Purpose To minimise connections, particularly to ORACLE servers where connections cost money! More...

#include <DbiConnection.h>

List of all members.

Public Member Functions

 DbiConnection (const std::string &url="", const std::string &user="", const std::string &password="")
virtual ~DbiConnection ()
const std::string & GetDbName () const
Dbi::DbTypes GetDbType () const
const std::string & GetPassword () const
const std::string & GetUrl () const
const std::string & GetUser () const
Bool_t IsClosed () const
Bool_t IsTemporary () const
Bool_t TableExists (const std::string &tableName) const
const DbiExceptionLogGetExceptionLog () const
void ClearExceptionLog ()
Bool_t PrintExceptionLog (Int_t level=3) const
 Print exceptions at level of above and return true if any.
void RecordException ()
void SetTableExists (const std::string &tableName="")
void Connect ()
 Methods used when "borrowing" the server (use same as for Statement).
void DisConnect ()
void ConnectStatement ()
 Increment number of statements relying on this connection.
void DisConnectStatement ()
 Decrement number of statements relying on this connection and close if idle.
void SetPermanent (Bool_t permanent=true)
 Connection is permanent, don't close even when idle.
Bool_t Close (Bool_t force=false)
Bool_t Open ()
TSQLServer * GetServer ()
TSQLStatement * CreatePreparedStatement (const std::string &sql)

Private Member Functions

void CloseIdleConnection ()

Private Attributes

std::string fDbName
 Database Name.
std::string fExistingTableList
 A comma separate list of existing tables each in single quotes : 'table1','table2',...
TUrl fUrl
 TSQLServer URL.
std::string fUser
 Username.
std::string fPassword
 Password.
Bool_t fUrlValidated
 True if URL works.
Int_t fNumConnectedStatements
 Number of connected statements.
Bool_t fIsTemporary
 Connection closes after each I/O (no connections left).
TSQLServer * fServer
 TSQLServer or 0 if closed.
DbiExceptionLog fExceptionLog
Dbi::DbTypes fDbType
 Type of database (MySQL, Oracle).


Detailed Description

Concept A managed TSQLServer connection- dropped when idle. Purpose To minimise connections, particularly to ORACLE servers where connections cost money!

Id
DbiConnection.h,v 1.16 2008/08/22 10:27:38 nwest Exp

DatabaseInterface

Contact: n.west1@physics.ox.ac.uk

Definition at line 45 of file DbiConnection.h.


Constructor & Destructor Documentation

DbiConnection::DbiConnection const std::string &  url = "",
const std::string &  user = "",
const std::string &  password = ""
 

Definition at line 40 of file DbiConnection.cxx.

References LEA_CTOR, MAXMSG, and MSG.

00042                                                                    :
00043 
00044 fUrl(url.c_str()),
00045 fUser(user),
00046 fPassword(password),
00047 fUrlValidated(false),
00048 fNumConnectedStatements(0),
00049 fIsTemporary(true),
00050 fServer(0),
00051 fDbType(Dbi::kUnknownDbType)
00052 {
00053 //
00054 //
00055 //  Purpose:  Default constructor
00056 
00057   LEA_CTOR    //Leak Checker
00058 
00059   MSG("Dbi", Msg::kVerbose) << "Creating DbiConnection" << endl;
00060 
00061   if ( this->Open() ) {
00062     MSG("Dbi",Msg::kInfo) 
00063           << "Successfully opened connection to: " << this->GetUrl() << endl;
00064     fUrlValidated =  true;
00065 
00066     // Initialise the list existing supported tables.
00067     this->SetTableExists();
00068 
00069     string productName(fServer->GetDBMS());
00070     if      ( productName == "MySQL"    ) fDbType = Dbi::kMySQL;   
00071     else if ( productName == "Oracle"   ) fDbType = Dbi::kOracle;
00072     else {
00073        MAXMSG("Dbi",Msg::kError,20) 
00074          << "Cannot determine DB type from name: " <<  productName 
00075          << "\nWill assume MySQL, but it will probably end in tears!" << endl;
00076       fDbType = Dbi::kMySQL;
00077     }
00078 
00079     //  If URL looks O.K., check that both client and server support prepared statements.
00080     if ( fUrlValidated ) {
00081 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,9)
00082       if ( ! fServer->HasStatement() ) {
00083 #else
00084       if ( ! fServer->IsSupportStatement() ) {
00085 #endif
00086         MSG("Dbi",Msg::kError) << "  This client does not support prepared statements." << endl;
00087         fUrlValidated = false;
00088       }
00089       std::string serverInfo(fServer->ServerInfo());
00090       if ( fDbType == Dbi::kMySQL &&  serverInfo < "4.1" ) {
00091         MSG("Dbi",Msg::kError) << "This MySQL server (" << serverInfo
00092                              << ") does not support prepared statements." << endl;
00093         fUrlValidated = false;
00094       }
00095       if ( fUrlValidated ) {
00096         MSG("Dbi",Msg::kInfo) << "This client, and MySQL server (" << serverInfo
00097                              << ") does support prepared statements." << endl;
00098       }
00099       else {
00100 
00101         MSG("Dbi",Msg::kError) << "\n"
00102            << "This version of MySQL does not support prepared statements.\n"
00103            << "\n"
00104            << "Please upgrade to MySQL (client and server) version 4.1 or greater \n"
00105            << "\n"
00106            << endl;
00107       }
00108 
00109     }
00110     if ( ! fUrlValidated ) {
00111       MSG("Dbi",Msg::kFatal) << "Aborting due to above errors" << endl;
00112       exit(1);
00113     }
00114 
00115   }
00116 
00117   fDbName = fUrl.GetFile();
00118 
00119 }

DbiConnection::~DbiConnection  )  [virtual]
 

Definition at line 123 of file DbiConnection.cxx.

References Close(), LEA_DTOR, and MSG.

00123                               {
00124 //
00125 //
00126 //  Purpose: Destructor
00127 
00128   LEA_DTOR    //Leak Checker
00129 
00130   MSG("Dbi", Msg::kVerbose) << "Destroying DbiConnection" << endl;
00131   this->Close(true);
00132 
00133 }


Member Function Documentation

void DbiConnection::ClearExceptionLog  )  [inline]
 

Definition at line 72 of file DbiConnection.h.

Referenced by Close(), and Open().

00072 { fExceptionLog.Clear(); }

Bool_t DbiConnection::Close Bool_t  force = false  ) 
 

Definition at line 136 of file DbiConnection.cxx.

References ClearExceptionLog(), GetUrl(), IsClosed(), and MSG.

Referenced by CloseIdleConnection(), and ~DbiConnection().

00136                                                        {
00137 //
00138 //
00139 //  Purpose: Close server connection unless active (or always if forced) . 
00140 //
00141 //  Return:  true if connection now closed. 
00142 
00143   this->ClearExceptionLog();
00144   if ( this->IsClosed() ) return true;
00145 
00146   if ( fNumConnectedStatements ) {
00147     if ( ! force ) {
00148       MSG("Dbi",Msg::kInfo) << "Unable to close connection: " << this->GetUrl()
00149                             << "; it still has  "
00150                             << fNumConnectedStatements << "active statements. " << endl;
00151       return false;
00152     }
00153     MSG("Dbi",Msg::kInfo) << "Closing connection: " << this->GetUrl()
00154                           << "; even though it still has "
00155                           << fNumConnectedStatements << " active statements. " << endl;
00156   }
00157 
00158   delete fServer;
00159   fServer = 0;
00160   MSG("Dbi",Msg::kDebug)  << "Closed connection: " << this->GetUrl() << endl;
00161   return true;
00162 
00163 }

void DbiConnection::CloseIdleConnection  )  [private]
 

Definition at line 167 of file DbiConnection.cxx.

References Close(), and fIsTemporary.

00167                                         {
00168 //
00169 //
00170 //  Purpose:  Close idle connection.
00171 
00172   if ( fIsTemporary &&  fNumConnectedStatements == 0 ) this->Close();
00173 
00174 }

void DbiConnection::Connect  )  [inline]
 

Methods used when "borrowing" the server (use same as for Statement).

Definition at line 88 of file DbiConnection.h.

Referenced by DbiDBProxy::StoreMetaData().

00088 { this->ConnectStatement(); }

void DbiConnection::ConnectStatement  )  [inline]
 

Increment number of statements relying on this connection.

Definition at line 92 of file DbiConnection.h.

Referenced by DbiCascader::HoldConnections().

00092 { ++fNumConnectedStatements; }

TSQLStatement * DbiConnection::CreatePreparedStatement const std::string &  sql  ) 
 

Get statement, opening if necessary. Caller must take ownership.

Definition at line 179 of file DbiConnection.cxx.

References DbiExceptionLog::AddEntry(), fExceptionLog, and Open().

Referenced by DbiStatement::CreateProcessedStatement(), and SetTableExists().

00179                                                                           {
00180 //
00181 //
00182 //  Purpose:  Open if necessary and get a prepared statment.
00183 //
00184 //  Return:    Statement - Caller must take ownership.
00185 //             will be 0 if failure.
00186 
00187   TSQLStatement* stmt = 0;
00188   if ( ! this->Open() ) return stmt;
00189   stmt = fServer->Statement(sql.c_str());
00190   if ( ! stmt ) {
00191     fExceptionLog.AddEntry(*fServer);
00192   }
00193   else stmt->EnableErrorOutput(false);
00194 
00195   return stmt;
00196 }

void DbiConnection::DisConnect  )  [inline]
 

Definition at line 89 of file DbiConnection.h.

Referenced by DbiDBProxy::StoreMetaData().

00089 { this->DisConnectStatement(); }

void DbiConnection::DisConnectStatement  )  [inline]
 

Decrement number of statements relying on this connection and close if idle.

Definition at line 94 of file DbiConnection.h.

Referenced by DbiStatement::~DbiStatement().

00094                              {
00095        --fNumConnectedStatements;
00096       if ( ! fNumConnectedStatements ) this->CloseIdleConnection(); }

const std::string& DbiConnection::GetDbName  )  const [inline]
 

Definition at line 60 of file DbiConnection.h.

Referenced by DbiStatement::ExecuteQuery(), DbiStatement::ExecuteUpdate(), and DbiCascader::GetDbName().

00060 { return fDbName; }

Dbi::DbTypes DbiConnection::GetDbType  )  const [inline]
 

Definition at line 61 of file DbiConnection.h.

Referenced by DTFtest(), and DbiDBProxy::ReplaceSeqNo().

00061 { return fDbType; }

const DbiExceptionLog& DbiConnection::GetExceptionLog  )  const [inline]
 

Definition at line 71 of file DbiConnection.h.

Referenced by DbiStatement::AppendExceptionLog().

00071 { return fExceptionLog; }

const std::string& DbiConnection::GetPassword  )  const [inline]
 

Definition at line 62 of file DbiConnection.h.

00062 { return fPassword; }

TSQLServer * DbiConnection::GetServer  ) 
 

Get server, opening if necessary DbiConnection retains ownership

Definition at line 199 of file DbiConnection.cxx.

References Open().

Referenced by DbiStatement::ExecuteUpdate(), and DbiDBProxy::StoreMetaData().

00199                                      {
00200 //
00201 //
00202 //  Purpose:  Open if necessary and get a TSQLServer.
00203 //
00204 //  Return:    Server ( = 0 if connection not open).
00205 //
00206 //  WARNING:  The server returned remains is being borrowed from the
00207 //            DbiConnection and remains under its ownership and must
00208 //            not be deleted.  However the caller must invoke the
00209 //            Connect() method on this DbiConnection before borrowing
00210 //            it and must invoke the DisConnect() when it has finished
00211 //            using it to ensure the DbiConnection does not close it
00212 //            prematurely i.e.:-
00213 //
00214 //            void Demo(DbiConnection* con) {
00215 //              con->Connect();
00216 //              TSQLServer* server = con->GetServer();
00217 //              // Do stuff
00218 //              con->DisConnect();
00219 //            }
00220 
00221   if ( ! this->Open() ) return 0;
00222   return fServer;
00223 }

const std::string & DbiConnection::GetUrl  )  const
 

Definition at line 226 of file DbiConnection.cxx.

Referenced by Close(), and DbiCascader::CreateTemporaryTable().

00226                                              {
00227 
00228   // Don't ask me why TUrl::GetUrl() is non-const, just accept that it is!
00229 
00230   // Note: This function returns a reference to a shared string; use the
00231   //       value or make a copy of it before any subsequent call to this
00232   //       function.
00233 
00234   static std::string url;
00235   url = const_cast<DbiConnection*>(this)->fUrl.GetUrl();
00236   return url;
00237 
00238 }

const std::string& DbiConnection::GetUser  )  const [inline]
 

Definition at line 64 of file DbiConnection.h.

00064 { return fUser; }

Bool_t DbiConnection::IsClosed  )  const [inline]
 

Definition at line 65 of file DbiConnection.h.

Referenced by Close(), and Open().

00065 { return ! fServer; }

Bool_t DbiConnection::IsTemporary  )  const [inline]
 

Definition at line 66 of file DbiConnection.h.

Referenced by DbiCascader::CreateTemporaryTable().

00066 { return fIsTemporary; }

Bool_t DbiConnection::Open  ) 
 

Definition at line 242 of file DbiConnection.cxx.

References DbiExceptionLog::AddEntry(), DbiServices::AsciiDBConectionsTemporary(), ClearExceptionLog(), fExceptionLog, fIsTemporary, fPassword, fUrl, fUrlValidated, fUser, DbiAsciiDbImporter::GetExceptionLog(), DbiAsciiDbImporter::GetImportedTableNames(), gSystem(), IsClosed(), MAXMSG, MSG, and SetTableExists().

Referenced by CreatePreparedStatement(), DbiCascader::DbiCascader(), and GetServer().

00242                            {
00243 //
00244 //  Purpose:  Open connection if necessary.
00245 //
00246 
00247   this->ClearExceptionLog();
00248   if ( ! this->IsClosed() ) return true;
00249 
00250   if ( ! fUrl.IsValid() ) {
00251     ostringstream oss;
00252     oss << "Unable to open connection: URL '" << fUrl.GetUrl() << "' is invalid";
00253     MAXMSG("Dbi",Msg::kError,20) << oss.str() << endl;
00254     fExceptionLog.AddEntry(oss.str());
00255     return false;
00256   }
00257 
00258   // Make several attempts (or more if URL is known to be O.K.) to open connection.
00259   int maxAttempt = fUrlValidated ? 100 : 20; 
00260   for (int attempt = 1; attempt <= maxAttempt; ++attempt) {
00261     fServer = TSQLServer::Connect(fUrl.GetUrl(),fUser.c_str(),fPassword.c_str()); 
00262     if ( ! fServer ) {
00263       ostringstream oss;
00264       oss << "Failing to open: " << fUrl.GetUrl() << " for user " << fUser
00265           << " and password " << fPassword << " (attempt " << attempt << ")";
00266       fExceptionLog.AddEntry(oss.str());
00267       if ( attempt == 1 ) {
00268         MAXMSG("Dbi",Msg::kError,20) << oss.str() << " retrying ... " << endl;
00269       }
00270       gSystem->Sleep(attempt*1000);
00271     }
00272 
00273     else {
00274       fServer->EnableErrorOutput(false);
00275       if ( attempt > 1 ) MSG("Dbi",Msg::kWarning)  << "... Connection opened on attempt " << attempt << endl;
00276       MSG("Dbi",Msg::kDebug)
00277         << "Successfully opened connection to: " << fUrl.GetUrl() << endl;
00278 
00279       // If this is an ASCII database, populate it and make the connection permanent
00280       // unless even ASCII DB connections are temporary.
00281 
00282       TString ascii_file = fUrl.GetAnchor();
00283       if ( ascii_file.IsNull() ) return true;
00284       gSystem->Setenv("DBI_CATALOGUE_PATH",gSystem->DirName(fUrl.GetAnchor()));
00285       DbiAsciiDbImporter importer(ascii_file,fServer);
00286       const DbiExceptionLog& el(importer.GetExceptionLog());
00287       if ( ! el.IsEmpty() ) {
00288         MSG("Dbi",Msg::kError) << "Failed to populate ASCII database from " << fUrl.GetUrl() << "\n"
00289                                << el << endl;
00290         delete fServer;
00291         fServer = 0;
00292         return false;
00293       }
00294       fIsTemporary = DbiServices::AsciiDBConectionsTemporary();
00295       // Add imported tables names.
00296       const std::list<std::string> tableNames(importer.GetImportedTableNames());
00297       std::list<std::string>::const_iterator itr(tableNames.begin()), itrEnd(tableNames.end());
00298       while ( itr != itrEnd ) {
00299         this->SetTableExists(*itr);
00300         ++itr;
00301       }
00302       return true;
00303 
00304     }
00305   }
00306   MAXMSG("Dbi",Msg::kError,20) 
00307     << "... Failed to open a connection to: " << fUrl.GetUrl() 
00308     << " for user " << fUser << " and pwd " << fPassword << endl;
00309  
00310   return false;
00311 
00312 }

Bool_t DbiConnection::PrintExceptionLog Int_t  level = 3  )  const
 

Print exceptions at level of above and return true if any.

Definition at line 316 of file DbiConnection.cxx.

References fExceptionLog, MSG, and DbiExceptionLog::Size().

00316                                                          {
00317 //
00318 //
00319 //  Purpose:  Print all warning at supplied  Msg log level.
00320 //
00321 //  Return:    kTRUE if warnings have occurred
00322 
00323   MSG("Dbi",level) << fExceptionLog;
00324   return fExceptionLog.Size() != 0;
00325 
00326 }

void DbiConnection::RecordException  ) 
 

Definition at line 330 of file DbiConnection.cxx.

References DbiExceptionLog::AddEntry(), and fExceptionLog.

Referenced by DbiStatement::ExecuteUpdate().

00330                                      {
00331 //
00332 //  Purpose:  Record an exception that has occurred while a client was using its TSQLServer.
00333 
00334   fExceptionLog.AddEntry(*fServer);
00335 
00336 }

void DbiConnection::SetPermanent Bool_t  permanent = true  )  [inline]
 

Connection is permanent, don't close even when idle.

Definition at line 98 of file DbiConnection.h.

Referenced by DbiCascader::CreateTemporaryTable().

00098 { fIsTemporary = ! permanent; }

void DbiConnection::SetTableExists const std::string &  tableName = ""  ) 
 

Add name to list of existing tables (necessary when creating tables) Default name = "", reread all tables from database.

Definition at line 340 of file DbiConnection.cxx.

References CreatePreparedStatement(), fExistingTableList, and TableExists().

Referenced by DbiCascader::CreateTemporaryTable(), DTFtest(), and Open().

00340                                                               {
00341 //
00342 //  Purpose: Add name to list of existing tables (necessary when creating tables) 
00343 //
00344 //  Note: If tableName is null refresh list from the database.
00345 
00346   if ( tableName == "" ) {
00347     TSQLStatement* stmt =  CreatePreparedStatement("show tables");
00348     if ( stmt ) {
00349       if (stmt->Process()) {
00350         stmt->StoreResult();
00351         while (stmt->NextResultRow()) {
00352           std::string tn(stmt->GetString(0));
00353           this->SetTableExists(tn);
00354         }
00355       }
00356       delete stmt;
00357       stmt = 0;
00358     }
00359   }
00360   else {
00361     if ( ! this->TableExists(tableName) ) {
00362       fExistingTableList += ",'";
00363       fExistingTableList += tableName;
00364       fExistingTableList += "'";
00365     }
00366   }
00367 }

Bool_t DbiConnection::TableExists const std::string &  tableName  )  const
 

Definition at line 371 of file DbiConnection.cxx.

References fExistingTableList.

Referenced by DbiCascader::GetTableDbNo(), and SetTableExists().

00371                                                                    {
00372 //
00373 //  Purpose: Check to see table exists in connected database.
00374 
00375   std::string test("'");
00376   test += tableName;
00377   test += "'";
00378   return fExistingTableList.find(test) != std::string::npos;
00379 }


Member Data Documentation

std::string DbiConnection::fDbName [private]
 

Database Name.

Definition at line 120 of file DbiConnection.h.

Dbi::DbTypes DbiConnection::fDbType [private]
 

Type of database (MySQL, Oracle).

Definition at line 151 of file DbiConnection.h.

DbiExceptionLog DbiConnection::fExceptionLog [private]
 

Log of exceptions generated. Cleared by Open Close and (implicitly) by CreatePreparedStatement, GetServer

Definition at line 148 of file DbiConnection.h.

Referenced by CreatePreparedStatement(), Open(), PrintExceptionLog(), and RecordException().

std::string DbiConnection::fExistingTableList [private]
 

A comma separate list of existing tables each in single quotes : 'table1','table2',...

Definition at line 123 of file DbiConnection.h.

Referenced by SetTableExists(), and TableExists().

Bool_t DbiConnection::fIsTemporary [private]
 

Connection closes after each I/O (no connections left).

Definition at line 141 of file DbiConnection.h.

Referenced by CloseIdleConnection(), and Open().

Int_t DbiConnection::fNumConnectedStatements [private]
 

Number of connected statements.

Definition at line 138 of file DbiConnection.h.

std::string DbiConnection::fPassword [private]
 

Password.

Definition at line 132 of file DbiConnection.h.

Referenced by Open().

TSQLServer* DbiConnection::fServer [private]
 

TSQLServer or 0 if closed.

Definition at line 144 of file DbiConnection.h.

TUrl DbiConnection::fUrl [private]
 

TSQLServer URL.

Definition at line 126 of file DbiConnection.h.

Referenced by Open().

Bool_t DbiConnection::fUrlValidated [private]
 

True if URL works.

Definition at line 135 of file DbiConnection.h.

Referenced by Open().

std::string DbiConnection::fUser [private]
 

Username.

Definition at line 129 of file DbiConnection.h.

Referenced by Open().


The documentation for this class was generated from the following files:
Generated on Mon Feb 15 11:09:02 2010 for loon by  doxygen 1.3.9.1