Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MySQLConnection.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MySQLConnection.cxx
1 // $Id: MySQLConnection.cxx,v 1.1.1.1 2004/02/18 20:58:02 dave Exp $
2 //*-- Author : Valeriy Onuchin 22/02/2001
3 //
4 // RDBC driver to MySQL database implemented with MySQL C API.
5 //
6 // ++ The code consists of some parts stolen from mm JDBC and
7 // MyODBC ODBC drivers and other mysql-related open sources.
8 //
9 
11 //
12 //
13 // A connection (session) with a specific database. Within the context
14 // of a TSQLConnection, SQL statements are executed and results are
15 // returned. A TSQLConnection's database is able to provide information
16 // describing its tables, its supported SQL grammar, its stored procedures,
17 // the capabilities of this connection, and so on. This information is
18 // obtained with the GetMetaData() method.
19 //
20 // See also:
21 // TSQLDriverManager::GetConnection(TString)
22 // TSQLStatement TSQLPreparedStatement TSQLCallableStatement
23 // TSQLResultSet TSQLDatabaseMetaData
24 //
26 //
27 // A transaction is a recoverable sequence of SQL operations grouped
28 // as a single unit. The initiation and termination of transaction
29 // define the following points of data consistency within an
30 // application process; either all SQL operations within a transaction
31 // are applied to the data source (committed), or the effects of all
32 // SQL operations within a transaction are completely "undone"
33 // (rolled back).
34 // RDBC provides the following modes of transaction processing
35 // that determine haw and when transactions are to be committed (or,
36 // if possible rolled back):
37 //
38 // - Auto-commit mode
39 // - Manual-commit mode
40 //
41 // defined by TSQLConnection::SetAutoCommit( Bool_t autoCommit )
42 //
44 //
45 // In multi-user database system, transactions can occur
46 // simultaneously, and each transaction has potential to interfere
47 // with another one. When transactions are not isolated from each
48 // other in multi-user enviroments, the following three types of
49 // events can occur:
50 //___________________________________________________________________
51 //
52 // Dirty Read:
53 //
54 // Transaction 1 changes a row. Transaction 2 reads
55 // the changed row before Transacion 1 commits the change. If
56 // Transaction 1 rolls back the change, Transacion 2 will have
57 // read a row that is considered to have never existed
58 //
59 //___________________________________________________________________
60 //
61 // Nonrepeatable Read:
62 //
63 // Transaction 1 reads a row. Transaction 2 updates or deletes
64 // that row and commits the change. If Transaction 1 attempts
65 // to reread the row, it will receive different row values or
66 // discover that the row has been deleted.
67 //
68 //___________________________________________________________________
69 //
70 // Phantom:
71 //
72 // Transaction 1 reads a set of rows that satisfy some search
73 // criteria. Transaction 2 generates one or more rows ( either
74 // through inserts or updates ) that match the search criteria
75 // If transacion 1 re-executes the statement that reads the rows,
76 // it receives a different set of rows.
77 //
79 //
80 // ODBC defines four levels of transaction isolation that can,
81 // prevent all, some, or none of these events from occurring.
82 // They are:
83 //___________________________________________________________________
84 //
85 // kTRANSACTION_NONE
86 //
87 // Indicates that transactions are not supported.
88 //
89 //___________________________________________________________________
90 //
91 // kTRANSACTION_READ_UNCOMMITTED
92 //
93 // Dirty reads, non-repeatable reads and phantom reads can occur.
94 // This level allows a row changed by one transaction to be read
95 // by another transaction before any changes in that row have been
96 // committed (a "dirty read"). If any of the changes are rolled back,
97 // the second transaction will have retrieved an invalid row.
98 //
99 //___________________________________________________________________
100 //
101 // kTRANSACTION_READ_COMMITTED
102 //
103 //
104 // Dirty reads are prevented; non-repeatable reads and phantom reads
105 // can occur. This level only prohibits a transaction from reading a
106 // row with uncommitted changes in it.
107 //
108 //___________________________________________________________________
109 //
110 // kTRANSACTION_REPEATABLE_READ
111 //
112 // Dirty reads and non-repeatable reads are prevented; phantom reads
113 // can occur. This level prohibits a transaction from reading a row
114 // with uncommitted changes in it, and it also prohibits the situation
115 // where one transaction reads a row, a second transaction alters the
116 // row, and the first transaction rereads the row, getting different
117 // values the second time (a "non-repeatable read").
118 //
119 //___________________________________________________________________
120 //
121 // kTRANSACTION_SERIALIZABLE
122 //
123 // Dirty reads, non-repeatable reads and phantom reads are prevented.
124 // This level includes the prohibitions in kTRANSACTION_REPEATABLE_READ
125 // and further prohibits the situation where one transaction reads
126 // all rows that satisfy a WHERE condition, a second transaction
127 // inserts a row that satisfies that WHERE condition, and the first
128 // transaction rereads for the same condition, retrieving the
129 // additional "phantom" row in the second read.
130 //
131 //
133 
134 #include <RDBC/TSQLConnection.h>
135 #include <RDBC/TSQLStatement.h>
139 #include <RDBC/TSQLDriverManager.h>
140 #include <RDBC/TSQLResultSet.h>
141 #include <TList.h>
142 #include <TNamed.h>
143 
144 #include "MySQLConnectionPrivate.h"
145 
147 
148 
149 
150 //___________________________________________________________________
151 TSQLConnection::TSQLConnection( void* imp ):TSQL(imp)
152 {
153  // private constructor called by
154 
155  fImp = new ConnectionPrivate();
156  fListOfStatements = new TList();
157  fMetaData = new TSQLDatabaseMetaData(this,fImp)
158 }
159 
160 //___________________________________________________________________
161 TSQLConnection::TSQLConnection( const TString& connectString ):TSQL(0)
162 {
163  // Attempts to establish a connection to the given database
164  // by specified connection string. This string is simply
165  // a series of keyword/value pairs, searated by semicolons,
166  // that contains information used to establish the connection.
167  // The TSQLDriverManager attempts to select an appropriate driver
168  // from the set of registered drivers.
169  //
170  // Parameters:
171  // connectString usually something like:
172  // "dsn=minos;uid=scott;pwd=tiger"
173  //
174  // Throws:
175  // TSQLException - if a database access error occurs
176 
177  fImp = new ConnectionPrivate();
179  fListOfStatements = new TList();
180 }
181 
182 //___________________________________________________________________
184  const TString& username,
185  const TString& password ): TSQL(0)
186 {
187  // Attempts to establish a connection to the given Data Source Name (DSN).
188  // The TSQLDriverManager attempts to select an appropriate driver from
189  // the set of registered drivers.
190  //
191  // Parameters:
192  // url - URL string
193  // username - the database user on whose behalf the TSQLConnection
194  // is being made
195  // password - the user's password
196  //
197  // Throws:
198  // TSQLException - if a database access error occurs
199  //
200 
202  fImp = imp;
203 
204  imp->fUrl = url;
205 
206 // imp->fMYSQL.options.compress = compress;
207 // imp->fMYSQL.options.connect_timeout=connect_timeout;
208 // locked = kTRUE; mysql.options.my_cnf_file="my";
209 
210  if( mysql_real_connect( imp->fMYSQL, url.GetHost().Data(),
211  username.Data(), password.Data(),
212  url.GetDatabase().Data(),
213  url.GetPort(), const char *unix_socket, unsigned int client_flag) compress,
214  connect_timeout,socket_name, client_flag))
215  {
216  imp->fLocked = kFALSE;
217  imp->fIsConnected = kTRUE;
218 
219  } else {
220  imp->fLocked = kFALSE;
221  imp->fIsConnected = kFALSE;
222  Throw(new TSQLException(mysql_error(imp->fMYSQL),"",mysql_errno(imp->fMYSQL))); //
223  return;
224  }
225 
226  fMetaData = new TSQLDatabaseMetaData(this,fImp);
227  fListOfStatements = new TList();
228 }
229 
230 //___________________________________________________________________
232 {
233  // Destructor:
234  //
235  // - deallocate all statements produced by this connection
236  // - disconnect this connection
237 
238  Close();
239 }
240 
241 //___________________________________________________________________
243 {
244  // Creates a TSQLStatement object for sending SQL statements
245  // to the database. SQL statements without parameters are
246  // normally executed using TSQLStatement objects. If the
247  // same SQL statement is executed many times, it is more
248  // efficient to use a TSQLPreparedStatement. TSQLResultSet s
249  // created using the returned TSQLStatement will have
250  // forward-only type, and read-only concurrency, by default.
251  //
252  // Returns:
253  // a new TSQLStatement object
254  // zero - in case of error
255  // Throws:
256  // TSQLException - if a database access error occurs
257 
258  TSQLStatement* stmt = new TSQLStatement(this,imp);
259  fListOfStatements->Add(stmt);
260  return stmt;
261 }
262 
263 //___________________________________________________________________
265  Int_t resultSetConcurrency )
266 {
267  // Creates a TSQLStatement object that will generate TSQLResultSet
268  // objects with the given type and concurrency. This method is the
269  // same as the CreateStatement() method above, but it allows the
270  // default result set type and result set concurrency type to be
271  // overridden.
272  //
273  // Parameters:
274  // resultSetType - a result set type;
275  // see TSQLResultSet::kTYPE_XXX
276  // resultSetConcurrency - a concurrency type;
277  // see TSQLResultSet::kCONCUR_XXX
278  // Returns:
279  // a new TSQLStatement object
280  // Throws:
281  // TSQLException - if a database access error occurs
282 
283  TSQLStatement* stmt = new TSQLStatement(this,imp);
284  fListOfStatements->Add(stmt);
285  return stmt;
286 }
287 
288 //___________________________________________________________________
290  const TString& sql )
291 {
292  // Creates a TSQLPreparedStatement object for sending
293  // parameterized SQL statements to the database. A SQL statement
294  // with or without IN parameters can be pre-compiled and stored
295  // in a TSQLPreparedStatement object. This object can then be
296  // used to efficiently execute this statement multiple times.
297  //
298  // Note: This method is optimized for handling parametric SQL
299  // statements that benefit from precompilation.
300  // If the driver supports precompilation, the method
301  // PrepareStatement() will send the statement to the database
302  // for precompilation. Some drivers may not support precompilation.
303  // In this case, the statement may not be sent to the database
304  // until the TSQLPreparedStatement is executed. This has no direct
305  // effect on users; however, it does affect which method throws
306  // certain TSQLException s. Result sets created using the returned
307  // TSQLPreparedStatement will have forward-only type and read-only
308  // concurrency, by default.
309  //
310  // Parameters:
311  // sql - a SQL statement that may contain one or more '?'
312  // IN parameter placeholders
313  // Returns:
314  // a new TSQLPreparedStatement object containing the
315  // pre-compiled statement
316  // Throws:
317  // TSQLException - if a database access error occurs
318 
319  TSQLPreparedStatement* stmt = new TSQLPreparedStatement(this,imp);
320  fListOfStatements->Add(stmt);
321  return stmt;
322 }
323 
324 //___________________________________________________________________
326 {
327  // Creates a TSQLCallableStatement object for calling database
328  // stored procedures. The TSQLCallableStatement provides methods
329  // for setting up its IN and OUT parameters, and methods for
330  // executing the call to a stored procedure.
331  //
332  // Note: This method is optimized for handling stored procedure
333  // call statements. Some drivers may send the call statement
334  // to the database when the method PrepareCall() is done;
335  // others may wait until the TSQLCallableStatement is
336  // executed. This has no direct effect on users; however,
337  // it does affect which method throws certain SQLExceptions.
338  // Result sets created using the returned
339  // TSQLCallableStatement will have forward-only type and
340  // read-only concurrency, by default.
341  // Parameters:
342  // sql - a SQL statement that may contain one or more '?'
343  // parameter placeholders. Typically this statement is
344  // a function call escape string.
345  // Returns:
346  // a new TSQLCallableStatement object containing the
347  // pre-compiled SQL statement
348  // Throws:
349  // TSQLException - if a database access error occurs
350 
351  Throw( new TSQLSQLException("Callable statements not supported.", "S1C00",4000); //
352  return 0;
353 }
354 
355 //___________________________________________________________________
357  const TString& sql,
358  Int_t resultSetType,
359  Int_t resultSetConcurrency )
360 {
361  // Creates a TSQLPreparedStatement object that will generate
362  // TSQLResultSet objects with the given type and concurrency.
363  // This method is the same as the PrepareStatement() method above,
364  // but it allows the default result set type and result set
365  // concurrency type to be overridden.
366  //
367  // Parameters:
368  // resultSetType - a result set type;
369  // see TSQLResultSet::kTYPE_XXX
370  // resultSetConcurrency - a concurrency type;
371  // see TSQLResultSet::kCONCUR_XXX
372  // Returns:
373  // a new TSQLPreparedStatement object containing the
374  // pre-compiled SQL statement
375  // Throws:
376  // TSQLException - if a database access error occurs
377 
378  TSQLPreparedStatement* stmt = new TSQLPreparedStatement(this,imp);
379  fListOfStatements->Add(stmt);
380  return stmt;
381 }
382 
383 //___________________________________________________________________
385  const TString& sql,
386  Int_t resultSetType,
387  Int_t resultSetConcurrency )
388 {
389  // Creates a TSQLCallableStatement object that will generate
390  // TSQLResultSet objects with the given type and concurrency.
391  // This method is the same as the PrepareCall() method above,
392  // but it allows the default result set type and result set
393  // concurrency type to be overridden.
394  //
395  // Parameters:
396  // resultSetType - a result set type;
397  // see TSQLResultSet::kTYPE_XXX
398  // resultSetConcurrency - a concurrency type;
399  // see TSQLResultSet::kCONCUR_XXX
400  //
401  // Returns:
402  // a new TSQLCallableStatement object containing the
403  // pre-compiled SQL statement
404  // Throws:
405  // TSQLException - if a database access error occurs
406 
407  Throw( new TSQLSQLException("Callable statments not suppoted.", "S1C00",4000); //
408  return 0;
409 }
410 
411 //___________________________________________________________________
412 TString TSQLConnection::NativeSQL( const TString& sql )
413 {
414  // Converts the given SQL statement into the system's native SQL
415  // grammar. A driver may convert the sql grammar into its system's
416  // native SQL grammar prior to sending it; this method returns
417  // the native form of the statement that the driver would have
418  // sent.
419  //
420  // Parameters:
421  // sql - a SQL statement that may contain one or more '?'
422  // parameter placeholders
423  // Returns:
424  // the native form of this statement
425  // Throws:
426  // TSQLException - if a database access error occurs
427 
428  return sql;
429 }
430 
431 //___________________________________________________________________
432 void TSQLConnection::SetAutoCommit( Bool_t autoCommit )
433 {
434  // Sets this connection's auto-commit mode. If a connection is in
435  // auto-commit mode, then all its SQL statements will be executed
436  // and committed as individual transactions. Otherwise, its SQL
437  // statements are grouped into transactions that are terminated
438  // by a call to either the method commit or the method rollback.
439  // By default, new connections are in auto-commit mode. The commit
440  // occurs when the statement completes or the next execute occurs,
441  // whichever comes first. In the case of statements returning a
442  // TSQLResultSet, the statement completes when the last row
443  // of the TSQLResultSet has been retrieved or the TSQLResultSet
444  // has been closed. In advanced cases, a single statement may
445  // return multiple results as well as output parameter values.
446  // In these cases the commit occurs when all results and output
447  // parameter values have been retrieved.
448  //
449  // Parameters:
450  // autoCommit - kTRUE enables auto-commit;
451  // kFALSE disables auto-commit.
452  // Throws:
453  // TSQLException - if a database access error occurs
454 
455  if (autoCommit == kFALSE) {
456  Throw( new TSQLException("Cannot disable AUTO_COMMIT", "08003",)); //
457  }
458 }
459 
460 //___________________________________________________________________
462 {
463  // Gets the current auto-commit state.
464  //
465  // Returns:
466  // the current state of auto-commit mode
467  // Throws:
468  // TSQLException - if a database access error occurs
469  // See Also:
470  // SetAutoCommit(Bool_t)
471 
472  return kTRUE;
473 }
474 
475 //___________________________________________________________________
477 {
478  // Makes all changes made since the previous commit/rollback
479  // permanent and releases any database locks currently held by
480  // the TSQLConnection. This method should be used only when
481  // auto-commit mode has been disabled.
482  //
483  // Throws:
484  // TSQLException - if a database access error occurs
485  // See Also:
486  // SetAutoCommit(Bool_t)
487 
488  if( IsClosed() ) {
489  Throw( new TSQLException("Commit attempt on closed connection.", "08003", ); //
490  }
491 }
492 
493 //___________________________________________________________________
495 {
496  // Drops all changes made since the previous commit/rollback and
497  // releases any database locks currently held by this TSQLConnection.
498  // This method should be used only when auto-commit has been disabled.
499  //
500  // Throws:
501  // TSQLException - if a database access error occurs
502  // See Also:
503  // SetAutoCommit(Bool_t)
504 
505  if( IsClosed() ) {
506  Throw( new TSQLException("[RDBC]Rollback attempt on closed connection.", "08003", ); //
507  }
508 }
509 
510 //___________________________________________________________________
512 {
513  // Releases a TSQLConnection's database and resources immediately
514  // instead of waiting for them to be automatically released.
515  //
516  // Note: A TSQLConnection is automatically closed when it is
517  // garbage collected. Certain fatal errors also result in
518  // a closed TSQLConnection.
519  // Throws:
520  // TSQLException - if a database access error occurs
521 
522  if(IsClosed()) {
523  Throw(new TSQLException("[RDBC]Close attempt on closed connection.","08003",); //
524  return;
525  }
526 
527  TList* li = TSQLDriverManager::GetConnections();
528  li->Remove(this);
529 
530  if(fMetaData) delete fMetaData;
531 
532  if(fListOfStatements) { // deallocate all statements
533  fListOfStatements->Delete();
534  delete fListOfStatements;
535  }
536 
538  mysql_close(imp->fMYSQL);
539  fImp = 0;
540  Destroyed();
541  return;
542 }
543 
544 //___________________________________________________________________
546 {
547  // Tests to see if a TSQLConnection is closed.
548  //
549  // Returns:
550  // kTRUE if the connection is closed;
551  // kFALSE if it's still open
552  // Throws:
553  // TSQLException - if a database access error occurs
554 
556 
557  if(!imp->fIsClosed) {
558  // Test the connection
559  rs = execSQL(gPING_COMMAND, -1);
560  }
561 
562  imp->fIsClosed = !rs; // kFALSE if rs==0
563  return imp->fIsClosed;
564 }
565 
566 //___________________________________________________________________
568 {
569  // Gets the metadata regarding this connection's database.
570  // A TSQLConnection's database is able to provide information
571  // describing its tables, its supported SQL grammar, its
572  // stored procedures, the capabilities of this connection,
573  // and so on. This information is made available through a
574  // TSQLDatabaseMetaData object.
575  //
576  // Returns:
577  // a TSQLDatabaseMetaData object for this TSQLConnection
578  // Throws:
579  // TSQLException - if a database access error occurs
580 
581  return fMetaData;
582 }
583 
584 //___________________________________________________________________
585 void TSQLConnection::SetReadOnly( Bool_t readOnly )
586 {
587  // Puts this connection in read-only mode as a hint to enable
588  // database optimizations.
589  //
590  // Note: This method cannot be called while in the middle of a
591  // transaction.
592  //
593  // Parameters:
594  // readOnly - kTRUE enables read-only mode;
595  // kFALSE disables read-only mode.
596  // Throws:
597  // TSQLException - if a database access error occurs
598 
600 
601  if(IsClosed()) {
602  Throw(new TSQLException("SetReadOnly attempt on closed connection.","08003",); //
603  return;
604  }
605 
606  imp->fReadOnly = readOnly;
607 }
608 
609 //___________________________________________________________________
611 {
612  // Tests to see if the connection is in read-only mode.
613  //
614  // Returns:
615  // kTRUE if connection is read-only and kFALSE otherwise
616  // Throws:
617  // TSQLException - if a database access error occurs
618 
620  return imp->fReadOnly;
621 }
622 
623 //___________________________________________________________________
624 void TSQLConnection::SetCatalog( const TString& catalog )
625 {
626  // Sets a catalog name in order to select a subspace of this
627  // TSQLConnection's database in which to work. If the driver
628  // does not support catalogs, it will silently ignore this
629  // request.
630  //
631  // Throws:
632  // TSQLException - if a database access error occurs
633 
635 
636  if(IsClosed()) {
637  Throw(new TSQLException("SetCatalog attempt on closed connection.","08003",); //
638  return;
639  }
640 
641  if( !mysql_select_db(imp->fMYSQL,catalog) ) {
642  Throw( new TSQLException("SetCatalog attempt failed","",) );
643  return;
644  }
645  imp->fDatabase = catalog;
646 }
647 
648 //___________________________________________________________________
650 {
651  // Returns the TSQLConnection's current catalog name.
652  //
653  // Returns:
654  // the current catalog name or null string
655  // Throws:
656  // TSQLException - if a database access error occurs
657 
659 
660  if(IsClosed()) {
661  Throw(new TSQLException("GetCatalog attempt on closed connection.","08003",); //
662  return "";
663  }
664 
665  return imp->fDatabase;
666 }
667 
668 //___________________________________________________________________
670 {
671  // Attempts to change the transaction isolation level to the one
672  // given. The constants defined in the interface TSQLConnection
673  // are the possible transaction isolation levels.
674  //
675  // Note: This method cannot be called while in the middle of a
676  // transaction.
677  //
678  // Parameters:
679  // level - one of the kTRANSACTION_XXX isolation values with
680  // the exception of kTRANSACTION_NONE;
681  // some databases may not support other values
682  // Throws:
683  // TSQLException - if a database access error occurs
684  //
685  // See Also:
686  // TSQLDatabaseMetaData::SupportsTransactionIsolationLevel(Int_t)
687 
688  if(IsClosed()) {
689  Throw(new TSQLException("Transaction Isolation Levels are not supported.","S1C00",4000); //
690  }
691  return;
692 }
693 
694 //___________________________________________________________________
696 {
697  // Gets this TSQLConnection's current transaction isolation level.
698  //
699  // Returns:
700  // the current kTRANSACTION_XXX mode value
701  // Throws:
702  // TSQLException - if a database access error occurs
703 
705 }
706 
707 //___________________________________________________________________
709 {
710  // Returns kTRUE if tracing is enabled on this connection
711 
712  Throw(new TSQLException("Tracing is not enable","S1C00",4000));
713  return kFALSE;
714 }
715 
716 //___________________________________________________________________
718 {
719  // Sets tracing on or off
720 
721  Throw(new TSQLException("Tracing is not enable","S1C00",4000));
722 }
723 
724 //___________________________________________________________________
726 {
727  // Returns the file tracing is currently written to
728 
729  Throw(new TSQLException("Tracing is not enable","S1C00",4000));
730  return "";
731 }
732 
733 //___________________________________________________________________
734 void TSQLConnection::SetTraceFile( const TString& fn )
735 {
736  // Sets the file tracing is written to
737 
738  Throw(new TSQLException("Tracing is not enable","S1C00",4000));
739 }
740 
741 //___________________________________________________________________
743 {
744  // Returns kTRUE if batch are supported
745  //
746  // Throws:
747  // TSQLException - if a database access error occurs
748 
749  return kFALSE; // not ... for a moment
750 }
751 
752 //___________________________________________________________________
753 void TSQLConnection::SetURL(const TString& url)
754 {
755  // sets URL string
756 
758  imp->fURL = url;
759  fMetaData->SetURL(url);
760 }
761 
763 //___________________________________________________________________
764 const char* s(Bool_t b)
765 {
766  //
767 
768  return b?"Yes":"No";
769 }
770 
771 //___________________________________________________________________
772 TString maybeQuote(const TString& str, const TString& qc)
773 {
774  //
775 
776  TString res;
777  if(qc!=" ") res = qc + str + qc;
778  else res = str;
779  return res;
780 }
781 
782 //___________________________________________________________________
784  Int_t rsType, const char* name)
785 {
786  // prints result set info
787 
788  if(md->SupportsResultSetType(rsType)) {
789  printf("%s\n",name);
790 
792  printf(" + kCONCUR_READ_ONLY\n");
793  }
794 
796  printf(" + kCONCUR_UPDATABLE\n");
797  }
798 
799  if(md->OwnInsertsAreVisible(rsType)) {
800  printf(" Own inserts are visible\n");
801  }
802 
803  if(md->OwnUpdatesAreVisible(rsType)) {
804  printf(" Own updates are visible\n");
805  }
806  if(md->OwnDeletesAreVisible(rsType)) {
807  printf(" Own deletes are visible\n");
808  }
809  }
810 }
811 
812 
813 //___________________________________________________________________
814 struct {
815  int id;
816  const char* name;
817  } levels[] = {
818  { kTRANSACTION_READ_UNCOMMITTED, "kTRANSACTION_READ_UNCOMMITTED" },
819  { kTRANSACTION_READ_COMMITTED, "kTRANSACTION_READ_COMMITTED" },
820  { kTRANSACTION_REPEATABLE_READ, "kTRANSACTION_REPEATABLE_READ" },
821  { kTRANSACTION_SERIALIZABLE, "kTRANSACTION_SERIALIZABLE" },
822  { 0,NULL }
823  };
824 
825 //___________________________________________________________________
827 {
828  //prints out transaction info
829 
830  TString str;
831 
832  str = s(md->SupportsTransactions());
833  printf("Supports transactions : %s\n",str.Data());
834 
835  printf("\nTransaction support \n");
836  printf("---------------------------------------------------\n");
837 
838  if(!md->SupportsTransactions()) {
839  printf("This datasource does not support transactions.\n\n");
840  return;
841  }
842 
843  int defIsolation=md->GetDefaultTransactionIsolation();
844 
845  for(int i=0; levels[i].name!=NULL; i++) {
847  str = " +";
848  str += levels[i].name;
849  str += (levels[i].id==defIsolation) ? " (default)" :"";
850  printf("%s\n",str.Data());
851  }
852  }
853 
854  // the longest method name I've ever seen!
856  printf(" Both DML and DDL can be used within a transaction\n");
858  printf(" Only DML can be used within a transaction\n");
859  } else if(md->DataDefinitionCausesTransactionCommit()) {
860  printf(" DDL causes commit\n");
861  } else if(md->DataDefinitionIgnoredInTransactions()) {
862  printf(" DDL is ignored in transactions\n");
863  }
864 }
865 
866 //___________________________________________________________________
868 {
869  //
870 
871  Bool_t cdml = md->SupportsCatalogsInDataManipulation();
872  Bool_t cproc = md->SupportsCatalogsInProcedureCalls();
873  Bool_t ctd = md->SupportsCatalogsInTableDefinitions();
875  Bool_t cpd = md->SupportsCatalogsInPrivilegeDefinitions();
876  Bool_t hasCatalogs = cdml || cproc || ctd || cid || cpd;
877 
878  if(hasCatalogs) {
879  printf("Supported catalog uses\n");
880  printf("--------------------------------------------------- \n");
881  printf("Data manipulation : %s\n",s(cdml) );
882  printf("Procedure calls : %s\n",s(cproc) );
883  printf("Table definitions : %s\n",s(ctd) );
884  printf("Index definitions : %s\n",s(cid) );
885  printf("Privilege definitions: %s\n",s(cpd) );
886  } else {
887  printf("This datasource does not support catalogs\n");
888  }
889  printf("\n");
890 
891  TString id = md->GetTableTerm();
892  if(hasCatalogs) {
893  TString catSep;
894  TString catTerm;
895  catSep = md->GetCatalogSeparator();
896  catTerm = md->GetCatalogTerm();
897  if(md->IsCatalogAtStart()) {
898  id = catTerm + catSep + id;
899  } else {
900  id = id + catSep + catTerm;
901  }
902  }
903  printf("Preferred table identifier format: %s\n",id.Data());
904 }
905 
906 //___________________________________________________________________
908 {
909  //
910 
911  Bool_t sdml = md->SupportsSchemasInDataManipulation();
912  Bool_t sproc = md->SupportsSchemasInProcedureCalls();
913  Bool_t std = md->SupportsSchemasInTableDefinitions();
914  Bool_t sid = md->SupportsSchemasInIndexDefinitions();
915  Bool_t spd = md->SupportsSchemasInPrivilegeDefinitions();
916  Bool_t hasSchemas=sdml || sproc || std || sid || spd;
917 
918  if(hasSchemas) {
919  printf("Supported schema uses\n");
920  printf("--------------------------------------------------- \n");
921  printf("Data manipulation : %s\n",s(sdml) );
922  printf("Procedure calls : %s\n",s(sproc) );
923  printf("Table definitions : %s\n",s(std) );
924  printf("Index definitions : %s\n",s(sid) );
925  printf("Privilege definitions: %s\n",s(spd) );
926  } else {
927  printf("This datasource does not support schemas\n");
928  }
929  printf("\n");
930 
931  TString idq = md->GetIdentifierQuoteString();
932  // space means no quoting supported
933 
934  TString id = md->GetTableTerm();
935 }
936 
937 //___________________________________________________________________
939 {
940  //
941 
942  TString str;
943 
944  str = md->GetDatabaseProductName();
945  printf("Product name : %s\n",str.Data());
946 
947  str = md->GetDatabaseProductVersion();
948  printf("Product version : %s\n",str.Data());
949 }
950 
951 //___________________________________________________________________
953 {
954  //
955 
956  TString str;
957 
958  str = md->GetDriverName();
959  printf("Driver name : %s\n",str.Data());
960 
961  str = md->GetDriverVersion();
962  printf("Driver version : %s\n",str.Data());
963 }
964 
965 //___________________________________________________________________
967 {
968  //
969 
970  TString str;
971 
972  str = md->GetSystemFunctions();
973  printf("Supported system functions \n");
974  printf("--------------------------------------------------- \n");
975  printf("%s\n\n",str.Data());
976 
977  printf("Supported string functions\n");
978  printf("--------------------------------------------------- \n");
979  str = md->GetStringFunctions();
980  printf("%s\n\n",str.Data());
981 
982  printf("Supported time/date functions\n");
983  printf("--------------------------------------------------- \n");
984  str = md->GetTimeDateFunctions();
985  printf("%s\n\n",str.Data());
986 
987  printf("Supported numeric functions\n");
988  printf("---------------------------------------------------\n");
989  str = md->GetNumericFunctions();
990  printf("%s\n\n",str.Data());
991 }
992 
993 //___________________________________________________________________
995 {
996  //
997 
998  TString str;
999 
1000  printf("Non-ODBC SQL keywords\n");
1001  printf("--------------------------------------------------- \n");
1002  str = md->GetSQLKeywords();
1003  printf("%s\n\n",str.Data());
1004 }
1005 
1006 //___________________________________________________________________
1007 void TSQLConnection::Print(Option_t *option) const
1008 {
1009  // Prints out information about this connection
1010  //
1011  // If option contains:
1012  //
1013  // 'r' - prints result set info
1014  // 't' - prints out transaction info
1015  // 'p' - prints out product info
1016  // 'd' - prints out driver info
1017  // 'f' - prints out supported functions
1018  // 'k' - prints out Non-ODBC SQL keywords
1019  // 'c' - prints out catalog info
1020  // 's' - prints out shema info
1021  // 'a' - prints out everything
1022 
1023  TString opt = option;
1024  opt.ToLower();
1025 
1026  printf("Connection to :\t%s\n",fMetaData->GetURL().Data());
1027  printf("=================================================== \n\n");
1028 
1029  if(opt.Contains("p") || opt.Contains("a")) {
1031  printf("=================================================== \n\n");
1032  }
1033  if(opt.Contains("d") || opt.Contains("a")) {
1035  printf("=================================================== \n\n");
1036  }
1037  if(opt.Contains("t") || opt.Contains("a")) {
1039  printf("=================================================== \n\n");
1040  }
1041  if(opt.Contains("f") || opt.Contains("a")) {
1043  printf("=================================================== \n\n");
1044  }
1045  if(opt.Contains("k") || opt.Contains("a")) {
1047  printf("=================================================== \n\n");
1048  }
1049 
1050  if(opt.Contains("r") || opt.Contains("a")) {
1051  printf("Supported TSQLResultSet types\n");
1052  printf("--------------------------------------------------- \n");
1053  rsInfo(fMetaData,kTYPE_FORWARD_ONLY,"kTYPE_FORWARD_ONLY");
1054  rsInfo(fMetaData,kTYPE_SCROLL_INSENSITIVE,"kTYPE_SCROLL_INSENSITIVE");
1055  rsInfo(fMetaData,kTYPE_SCROLL_SENSITIVE,"kTYPE_SCROLL_SENSITIVE");
1056  printf("\n=================================================== \n");
1057  }
1058  if(opt.Contains("c") || opt.Contains("a")) {
1060  printf("=================================================== \n\n");
1061  }
1062  if(opt.Contains("s") || opt.Contains("a")) {
1064  printf("=================================================== \n\n");
1065  }
1066 }
1067 
1068 //___________________________________________________________________
1069 const char* TSQLConnection::GetName() const
1070 {
1071  // returns dsn/url
1072 
1073  return fMetaData->GetURL().Data();
1074 }
1075 
1076 //___________________________________________________________________
1077 const char* TSQLConnection::GetTitle() const
1078 {
1079  // returns nothing
1080 
1081  return "";
1082 }
1083 
1085 
1086 //___________________________________________________________________
1087 void TSQLConnection::SetLoginTimeout( Int_t seconds )
1088 {
1089  // Sets the maximum time in seconds that a driver will wait while
1090  // attempting to connect to a database. Set to 0 to disable.
1091  //
1092  // Parameters:
1093  // seconds - the login time limit in seconds
1094 
1096  imp->fLoginTimeout = seconds >= 0 ? seconds : 0;
1097 }
1098 
1099 //___________________________________________________________________
1100 Int_t TSQLConnection::GetLoginTimeout()
1101 {
1102  // Gets the maximum time in seconds that a driver can wait when
1103  // attempting to log in to a database.
1104  //
1105  // Returns:
1106  // the driver login time limit in seconds, or 0 if disabled.
1107 
1109  return imp->fLoginTimeout;
1110 }
1111 
1112 //___________________________________________________________________
1113 void TSQLConnection::Shutdown()
1114 {
1115  // Should be called before an application is to exit
1116 
1118 
1119  Bool_t suc = !(mysql_shutdown(imp->fMYSQL));
1120  // if(!suc) Throw MysqlBadQuery(error());
1121  return;
1122 }
1123 
1124 //___________________________________________________________________
1125 TList* TSQLConnection::RefreshDrivers(TList* gDrivers)
1126 {
1127  // Fetch a list of all of currently loaded drivers
1128  // to which the current caller has access.
1129 
1130  if(!gDrivers) return 0;
1131 
1132  return gDrivers;
1133 }
1134 
1135 //___________________________________________________________________
1136 TList* TSQLConnection::RefreshDataSources(TList* gDataSources)
1137 {
1138  // Fetch a list of of all available data sources ( TSQLUrl objects)
1139 
1140  if(!gDataSources) return 0;
1141 
1142  gDataSources->Delete(); // remove all
1143  TSQLUrl* url;
1144 
1145  return gDataSources;
1146 }