#include <DbiConnection.h>
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 DbiExceptionLog & | GetExceptionLog () 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). | |
DatabaseInterface
Contact: n.west1@physics.ox.ac.uk
Definition at line 45 of file DbiConnection.h.
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
Definition at line 72 of file DbiConnection.h. Referenced by Close(), and Open(). 00072 { fExceptionLog.Clear(); }
|
|
|
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 }
|
|
|
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 }
|
|
|
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(); }
|
|
|
Increment number of statements relying on this connection.
Definition at line 92 of file DbiConnection.h. Referenced by DbiCascader::HoldConnections(). 00092 { ++fNumConnectedStatements; }
|
|
|
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 }
|
|
|
Definition at line 89 of file DbiConnection.h. Referenced by DbiDBProxy::StoreMetaData(). 00089 { this->DisConnectStatement(); }
|
|
|
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(); }
|
|
|
Definition at line 60 of file DbiConnection.h. Referenced by DbiStatement::ExecuteQuery(), DbiStatement::ExecuteUpdate(), and DbiCascader::GetDbName(). 00060 { return fDbName; }
|
|
|
Definition at line 61 of file DbiConnection.h. Referenced by DTFtest(), and DbiDBProxy::ReplaceSeqNo(). 00061 { return fDbType; }
|
|
|
Definition at line 71 of file DbiConnection.h. Referenced by DbiStatement::AppendExceptionLog(). 00071 { return fExceptionLog; }
|
|
|
Definition at line 62 of file DbiConnection.h. 00062 { return fPassword; }
|
|
|
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 }
|
|
|
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 }
|
|
|
Definition at line 64 of file DbiConnection.h. 00064 { return fUser; }
|
|
|
Definition at line 65 of file DbiConnection.h. Referenced by Close(), and Open(). 00065 { return ! fServer; }
|
|
|
Definition at line 66 of file DbiConnection.h. Referenced by DbiCascader::CreateTemporaryTable(). 00066 { return fIsTemporary; }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
Connection is permanent, don't close even when idle.
Definition at line 98 of file DbiConnection.h. Referenced by DbiCascader::CreateTemporaryTable(). 00098 { fIsTemporary = ! permanent; }
|
|
|
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 }
|
|
|
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 }
|
|
|
Database Name.
Definition at line 120 of file DbiConnection.h. |
|
|
Type of database (MySQL, Oracle).
Definition at line 151 of file DbiConnection.h. |
|
|
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(). |
|
|
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(). |
|
|
Connection closes after each I/O (no connections left).
Definition at line 141 of file DbiConnection.h. Referenced by CloseIdleConnection(), and Open(). |
|
|
Number of connected statements.
Definition at line 138 of file DbiConnection.h. |
|
|
Password.
Definition at line 132 of file DbiConnection.h. Referenced by Open(). |
|
|
TSQLServer or 0 if closed.
Definition at line 144 of file DbiConnection.h. |
|
|
TSQLServer URL.
Definition at line 126 of file DbiConnection.h. Referenced by Open(). |
|
|
True if URL works.
Definition at line 135 of file DbiConnection.h. Referenced by Open(). |
|
|
Username.
Definition at line 129 of file DbiConnection.h. Referenced by Open(). |
1.3.9.1