00001 // @(#)root/net:$Id: TSQLServer.cxx 29321 2009-07-03 10:42:10Z brun $ 00002 // Author: Fons Rademakers 25/11/99 00003 00004 /************************************************************************* 00005 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * 00006 * All rights reserved. * 00007 * * 00008 * For the licensing terms see $ROOTSYS/LICENSE. * 00009 * For the list of contributors see $ROOTSYS/README/CREDITS. * 00010 *************************************************************************/ 00011 00012 ////////////////////////////////////////////////////////////////////////// 00013 // // 00014 // TSQLServer // 00015 // // 00016 // Abstract base class defining interface to a SQL server. // 00017 // // 00018 // To open a connection to a server use the static method Connect(). // 00019 // The db argument of Connect() is of the form: // 00020 // <dbms>://<host>[:<port>][/<database>], e.g. // 00021 // mysql://pcroot.cern.ch:3456/test, oracle://srv1.cern.ch/main, ... // 00022 // Depending on the <dbms> specified an appropriate plugin library // 00023 // will be loaded which will provide the real interface. // 00024 // // 00025 // Related classes are TSQLResult and TSQLRow. // 00026 // // 00027 ////////////////////////////////////////////////////////////////////////// 00028 00029 #include "TSQLServer.h" 00030 #include "TSQLResult.h" 00031 #include "TSQLRow.h" 00032 #include "TSQLTableInfo.h" 00033 #include "TSQLColumnInfo.h" 00034 #include "TROOT.h" 00035 #include "TList.h" 00036 #include "TObjString.h" 00037 #include "TPluginManager.h" 00038 #include "TVirtualMutex.h" 00039 00040 ClassImp(TSQLServer) 00041 00042 00043 const char* TSQLServer::fgFloatFmt = "%e"; 00044 00045 00046 //______________________________________________________________________________ 00047 TSQLServer *TSQLServer::Connect(const char *db, const char *uid, const char *pw) 00048 { 00049 // The db should be of the form: <dbms>://<host>[:<port>][/<database>], 00050 // e.g.: mysql://pcroot.cern.ch:3456/test, oracle://srv1.cern.ch/main, 00051 // pgsql://... or sapdb://... 00052 // The uid is the username and pw the password that should be used for 00053 // the connection. Depending on the <dbms> the shared library (plugin) 00054 // for the selected system will be loaded. When the connection could not 00055 // be opened 0 is returned. 00056 00057 TPluginHandler *h; 00058 TSQLServer *serv = 0; 00059 00060 if ((h = gROOT->GetPluginManager()->FindHandler("TSQLServer", db))) { 00061 if (h->LoadPlugin() == -1) 00062 return 0; 00063 serv = (TSQLServer *) h->ExecPlugin(3, db, uid, pw); 00064 } 00065 00066 if (serv && serv->IsZombie()) { 00067 delete serv; 00068 serv = 0; 00069 } 00070 00071 return serv; 00072 } 00073 00074 //______________________________________________________________________________ 00075 Bool_t TSQLServer::Exec(const char* sql) 00076 { 00077 // Execute sql query. 00078 // Usefull for commands like DROP TABLE or INSERT, where result set 00079 // is not interested. Return kTRUE if no error 00080 00081 TSQLResult* res = Query(sql); 00082 if (res==0) return kFALSE; 00083 00084 delete res; 00085 00086 return !IsError(); 00087 } 00088 00089 00090 //______________________________________________________________________________ 00091 Int_t TSQLServer::GetErrorCode() const 00092 { 00093 // returns error code of last operation 00094 // if res==0, no error 00095 // Each specific implementation of TSQLServer provides its own error coding 00096 00097 return fErrorCode; 00098 } 00099 00100 //______________________________________________________________________________ 00101 const char* TSQLServer::GetErrorMsg() const 00102 { 00103 // returns error message of last operation 00104 // if no errors, return 0 00105 // Each specific implementation of TSQLServer provides its own error messages 00106 00107 return GetErrorCode()==0 ? 0 : fErrorMsg.Data(); 00108 } 00109 00110 //______________________________________________________________________________ 00111 void TSQLServer::ClearError() 00112 { 00113 // reset error fields 00114 00115 fErrorCode = 0; 00116 fErrorMsg = ""; 00117 } 00118 00119 //______________________________________________________________________________ 00120 void TSQLServer::SetError(Int_t code, const char* msg, const char* method) 00121 { 00122 // set new values for error fields 00123 // if method is specified, displays error message 00124 00125 fErrorCode = code; 00126 fErrorMsg = msg; 00127 if ((method!=0) && fErrorOut) 00128 Error(method,"Code: %d Msg: %s", code, (msg ? msg : "No message")); 00129 } 00130 00131 //______________________________________________________________________________ 00132 Bool_t TSQLServer::StartTransaction() 00133 { 00134 // submit "START TRANSACTION" query to database 00135 // return kTRUE, if succesfull 00136 00137 return Exec("START TRANSACTION"); 00138 } 00139 00140 //______________________________________________________________________________ 00141 Bool_t TSQLServer::Commit() 00142 { 00143 // submit "COMMIT" query to database 00144 // return kTRUE, if succesfull 00145 00146 return Exec("COMMIT"); 00147 } 00148 00149 //______________________________________________________________________________ 00150 Bool_t TSQLServer::Rollback() 00151 { 00152 // submit "ROLLBACK" query to database 00153 // return kTRUE, if succesfull 00154 00155 return Exec("ROLLBACK"); 00156 } 00157 00158 //______________________________________________________________________________ 00159 TList* TSQLServer::GetTablesList(const char* wild) 00160 { 00161 // Return list of user tables 00162 // Parameter wild specifies wildcard for table names. 00163 // It either contains exact table name to verify that table is exists or 00164 // wildcard with "%" (any number of symbols) and "_" (exactly one symbol). 00165 // Example of vaild wildcards: "%", "%name","___user__". 00166 // If wild=="", list of all available tables will be produced. 00167 // List contain just tables names in the TObjString. 00168 // List must be deleted by the user. 00169 // Example code of method usage: 00170 // 00171 // TList* lst = serv->GetTablesList(); 00172 // TIter next(lst); 00173 // TObject* obj; 00174 // while (obj = next()) 00175 // cout << "Table: " << obj->GetName() << endl; 00176 // delete lst; 00177 00178 TSQLResult* res = GetTables(fDB.Data(), wild); 00179 if (res==0) return 0; 00180 00181 TList* lst = 0; 00182 TSQLRow* row = 0; 00183 while ((row = res->Next())!=0) { 00184 const char* tablename = row->GetField(0); 00185 if (lst==0) { 00186 lst = new TList; 00187 lst->SetOwner(kTRUE); 00188 } 00189 lst->Add(new TObjString(tablename)); 00190 delete row; 00191 } 00192 00193 delete res; 00194 00195 return lst; 00196 } 00197 00198 //______________________________________________________________________________ 00199 Bool_t TSQLServer::HasTable(const char* tablename) 00200 { 00201 // Tests if table of that name exists in database 00202 // Return kTRUE, if table exists 00203 00204 if ((tablename==0) || (strlen(tablename)==0)) return kFALSE; 00205 00206 TList* lst = GetTablesList(tablename); 00207 if (lst==0) return kFALSE; 00208 00209 Bool_t res = kFALSE; 00210 00211 TObject* obj = 0; 00212 TIter iter(lst); 00213 00214 // Can be, that tablename contains "_" or "%" symbols, which are wildcards in SQL, 00215 // therefore more than one table can be returned as result. 00216 // One should check that exactly same name is appears 00217 00218 while ((obj = iter()) != 0) 00219 if (strcmp(tablename, obj->GetName())==0) res = kTRUE; 00220 00221 delete lst; 00222 return res; 00223 } 00224 00225 //______________________________________________________________________________ 00226 TSQLTableInfo* TSQLServer::GetTableInfo(const char* tablename) 00227 { 00228 // Producec TSQLTableInfo object, which contain info about 00229 // table itself and each table column 00230 // Object must be deleted by user. 00231 00232 if ((tablename==0) || (*tablename==0)) return 0; 00233 00234 TSQLResult* res = GetColumns(fDB.Data(), tablename); 00235 if (res==0) return 0; 00236 00237 TList* lst = 0; 00238 TSQLRow* row = 0; 00239 while ((row = res->Next())!=0) { 00240 const char* columnname = row->GetField(0); 00241 if (lst==0) lst = new TList; 00242 lst->Add(new TSQLColumnInfo(columnname)); 00243 delete row; 00244 } 00245 00246 delete res; 00247 00248 return new TSQLTableInfo(tablename, lst); 00249 } 00250 00251 //______________________________________________________________________________ 00252 void TSQLServer::SetFloatFormat(const char* fmt) 00253 { 00254 // set printf format for float/double members, default "%e" 00255 00256 if (fmt==0) fmt = "%e"; 00257 fgFloatFmt = fmt; 00258 } 00259 00260 //______________________________________________________________________________ 00261 const char* TSQLServer::GetFloatFormat() 00262 { 00263 // return current printf format for float/double members, default "%e" 00264 00265 return fgFloatFmt; 00266 }