File indexing completed on 2025-08-03 08:22:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #include <RDBC/TSQLDriverManager.h>
0051 #include <RDBC/TSQLConnection.h>
0052 #include <RDBC/TSQLUrl.h>
0053 #include <TList.h>
0054 #include <TSystem.h>
0055 #include <TClassTable.h>
0056 #include <iostream>
0057 #include <TROOT.h>
0058 #include <TString.h>
0059 #include <stdlib.h>
0060 #include <TSysEvtHandler.h>
0061 #include <TApplication.h>
0062 #include <TInterpreter.h>
0063 #include <RDBC/TSQLImporter.h>
0064
0065 ClassImpQ(TSQLDriverManager)
0066
0067 TList* gDataSources;
0068 TList* gDrivers;
0069 TList* gConnections;
0070 TString gRDBClibPath;
0071 TSignalHandler* gSIGTERMhandler;
0072 TSignalHandler* gSIGQUIThandler;
0073 Bool_t gHandlersInitiated = kFALSE;
0074
0075
0076 TSQLDriverManager* InitGlobalDriverManager()
0077 {
0078
0079 if (!gSQLDriverManager) gSQLDriverManager = new TSQLDriverManager();
0080 return gSQLDriverManager;
0081 }
0082
0083 TSQLDriverManager* gSQLDriverManager = InitGlobalDriverManager();
0084
0085
0086
0087
0088
0089 class SIGTERMhandler: public TSignalHandler
0090 {
0091 public:
0092 SIGTERMhandler(ESignals sig) : TSignalHandler(sig, kFALSE) { }
0093
0094 Bool_t Notify() {
0095 delete gSQLDriverManager;
0096 gApplication->Terminate(0);
0097 return kTRUE;
0098 }
0099 };
0100
0101
0102
0103
0104
0105
0106 class TSQLini: public TObject
0107 {
0108 private:
0109 TString fOldIni;
0110 TString fNewIni;
0111
0112 public:
0113 TSQLini(TSQLUrl* url);
0114 ~TSQLini();
0115 };
0116
0117
0118 TSQLini::TSQLini(TSQLUrl* url)
0119 {
0120
0121
0122
0123
0124 TString homedir = "/tmp";
0125 fOldIni = gSystem->Getenv("ODBCINI");
0126 fNewIni = homedir + Form("/.odbcini.%d",gSystem->GetPid());
0127 gSystem->Setenv("ODBCINI",fNewIni.Data());
0128
0129 url->Print(fNewIni.Data());
0130 }
0131
0132
0133 TSQLini::~TSQLini()
0134 {
0135
0136
0137 gSystem->Setenv("ODBCINI",fOldIni.Data());
0138
0139 if(gSystem->Unlink(fNewIni.Data())) {
0140 TString message = "Failed to delete file: ";
0141 message += fNewIni;
0142 Warning("Restore ODBCINI",message.Data());
0143 }
0144 }
0145
0146 TSQLini* gODBCini = 0;
0147
0148 Bool_t InitRDBCpath()
0149 {
0150
0151
0152 gRDBClibPath = gInterpreter->GetSharedLibs();
0153 int i1 = gRDBClibPath.Index("libRDBC.");
0154 if ( i1 < 0 ) return kFALSE;
0155 TString str = gRDBClibPath(0,i1);
0156 int i2 = str.Last(' ');
0157 str = gRDBClibPath(i2+1,gRDBClibPath.Length()-i2-1);
0158 i2 = str.Index(' ');
0159
0160 if(i2 == kNPOS) gRDBClibPath = str;
0161 else gRDBClibPath=str(0,i2-1);
0162
0163 gRDBClibPath = gSystem->DirName(gRDBClibPath.Data());
0164 return !gRDBClibPath.IsNull();
0165 }
0166
0167 static Bool_t dummy = InitRDBCpath();
0168
0169
0170 void InitHandlers()
0171 {
0172
0173
0174
0175 if(gHandlersInitiated) return;
0176
0177 if(gSystem) gSystem->RemoveOnExit(gSQLDriverManager);
0178 if(gInterpreter) gInterpreter->SaveGlobalsContext();
0179
0180
0181
0182
0183 gSIGTERMhandler = new SIGTERMhandler(kSigTermination);
0184 gSIGQUIThandler = new SIGTERMhandler(kSigQuit);
0185 if(gSystem) gSystem->AddSignalHandler(gSIGTERMhandler);
0186 if(gSystem) gSystem->AddSignalHandler(gSIGQUIThandler);
0187
0188 if(TClassTable::GetDict("TSQL")) {
0189 InitRDBCpath();
0190 }
0191
0192 gHandlersInitiated = kTRUE;
0193 }
0194
0195
0196
0197 TSQLDriverManager::TSQLDriverManager():TSQL(0)
0198 {
0199
0200
0201 if(!gSQLDriverManager) {
0202 gSQLDriverManager = this;
0203 gDataSources = new TList();
0204 gDrivers = new TList();
0205 gConnections = new TList();
0206 } else {
0207 Destroyed();
0208 }
0209 }
0210
0211
0212 TSQLDriverManager::~TSQLDriverManager()
0213 {
0214
0215
0216
0217
0218
0219 if(gDebug) Warning("~TSQLDriverManager()","Shutting down DriverManager");
0220 Shutdown();
0221 Destroyed();
0222 }
0223
0224
0225 void TSQLDriverManager::Shutdown()
0226 {
0227
0228
0229 gConnections->Delete();
0230 gDrivers->Delete();
0231 gDataSources->Delete();
0232 delete gDrivers;
0233 delete gDataSources;
0234 delete gConnections;
0235 gDrivers = 0;
0236 gDataSources = 0;
0237 gConnections = 0;
0238
0239 if(gODBCini) delete gODBCini;
0240 gSQLDriverManager = 0;
0241 }
0242
0243
0244 TList* TSQLDriverManager::GetDrivers()
0245 {
0246
0247
0248
0249 if(!TClassTable::GetDict("ODBCConnection")) {
0250 gSQLDriverManager->Throw(new TSQLException(
0251 "TSQLDriverManager::GetDrivers:RDBC-ODBC driver not loaded"));
0252 return 0;
0253 }
0254
0255 return gDrivers = (TList*)gROOT->ProcessLineFast(
0256 Form("ODBCConnection::RefreshDrivers((TList*)%ul)",gDrivers));
0257 }
0258
0259
0260 TList* TSQLDriverManager::GetDataSources()
0261 {
0262
0263
0264 if(!TClassTable::GetDict("ODBCConnection")) {
0265 gSQLDriverManager->Throw(new TSQLException(
0266 "TSQLDriverManager::GetDataSources:RDBC-ODBC driver not loaded"));
0267 return 0;
0268 }
0269
0270 return gDataSources = (TList*)gROOT->ProcessLineFast(
0271 Form("ODBCConnection::RefreshDataSources((TList*)%ul)",gDataSources));
0272 }
0273
0274
0275 #ifndef WIN32
0276
0277
0278
0279
0280
0281 #include <termio.h>
0282 #define TERMIO struct termio
0283
0284
0285
0286 TString EnterPassword()
0287 {
0288
0289
0290
0291 TERMIO org,tmp;
0292 TString pswd;
0293 const int bufsiz = 128;
0294 char passtr[bufsiz];
0295
0296 if(isatty(fileno(stdout))) {
0297 fputs("Enter password:",stdout);
0298 fflush(stdout);
0299 }
0300 ioctl(fileno(stdin), (int) TCGETA, &org);
0301 tmp = org;
0302 tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
0303 tmp.c_cc[VMIN] = 1;
0304 tmp.c_cc[VTIME]= 0;
0305 ioctl(fileno(stdin),(int) TCSETA, &tmp);
0306
0307 fgets(passtr,bufsiz,stdin);
0308
0309 pswd = passtr;
0310 pswd.Chop();
0311 ioctl(fileno(stdin),(int) TCSETA, &org);
0312
0313 if (isatty(fileno(stdout))) fputc('\n',stdout);
0314 return pswd;
0315 }
0316
0317 #else
0318 #include <conio.h>
0319
0320
0321 TString EnterPassword()
0322 {
0323
0324
0325 char to[80];
0326 char *pos=to,*end = to+sizeof(to)-1;
0327 int i = 0;
0328
0329 fprintf(stdout,"Enter password: ");
0330
0331 for (;;) {
0332 char tmp;
0333 tmp = _getch();
0334
0335 if (tmp == '\b' || (int) tmp == 127) {
0336 if (pos != to) {
0337 _cputs("\b \b");
0338 pos--;
0339 continue;
0340 }
0341 }
0342 if (tmp == '\n' || tmp == '\r' || tmp == 3) break;
0343 if (iscntrl(tmp) || pos == end) continue;
0344 _cputs("*");
0345 *(pos++) = tmp;
0346 }
0347
0348 while (pos != to && isspace(pos[-1]) == ' ') pos--;
0349
0350 *pos=0;
0351 _cputs("\n");
0352
0353 return to;
0354 }
0355 #endif
0356
0357
0358
0359 TSQLConnection* TSQLDriverManager::GetConnection( const TString& url,
0360 const TString& user,
0361 const TString& password )
0362 {
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 if(!gHandlersInitiated) InitHandlers();
0381 gSQLDriverManager->GetWarnings()->Delete();
0382
0383 TSQLConnection* con = 0;
0384 TSQLUrl sqlurl(url);
0385
0386 if(!sqlurl.IsValid()) {
0387 gSQLDriverManager->Throw(new TSQLException(
0388 Form("TSQLDriverManager::GetConnection:URL %s is not valid:-\n"
0389 " Protocol : %s SubProtocol: %s Driver: %s Port: %d",
0390 url.Data(),
0391 sqlurl.GetProtocol().Data(),
0392 sqlurl.GetSubProtocol().Data(),
0393 sqlurl.GetDriver().Data(),
0394 sqlurl.GetPort()
0395 )));
0396 return 0;
0397 }
0398
0399 TString pswd = password;
0400
0401 if(pswd.IsNull()) pswd = EnterPassword();
0402
0403
0404 TString anchor = sqlurl.GetAnchor();
0405
0406 if( sqlurl.GetProtocol()=="file" ||
0407 sqlurl.GetProtocol()=="http" ||
0408 sqlurl.GetProtocol()=="ftp" ) {
0409 anchor = sqlurl;
0410 sqlurl = "mysql:odbc://localhost/test";
0411 }
0412
0413 sqlurl.AddOption("User=" + user);
0414 con = (TSQLConnection*)gSQLDriverManager->GetConnections()->FindObject(sqlurl.GetUrl().Data());
0415
0416 if(con) {
0417 con->AddReference();
0418 goto exit;
0419 }
0420
0421 if( (sqlurl.GetProtocol()=="odbc" || sqlurl.GetSubProtocol()=="odbc") ) {
0422 if(!TClassTable::GetDict("ODBCConnection")) {
0423 gSQLDriverManager->Throw(new TSQLException(
0424 "TSQLDriverManager::GetConnection:RDBC-ODBC driver not loaded"));
0425 return 0;
0426 }
0427
0428 TString dsn = sqlurl.GetDSN();
0429
0430 if(gODBCini) { delete gODBCini; gODBCini = 0; }
0431 if(sqlurl.IsDynamicDSN()) gODBCini = new TSQLini(&sqlurl);
0432
0433 con = (TSQLConnection*) gROOT->ProcessLineFast(Form(
0434 "new ODBCConnection(\"%s\",\"%s\",\"%s\")",dsn.Data(),user.Data(),pswd.Data()));
0435
0436 if(gODBCini) { delete gODBCini; gODBCini = 0; }
0437 goto exit;
0438 }
0439
0440 exit:
0441 if ( con && !con->fImp ) {
0442 delete con;
0443 con = 0;
0444 return 0;
0445 }
0446 if(!con) return con;
0447 TSQLImporter* importer = 0;
0448
0449 if(!anchor.IsNull()) {
0450
0451 importer = new TSQLImporter();
0452 importer->Connect("Throw(TSQLException*)","TSQLDriverManager",gSQLDriverManager,"Throw(TSQLException*)");
0453 importer->Import(anchor,con);
0454
0455 if(!importer->IsValid() || gSQLDriverManager->GetWarnings()->GetSize()) {
0456 delete importer;
0457 delete con;
0458 return 0;
0459 }
0460 }
0461
0462 if(con->fImp) {
0463 if(con->References()==1) {
0464 gSQLDriverManager->GetConnections()->Add(con);
0465 con->SetURL(sqlurl.GetUrl());
0466 }
0467 } else {
0468 delete con;
0469 return 0;
0470 }
0471 if(importer) delete importer;
0472
0473 return con;
0474 }
0475
0476
0477 TSQLConnection* TSQLDriverManager::GetConnection( const TString& connectString )
0478 {
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494 if(!gHandlersInitiated) InitHandlers();
0495 gSQLDriverManager->GetWarnings()->Delete();
0496
0497 if(gODBCini) { delete gODBCini; gODBCini = 0; }
0498 TSQLConnection* con = 0;
0499 con = (TSQLConnection*)gSQLDriverManager->GetConnections()->FindObject(connectString.Data());
0500
0501 if(con) {
0502 con->AddReference();
0503 goto exit;
0504 }
0505
0506 if(!TClassTable::GetDict("ODBCConnection")) {
0507 gSQLDriverManager->Throw(new TSQLException(
0508 "TSQLDriverManager::GetConnection:RDBC-ODBC driver not loaded"));
0509 return 0;
0510 }
0511
0512 con = (TSQLConnection*) gROOT->ProcessLineFast(Form(
0513 "new ODBCConnection(\"%s\")",connectString.Data()));
0514 exit:
0515 if(con->fImp) {
0516 if(con->References()==1) {
0517 gSQLDriverManager->GetConnections()->Add(con);
0518 con->SetURL(connectString.Data());
0519 }
0520 } else {
0521 delete con;
0522 return 0;
0523 }
0524 return con;
0525 }
0526
0527
0528 void TSQLDriverManager::SetLoginTimeout( Int_t seconds )
0529 {
0530
0531
0532
0533
0534
0535
0536 if(TClassTable::GetDict("ODBCConnection"))
0537 gROOT->ProcessLineFast(Form("ODBCConnection::SetLoginTimeout(%d)",seconds));
0538 }
0539
0540
0541 Int_t TSQLDriverManager::GetLoginTimeout()
0542 {
0543
0544
0545
0546
0547
0548
0549 return TClassTable::GetDict("ODBCConnection") ?
0550 (Int_t) gROOT->ProcessLineFast("ODBCConnection::GetLoginTimeout()") : 0;
0551 }
0552
0553
0554 TList* TSQLDriverManager::GetConnections()
0555 {
0556
0557
0558 return gConnections;
0559 }