Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TSQLUrl.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TSQLUrl.cxx
1 // $Id: TSQLUrl.cxx,v 1.2 2009/10/09 12:28:48 pinkenbu Exp $
2 //*-- Author : Valeriy Onuchin 14/02/2000
3 //
4 
6 //
7 // The connection string can be specified by DSN or URL.
8 // The default format of URL string is:
9 //
10 // protocol:[subprotocol:][driver:]//host[:port]/[database][?options]
11 //
12 // where:
13 // protocol - DBMS type , e.g. mysql,oracle, etc.
14 // subprotocol - driver type , currently: "odbc"
15 // driver - driver name ( it could be alias name defined in /etc/odbcinst )
16 // or path to the driver lib, e.g. myodbc - /usr/local/lib/libmyodbc.so
17 //
18 // If absolute pathname is not specified, driver manager will try to
19 // find "lib[driver].so" in the following directories"
20 // /usr/lib,
21 // /usr/local/lib,
22 // $ROOTSYS/lib,
23 //
24 // host - host name or IP address of database server
25 // port - port number
26 // database - name of database
27 // options - string key=value's separated by ';' or '&'
28 //
29 // Example: "mysql:odbc:myodbc://myhost:3306/test?Trace=Yes;TraceFile=qq.log"
30 //
31 // You can do the same via "mysql://myhost/test?Trace=Yes;TraceFile=qq.log"
32 // The missing parts of connect string are set to default values.
33 //
34 // For MySQL these values are:
35 //
36 // subprotcol = odbc
37 // driver = /usr/local/lib/libmyodbc.so
38 // port = 3306
39 // database = test
40 // options = "Trace=;TraceFile="
41 //
42 //
43 // See also:
44 // TSQLConnection TSQLDriverManager
45 //
47 
48 #include <RDBC/TSQLUrl.h>
49 #include <RDBC/TSQLDriverManager.h>
50 #include <RDBC/TSQLDriverInfo.h>
51 #include <iostream>
52 #include <TString.h>
53 #include <TList.h>
54 #include <TSystem.h>
55 #include <TNamed.h>
56 #include <TRefCnt.h>
57 #include <cstdlib>
58 
60 
61 
62 //
63 // TSQLUrlParser - auxilary class used for parsing of URL string
64 // It has several subclasses, i.e. OracleParser,MySQLParser etc.
65 // which handle database specific cases.
66 //
67 //
69 class TSQLUrlParser: public TQObject, public TRefCnt
70 {
71 friend class TSQLUrl;
72 
73 protected:
74 
75  enum EErrorBits {
76  kErrProtocol = BIT(0), // wrong protocol
77  kErrSubProtocol= BIT(1), // wrong subprotocol
78  kErrDriver = BIT(2), // wrong or not existent driver
79  kErrHost = BIT(3), // wrong host
80  kErrPort = BIT(4), // wrong port
81  kErrFile = BIT(5), // wrong file/database
82  kErrDatabase = BIT(5), // wrong file/database
83  kErrAnchor = BIT(6), // wrong anchor
84  kErrOption = BIT(7) // wrong option
85  };
86 
87  TString fDriver; // driver name
88  TString fFullUrl; // full url string
89  TString fDSN; // DataSourceName
90  TString fProtocol; // protocol: oracle, mysql, etc
91  TString fSubProtocol; // sub-protocol:odbc, thin, etc
92  TString fHost; // remote host
93  TString fFile; // remote object
94  TString fAnchor; // anchor in object
95  TString fOptions; // options (after ?)
96  TString fDescription; // description
97  TString fPort; // port through which to contact remote server
98  Int_t fStatus; // O if url is valid , non-zero otherwise
99  Bool_t fDynamicDSN; // kTRUE if DSN is created at dynamically
100 
101 protected:
102  virtual TString DefaultProtocol() { return "odbc"; }
103  virtual TString DefaultSubProtocol() { return "odbc"; }
104  virtual TString DefaultDriver() { return ""; }
105  virtual TString DefaultHost() { return "localhost"; }
106  virtual TString DefaultDatabase() { return ""; }
107  virtual TString DefaultPort() { return ""; }
108  virtual TString DefaultOptions() { return ""; }
109  virtual TString DefaultAnchor() { return ""; }
110  virtual TString DefaultDescription() { return ""; }
111  virtual TString DefaultDriverPath() { return ""; }
112 
113  virtual Bool_t ValidProtocol(const TString&);
114  virtual Bool_t ValidSubProtocol(const TString&);
115  virtual Bool_t ValidDriver(const TString&);
116  virtual Bool_t ValidHost(const TString&);
117  virtual Bool_t ValidDatabase(const TString&);
118  virtual Bool_t ValidPort(const TString&);
119  virtual Bool_t ValidOption(const TString&);
120  virtual Bool_t ValidAnchor(const TString&);
121  virtual void Validate();
122  virtual void SetDefaults();
123  virtual void SetFullUrl();
124 public:
125  TSQLUrlParser():TQObject(),TRefCnt() { }
126  TSQLUrlParser(const TString& url);
127  TSQLUrlParser& operator=(const TSQLUrlParser& url);
128  void Throw( TSQLException* e ) { Emit("Throw(TSQLException*)",(long)e); } //*SIGNAL*
129  virtual Bool_t IsValid() { return fStatus==0; }
130 };
131 
133 class Tokenizer
134 {
135 private:
136  TString fString; // string to tokenize
137  TString fDelim; // delimter
138  Ssiz_t fDL; // delim length
139 
140 public:
142 
143  Tokenizer(const TString& str,const TString& delim)
144  {
145  SetString(str);
146  SetDelim(delim);
147  }
148 
149  Tokenizer(const TString& str)
150  {
151  SetString(str);
152  }
153 
154  TString GetString() const { return fString; }
155  void SetString(const TString& str)
156  {
157  // force new TString w/ separate reference counting
158  // so internal Tokenizer actions (effective modification of fData)
159  // by Forw/Back don't disturb const TString& passed in to ctor
160  const char* strCopy = str.Data();
161  fString = TString(strCopy);
162  }
163 
164  void SetDelim(const TString& delim)
165  {
166  fDelim = delim;
167  fDL = fDelim.Length();
168  }
169 
170  TString Skip(Int_t n)
171  {
172  fString = fString(n,fString.Length()-n);
173  return fString;
174  }
175 
176  TString Before()
177  {
178  // Returns string before delim
179 
180  Int_t idx = fString.First(fDelim.Data());
181 
182  if(idx!=kNPOS) {
183  return fString(0,idx);
184  } else {
185  return fString;
186  }
187  }
188 
189  TString After()
190  {
191  // Returns string after delim
192 
193  Int_t idx = fString.First(fDelim.Data());
194 
195  if(idx!=kNPOS) {
196  return fString(idx+fDL,fString.Length());
197  } else {
198  return fString;
199  }
200  }
201 
202  TString Forw(char term=0)
203  {
204  // - Looks for fDelim string which is before "term char"
205  // - Returns string before fDelim.
206  // - Cuts fString after fDelim.
207 
208  TString str;
209 
210  Int_t idx1 = fString.First(term);
211 
212  if(idx1!=kNPOS) {
213  str = fString(0,idx1);
214  } else {
215  str = fString;
216  idx1 = 0;
217  }
218 
219  Int_t idx = str.Index(fDelim.Data());
220 
221  if(idx!=kNPOS) {
222  fString = fString(idx+fDL,fString.Length());
223  return str(0,idx);
224  } else {
225  return fString;
226  }
227  }
228 
229  TString Back(char term=0)
230  {
231  // - Looks for fDelim string which is after "term char"
232  // - Returns string after fDelim.
233  // - Cuts fString before fDelim.
234 
235  TString str;
236 
237  Int_t idx1 = fString.Last(term);
238 
239  if(idx1!=kNPOS && idx1<fString.Length()) {
240  str = fString(idx1,fString.Length());
241  } else {
242  str = fString;
243  idx1 = 0;
244  }
245 
246  Int_t idx = str.Index(fDelim.Data());
247 
248  if(idx!=kNPOS) {
249  fString = fString(0,idx+idx1);
250  return str(idx+fDL,str.Length());
251  } else {
252  return "";
253  }
254  }
255 };
256 
258 //___________________________________________________________________
259 TSQLUrlParser::TSQLUrlParser(const TString& url):TQObject(),TRefCnt()
260 {
261  //
262 
263  TString str;
264  fDynamicDSN = kTRUE;
265  fStatus = 0;
266 
267  Tokenizer parser(url);
268 
269  // protocol
270  parser.SetDelim(":");
271  fProtocol = parser.Forw('/');
272 
273  if(fProtocol.IsNull()) { // dsn-like
274  fFullUrl = url;
275  fDSN = url;
276  fProtocol = DefaultProtocol();
277  fDynamicDSN = kFALSE;
278  return;
279  }
280 
281  fProtocol.ToLower();
282 
283  // subprotocol
284  parser.SetDelim(":"); //
285  fSubProtocol = parser.Forw('/'); //
286  fSubProtocol.ToLower();
287 
288  parser.SetDelim("://");
289  fDriver= parser.Forw('@');
290 
291  if(fDriver.BeginsWith("//")) {
292  fDriver="";
293  parser.Skip(2);
294  }
295 
296  parser.SetDelim("?");
297  fOptions = parser.Back(':');
298 
299  parser.SetDelim("#");
300  fAnchor = parser.Back(':'); //
301 
302  if(fAnchor.IsNull()) fAnchor = DefaultAnchor();
303 
304  // host + port + file
305  parser.SetDelim("/");
306  fFile = parser.Back(':');
307 
308  if(parser.GetString().Contains(":")) {
309  parser.SetDelim(":");
310  fPort = parser.After();
311  fHost = parser.Before();
312  } else {
313  fHost = parser.GetString();
314  }
315 
316  if(fProtocol=="file") { // small fix
317  if( fHost != "localhost") {
318  // See if "host" is actually an environmental variable
319  const char* host = 0;
320  if ( fHost.BeginsWith("$") ) host = getenv(fHost.Data()+1);
321  if ( host ) {
322  fFile.Prepend("/");
323  fFile.Prepend(host);
324  }
325  else fFile = "/" + fHost + fFile;
326  fHost = "localhost";
327  }
328  }
329 }
330 
331 //___________________________________________________________________
332 void TSQLUrlParser::SetFullUrl()
333 {
334  //
335 
336  if(fDynamicDSN) { //
337  fFullUrl = fProtocol + ":" + fSubProtocol + ":";
338  fFullUrl += fDriver + "://";
339  if(!(fHost=="localhost" && fPort.IsNull())) fFullUrl += fHost;
340  fFullUrl += fPort.IsNull() ? "" : ":";
341  fFullUrl += fPort;
342  if((fHost=="localhost"&& fPort.IsNull())) fFullUrl += "/";
343  fFullUrl += fFile;
344  fFullUrl += fOptions.IsNull() ? "" : "?";
345  fFullUrl += fOptions;
346  }
347 }
348 
349 //___________________________________________________________________
350 void TSQLUrlParser::SetDefaults()
351 {
352  // default settings
353 
354  if(fSubProtocol.IsNull()) fSubProtocol = DefaultSubProtocol();
355  if(fDriver.IsNull()) fDriver = DefaultDriver();
356  if(fOptions.IsNull()) fOptions = DefaultOptions();
357  if(fDescription.IsNull()) fDescription = DefaultDescription();
358  if(fFile.IsNull()) fFile = DefaultDatabase();
359  if(fPort.IsNull()) fPort = DefaultPort();
360  if(fHost.IsNull()) fHost = DefaultHost();
361 }
362 
363 //___________________________________________________________________
365 {
366  //
367 
368  TString str;
369 
370  if(!ValidProtocol(fProtocol)) {
371  str = "Wrong format of protocol: ";
372  str += fProtocol;
373  fProtocol="none";
374  Throw(new TSQLException(str,""));
375  fStatus = fStatus | kErrProtocol;
376  }
377 
378  if(!ValidSubProtocol(fSubProtocol)) {
379  str = "Wrong format of sub-protocol: ";
380  str += fSubProtocol;
381  fSubProtocol="none";
382  Throw(new TSQLException(str,""));
383  fStatus = fStatus | kErrSubProtocol;
384  }
385 
386  if(!ValidDriver(fDriver)) {
387  str = "Wrong Driver : ";
388  str += fDriver;
389  fDriver="none";
390  Throw(new TSQLException(str,""));
391  fStatus = fStatus | kErrDriver;
392  }
393 
394  if(!ValidHost(fHost)) {
395  str = "Wrong format of host: ";
396  str += fHost;
397  fHost="none";
398  Throw(new TSQLException(str,""));
399  fStatus = fStatus | kErrHost;
400  }
401 
402  if(!ValidDatabase(fFile)) {
403  str = "Wrong format of file/database: ";
404  str += fFile;
405  fFile="none";
406  Throw(new TSQLException(str,""));
407  fStatus = fStatus | kErrFile;
408  }
409 
410  if(!ValidPort(fPort)) {
411  str = "Wrong port: ";
412  str += fPort;
413  fPort="none";
414  Throw(new TSQLException(str,""));
415  fStatus = fStatus | kErrPort;
416  }
417 
418  if(!ValidOption(fOptions)) {
419  str = "Wrong format of option: ";
420  str += fOptions;
421  fOptions="none";
422  Throw(new TSQLException(str,""));
423  fStatus = fStatus | kErrOption;
424  }
425 
426  if(fDSN.IsNull()) { //
427 // unixODBC imposes a 32 char limit on this (SQL_MAX_DSN_LENGTH)
428 // make each name distinct to avoid ODBCINI caching issues
429  static Int_t nConnect = 0;
430  fDSN = fProtocol + Form("%d-%d",gSystem->GetPid(),++nConnect);
431  }
432 }
433 
434 //___________________________________________________________________
435 TSQLUrlParser& TSQLUrlParser::operator=(const TSQLUrlParser& url)
436 {
437  //
438 
439  if (this != &url) {
440  fDriver = url.fDriver;
441  fFullUrl = url.fFullUrl;
442  fDSN = url.fDSN;
443  fProtocol = url.fProtocol;
444  fSubProtocol = url.fSubProtocol;
445  fHost = url.fHost;
446  fFile = url.fFile;
447  fAnchor = url.fAnchor;
448  fOptions = url.fOptions;
449  fDescription = url.fDescription;
450  fPort = url.fPort;
451  fStatus = url.fStatus;
452  fDynamicDSN = url.fDynamicDSN;
453  }
454  return *this;
455 }
456 
457 //___________________________________________________________________
458 Bool_t TSQLUrlParser::ValidProtocol(const TString& prot)
459 {
460  //
461 
462  const char* str = prot.Data();
463 
464  for (Ssiz_t i = 0; i < prot.Length(); i++) {
465  if( !isalnum(str[i]) && str[i]!='-' ) return kFALSE;
466  }
467  return kTRUE;
468 }
469 
470 //___________________________________________________________________
471 Bool_t TSQLUrlParser::ValidSubProtocol(const TString& prot)
472 {
473  //
474  const char* str = prot.Data();
475 
476  for (Ssiz_t i = 0; i < prot.Length(); i++) {
477  if( !isalnum(str[i]) && str[i]!='-' ) return kFALSE;
478  }
479  return kTRUE;
480 }
481 
482 //___________________________________________________________________
483 Bool_t TSQLUrlParser::ValidDriver(const TString& drvname)
484 {
485  //
486 
487  Char_t* chrStr =0;
488  TList* li = TSQLDriverManager::GetDrivers();
489  TSQLDriverInfo* drv;
490  TString str;
491  TNamed* obj;
492  TString key;
493  TString value;
494  TString so = "."; so += gSystem->GetSoExt();
495  TString str2;
496  TString name = chrStr = gSystem->ExpandPathName(drvname.Data());
497  delete [] chrStr;
498 
499  if(li) {
500  TIter next(li);
501 
502  while((drv=(TSQLDriverInfo*)next())) {
503  str = drv->GetDescription();
504  if(str==name) return kTRUE;
505  li=drv->GetAttributes();
506  TIter nexta(li);
507 
508  while((obj=(TNamed*)nexta())) {
509  str=obj->GetName();
510  str.ReplaceAll(" ","");
511  str.ReplaceAll("\t","");
512  Int_t i = str.Index("=");
513  key = str(0,i);
514  value = str(i+1,str.Length()-i-1);
515  key.ToLower();
516  if(key=="driver" && value==name) return kTRUE;
517  }
518  }
519  }
520 
521  Bool_t af = gSystem->IsAbsoluteFileName(name.Data());
522 
523  if(!af) {
524  if(!name.BeginsWith("lib")) name = "lib" + name;
525  if(!name.EndsWith(so.Data())) name += so;
526 
527  str2 = chrStr = gSystem->ConcatFileName(DefaultDriverPath().Data(),name.Data());
528  delete [] chrStr;
529  if(!gSystem->AccessPathName(str2.Data())) { fDriver = str2; return kTRUE; }
530 
531  str2 = chrStr = gSystem->ConcatFileName("/usr/lib",name.Data());
532  delete [] chrStr;
533  if(!gSystem->AccessPathName(str2.Data())) { fDriver = str2; return kTRUE; }
534 
535  str2 = chrStr = gSystem->ConcatFileName("/usr/local/lib",name.Data());
536  delete [] chrStr;
537  if(!gSystem->AccessPathName(str2.Data())) { fDriver = str2; return kTRUE; }
538 
539  TString rootsys = chrStr = gSystem->ExpandPathName("$ROOTSYS/lib");
540  delete [] chrStr;
541 
542  str2 = chrStr = gSystem->ConcatFileName(rootsys.Data(),name.Data());
543  delete [] chrStr;
544  if(!gSystem->AccessPathName(str2.Data())) { fDriver = str2; return kTRUE; }
545 
546  // check driver at $LD_LIBRARY_PATH
547  TString ldlib = gSystem->Getenv("LD_LIBRARY_PATH");
548 
549  if(!ldlib.IsNull()) {
550  Int_t sep = 0;
551  Int_t prev = 0;
552  TString sublib;
553 
554  while(1) {
555  sep = ldlib.Index(":",prev);
556  if(sep==kNPOS) break;
557  sublib = ldlib(prev,sep-prev);
558 
559 
560  if( (sublib=="/usr/lib") ||
561  (sublib=="/usr/local/lib") ||
562  (sublib==rootsys) ) {
563  prev += sublib.Length()+1;
564  continue;
565  }
566  prev = sep+1;
567 
568  str2 = chrStr = gSystem->ConcatFileName(sublib.Data(),name.Data());
569  delete [] chrStr;
570  if(!gSystem->AccessPathName(str2.Data())) { fDriver = str2; return kTRUE; }
571  }
572  sublib = ldlib(prev,ldlib.Length()-prev);
573  str2 = chrStr = gSystem->ConcatFileName(sublib.Data(),name.Data());
574  delete [] chrStr;
575  if(!gSystem->AccessPathName(str2.Data())) { fDriver = str2; return kTRUE; }
576  }
577 
578  return kFALSE;
579  } else {
580  if(!gSystem->AccessPathName(name.Data())) {
581  fDriver = name;
582  return kTRUE;
583  } else {
584  fDriver = name;
585  return kFALSE;
586  }
587  }
588  return kFALSE;
589 }
590 
591 //___________________________________________________________________
592 Bool_t TSQLUrlParser::ValidHost(const TString& host)
593 {
594  //
595  const char* str = host.Data();
596  char prevch;
597 
598  for (Ssiz_t i = 0; i < host.Length(); i++) {
599  if( (!isalnum(str[i]) && str[i]!='.' && str[i]!='-') ||
600  (str[i]=='.' && prevch=='.') ) return kFALSE;
601  prevch=str[i];
602  }
603  return kTRUE;
604 }
605 
606 //___________________________________________________________________
607 Bool_t TSQLUrlParser::ValidDatabase(const TString& db)
608 {
609  //
610 
611  const char* str = db.Data();
612 
613  for (Ssiz_t i = 0; i < db.Length(); i++) {
614  if( !isascii(str[i]) ) return kFALSE;
615  }
616  return kTRUE;
617 }
618 
619 //___________________________________________________________________
620 Bool_t TSQLUrlParser::ValidPort(const TString& port)
621 {
622  //
623 
624  const char* str = port.Data();
625  return atoi(str)!=0;
626 }
627 
628 //___________________________________________________________________
629 Bool_t TSQLUrlParser::ValidOption(const TString& /* opt */)
630 {
631  //
632  return kTRUE;
633 }
634 
635 //___________________________________________________________________
636 Bool_t TSQLUrlParser::ValidAnchor(const TString&)
637 {
638  //
639  return kTRUE;
640 }
641 
643 class OracleParser: public TSQLUrlParser
644 {
645 protected:
646  TString fTNS; // TNS name
647 
648  virtual TString DefaultProtocol() { return "oracle"; }
649  virtual TString DefaultSubProtocol() { return "odbc"; }
650  virtual TString DefaultDriver();
651  virtual TString DefaultHost() { return "localhost"; }
652  virtual TString DefaultDatabase() { return "ORCL"; }
653  virtual TString DefaultPort() { return "1521"; }
654  virtual TString DefaultOptions();
655  virtual TString DefaultDescription() { return "Connection via OpenLink ODBC driver to Oracle database"; }
656 public:
657  OracleParser(const TString& url);
658 };
659 
660 //___________________________________________________________________
661 OracleParser::OracleParser(const TString& url):TSQLUrlParser(url)
662 {
663  //
664 
665  if(fHost.IsNull()) {
666  if(fFile.BeginsWith("@")) {
667  Tokenizer parser(fFile);
668  fFile = parser.Skip(1);
669  if(fFile.Contains(":")) {
670  parser.SetDelim(":");
671  fTNS = "";
672  fHost = parser.Forw(0);
673  fPort = parser.Forw(0);
674  fFile = parser.GetString();
675  } else {
676  fTNS = parser.GetString();
677  fHost = "localhost";
678  fFile = fTNS;
679  }
680  }
681  }
682 }
683 
684 //___________________________________________________________________
686 {
687  //
688 
689  if(fSubProtocol=="odbc") {
690  return "oplodbc";
691  } else {
692  return "";
693  }
694 }
695 
696 //___________________________________________________________________
698 {
699  //
700 
701  if(fSubProtocol=="odbc") {
702  return "ServerType=Oracle 8;"
703  "Protocol=TCP/IP;"
704  "ReadOnly=Yes;"
705  "FetchBufferSize=100;"
706  "UserName=scott;"
707  "Password=tiger;";
708  } else {
709  return "";
710  }
711 }
712 
714 class MySQLParser: public TSQLUrlParser
715 {
716 protected:
717  virtual TString DefaultProtocol() { return "mysql"; }
718  virtual TString DefaultSubProtocol() { return "odbc"; }
719  virtual TString DefaultDriver();
720  virtual TString DefaultHost() { return "localhost"; }
721  virtual TString DefaultDatabase() { return "test"; }
722  virtual TString DefaultPort() { return "3306"; }
723  virtual TString DefaultOptions() { return "Trace=No;TraceFile=;"; }
724  virtual TString DefaultDescription() { return "Connection via MyODBC driver to MySQL database"; }
725 // virtual TString DefaultDriverPath() { return ""; }
726 
727 public:
728  MySQLParser(const TString& url):TSQLUrlParser(url) { }
729 };
730 
731 //___________________________________________________________________
733 {
734  //
735 
736  if(fSubProtocol=="odbc") {
737  return "myodbc";
738  } else {
739  return "";
740  }
741 }
742 
744 class PostgreSQLParser: public TSQLUrlParser
745 {
746 protected:
747  virtual TString DefaultProtocol() { return "postgresql"; }
748  virtual TString DefaultSubProtocol() { return "odbc"; }
749  virtual TString DefaultDriver();
750  virtual TString DefaultHost() { return "localhost"; }
751  virtual TString DefaultDatabase() { return "test"; }
752  virtual TString DefaultPort() { return "5432"; }
753  virtual TString DefaultOptions() { return ""; }
754  virtual TString DefaultDescription() { return "Connection via psqlodbc driver to PostgreSQL database"; }
755 
756 public:
757  PostgreSQLParser(const TString& url);
758 };
759 
760 //___________________________________________________________________
761 PostgreSQLParser::PostgreSQLParser(const TString& url):TSQLUrlParser(url)
762 {
763 }
764 
765 //___________________________________________________________________
767 {
768  return "psqlodbc";
769 }
770 
772 class ConnectStringParser: public TSQLUrlParser
773 {
774 public:
775  ConnectStringParser(const TString& fullurl) {
776  Int_t i1 = fullurl.Index("=");
777  Int_t i2 = fullurl.Index(";",i1);
778  fFullUrl = fullurl;
779  if(i2<0) {
780  Destroyed();
781  return;
782  }
783  fDSN = fullurl(i1+1,i2-i1-1);
784  fOptions = fullurl(i2+1,fullurl.Length()-i2-1);
785  fDynamicDSN = kFALSE;
786  }
787 };
788 
790 //___________________________________________________________________
791 TSQLUrl::TSQLUrl( const TString& url ):TObject(),TQObject()
792 {
793  //
794 
795  TString fullurl(url.Data());
796  fullurl.ReplaceAll(" ",""); // remove blanks
797 
798  if (fullurl.BeginsWith("oracle:",TString::kIgnoreCase)) { fParser = new OracleParser(fullurl); goto exit; }
799  if (fullurl.BeginsWith("mysql:",TString::kIgnoreCase)) { fParser = new MySQLParser(fullurl); goto exit; }
800  if (fullurl.BeginsWith("postgresql:",TString::kIgnoreCase)) { fParser = new PostgreSQLParser(fullurl); goto exit; }
801 //if (fullurl.BeginsWith("msql:",TString::kIgnoreCase)) { fParser = new mSQLParser(fullurl); goto exit; }
802 //if (fullurl.BeginsWith("informix:",TString::kIgnoreCase)) { fParser = new InformixParser(fullurl); goto exit; }
803  if (fullurl.BeginsWith("dsn=",TString::kIgnoreCase)) { fParser = new ConnectStringParser(fullurl); goto exit; }
804  if(fullurl.BeginsWith("/")) fullurl = "file:" + fullurl;
805 
806 // default:
807  fParser = new TSQLUrlParser(fullurl);
808 
809 exit:
810  if(fParser->fDynamicDSN) {
811  fParser->SetDefaults();
812  fParser->Validate();
813  fParser->SetFullUrl();
814 
815  if(!fParser->IsValid()) {
816  //Throw(TSQLException*);
817 // delete fParser;
818 
819  } else fParser->AddReference(); //update counter of references
820  }
821 }
822 
823 //___________________________________________________________________
824 TSQLUrl::TSQLUrl( const TString& dsn, const TString& description):
825  TObject(),TQObject()
826 {
827  // ctor.
828 
829  fParser = new TSQLUrlParser(dsn);
830  fParser->fDescription = description;
831  fParser->AddReference(); //update counter of references
832 }
833 
834 //___________________________________________________________________
836 {
837  // dtor.
838 
839  fParser->RemoveReference(); // decrease references
840  if( fParser->References()<=0 ) delete fParser;
841 }
842 
843 //___________________________________________________________________
844 TSQLUrl::TSQLUrl(const TSQLUrl& url) : TObject(), TQObject()
845 {
846  //
847 
848  fParser = url.fParser;
849  fParser->AddReference(); //update counter of references
850 }
851 
852 //___________________________________________________________________
854 {
855  //
856 
857  if(this != &url) {
858  url.fParser->AddReference();
859  fParser = url.fParser;
860  }
861  return *this;
862 }
863 //___________________________________________________________________
864 TString TSQLUrl::GetDSN() const
865 {
866  // Return DataSourceName
867 
868  return fParser->fDSN; //
869 }
870 
871 //___________________________________________________________________
872 TString TSQLUrl::GetUrl() const
873 {
874  // Return full URL string.
875 
876  return fParser->fFullUrl; //
877 }
878 //___________________________________________________________________
879 TString TSQLUrl::GetProtocol() const
880 {
881  // protocol: oracle, mysql, postgresql
882 
883  return fParser->fProtocol;
884 }
885 
886 //___________________________________________________________________
887 TString TSQLUrl::GetSubProtocol() const
888 {
889  // subprotocol (driver type) : odbc, oci8, thin etc
890 
891  return fParser->fSubProtocol;
892 }
893 
894 //___________________________________________________________________
895 TString TSQLUrl::GetDriver() const
896 {
897  // driver library name: myodbc, oplodbc, odbcpsql or full path to driver
898  // /usr/lib/libmyodbc.so.1
899 
900  return fParser->fDriver;
901 }
902 
903 //___________________________________________________________________
904 TString TSQLUrl::GetHost() const
905 {
906  // remote host
907 
908  return fParser->fHost;
909 }
910 
911 //___________________________________________________________________
912 TString TSQLUrl::GetFile() const
913 {
914  // remote object: file or database
915 
916  return fParser->fFile;
917 }
918 
919 //___________________________________________________________________
920 TString TSQLUrl::GetAnchor() const
921 {
922  // anchor in object
923 
924  return fParser->fAnchor;
925 }
926 
927 //___________________________________________________________________
928 TString TSQLUrl::GetOptions() const
929 {
930  // options (after ?)
931 
932  return fParser->fOptions;
933 }
934 
935 //___________________________________________________________________
936 TString TSQLUrl::GetDescription() const
937 {
938  // return description string
939 
940  return fParser->fDescription;
941 }
942 
943 //___________________________________________________________________
944 Int_t TSQLUrl::GetPort() const
945 {
946  // port through which to contact remote server
947 
948  const char* str = (const char*)fParser->fPort;
949  return atoi(str);
950 }
951 
952 //___________________________________________________________________
953 Bool_t TSQLUrl::IsValid() const
954 {
955  //
956 
957  return fParser->fStatus == 0;
958 }
959 
960 //___________________________________________________________________
961 Bool_t TSQLUrl::IsDynamicDSN() const
962 {
963  //
964 
965  return fParser->fDynamicDSN;
966 }
967 
968 //___________________________________________________________________
969 void TSQLUrl::AddOption(const TString& opt)
970 {
971  //
972 
973  int l = fParser->fOptions.Length();
974 
975  if(l) fParser->fFullUrl += "?";
976 
977  if(!l || ( l && !fParser->fOptions.Last(';'))) fParser->fOptions += ";";
978  fParser->fOptions += opt + ";";
979  fParser->fFullUrl += opt + ";";
980 }
981 
982 //___________________________________________________________________
983 const char *TSQLUrl::GetName() const
984 {
985  //
986 
987  return GetDSN().Data();
988 }
989 
990 //___________________________________________________________________
991 const char *TSQLUrl::GetTitle() const
992 {
993  //
994 
995  return GetDescription().Data();
996 }
997 
998 //___________________________________________________________________
999 void TSQLUrl::ls(Option_t *option) const
1000 {
1001  // pritnts url
1002 
1003  Print(option);
1004 }
1005 
1006 //___________________________________________________________________
1007 void TSQLUrl::Print(Option_t *option) const
1008 {
1009  // pritnts url to stdout or to file with name=option
1010 
1011  FILE* fd;
1012  if(!option || !strlen(option) || !IsDynamicDSN()) fd = stdout;
1013  else fd = fopen(option,"w");
1014 
1015  if(!fd) {
1016 // Throw( new TSQLException(Form("TSQLUrl:: Failed to open file: %s",option)) );
1017  return;
1018  }
1019 
1020  if(!fParser->fDSN.IsNull()) fprintf(fd,"[%s]\n", fParser->fDSN.Data());
1021  if(!fParser->fDescription.IsNull()) fprintf(fd,"Description\t\t= %s\n", fParser->fDescription.Data());
1022  if(!fParser->fProtocol.IsNull() && (fd == stdout) ) fprintf(fd,"RDBC Protocol\t\t= %s\n", fParser->fProtocol.Data());
1023  if(!fParser->fSubProtocol.IsNull() && (fd == stdout) ) fprintf(fd,"RDBC SubProtocol\t\t= %s\n", fParser->fSubProtocol.Data());
1024  if(!fParser->fDriver.IsNull()) fprintf(fd,"Driver\t\t= %s\n", fParser->fDriver.Data());
1025  if(!fParser->fHost.IsNull()) fprintf(fd,"Server\t\t= %s\n", fParser->fHost.Data());
1026  if(!fParser->fPort.IsNull()) fprintf(fd,"Port\t\t= %s\n", fParser->fPort.Data());
1027  if(!fParser->fFile.IsNull()) fprintf(fd,"Database\t\t= %s\n", fParser->fFile.Data());
1028  if(!fParser->fAnchor.IsNull() && (fd == stdout) ) fprintf(fd,"Anchor\t\t= %s\n", fParser->fAnchor.Data());
1029  if(!fParser->fOptions.IsNull()) {
1030  TString str(fParser->fOptions.Data());
1031  str.ReplaceAll(";","\n");
1032  str.ReplaceAll("&","\n");
1033  str.ReplaceAll("=","\t\t= ");
1034  fprintf(fd,"%s",str.Data());
1035  }
1036  fprintf( fd,"\n" );
1037  if(fd != stdout) fclose(fd);
1038 }
1039