Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:22:02

0001 // $Id: MySQLConnection.cxx,v 1.1.1.1 2004/02/18 20:58:02 dave Exp $
0002 //*-- Author : Valeriy Onuchin 22/02/2001 
0003 //
0004 // RDBC driver to MySQL database implemented with MySQL C API.
0005 //
0006 // ++ The code consists of some parts stolen from mm JDBC and  
0007 //    MyODBC ODBC drivers and other mysql-related open sources.
0008 //
0009 
0010 /////////////////////////////////////////////////////////////////////
0011 //
0012 //
0013 // A connection (session) with a specific database. Within the context 
0014 // of a TSQLConnection, SQL statements are executed and results are 
0015 // returned.  A TSQLConnection's database is able to provide information 
0016 // describing its tables, its supported SQL grammar, its stored procedures, 
0017 // the capabilities of this connection, and so on. This information is
0018 // obtained with the GetMetaData() method. 
0019 //
0020 // See also:
0021 //    TSQLDriverManager::GetConnection(TString)
0022 //    TSQLStatement TSQLPreparedStatement TSQLCallableStatement
0023 //    TSQLResultSet TSQLDatabaseMetaData
0024 //
0025 ///////////////////////////////////////////////////////////////////////
0026 // 
0027 // A transaction is a recoverable sequence of SQL operations grouped
0028 // as a single unit. The initiation and termination of transaction 
0029 // define the following points of data consistency within an 
0030 // application process; either all SQL operations within a transaction 
0031 // are applied to the data source (committed), or the effects of all
0032 // SQL operations within a transaction are completely "undone"
0033 // (rolled back). 
0034 //   RDBC provides the following modes of transaction processing 
0035 // that determine haw and when transactions are to be committed (or,
0036 // if possible rolled back):
0037 // 
0038 //    - Auto-commit mode
0039 //    - Manual-commit mode 
0040 //
0041 //  defined by TSQLConnection::SetAutoCommit( Bool_t autoCommit )
0042 //
0043 ///////////////////////////////////////////////////////////////////
0044 //
0045 // In multi-user database system, transactions can occur 
0046 // simultaneously, and each transaction has potential to interfere
0047 // with another one. When transactions are not isolated from each
0048 // other in multi-user enviroments, the following three types of
0049 // events can occur:
0050 //___________________________________________________________________
0051 //
0052 // Dirty Read: 
0053 //
0054 //    Transaction 1 changes a row. Transaction 2 reads
0055 // the changed row before Transacion 1 commits the change. If
0056 // Transaction 1 rolls back the change, Transacion 2 will have
0057 // read a row that is considered to have never existed
0058 //
0059 //___________________________________________________________________
0060 //
0061 // Nonrepeatable Read:
0062 //
0063 //    Transaction 1 reads a row. Transaction 2 updates or deletes
0064 // that row and commits the change. If Transaction 1 attempts
0065 // to reread the row, it will receive different row values or 
0066 //  discover that the row has been deleted.
0067 //
0068 //___________________________________________________________________
0069 //
0070 // Phantom: 
0071 //
0072 //    Transaction 1  reads a set of rows that satisfy some search
0073 // criteria. Transaction 2 generates one or more rows ( either 
0074 // through inserts or updates ) that match the search criteria
0075 // If transacion 1 re-executes the statement that reads the rows,
0076 // it receives a different set of rows.
0077 //
0078 //////////////////////////////////////////////////////////////////////
0079 //
0080 // ODBC defines four levels of transaction isolation that can,
0081 // prevent all, some, or none of these events from occurring. 
0082 // They are:
0083 //___________________________________________________________________
0084 //
0085 // kTRANSACTION_NONE
0086 //
0087 // Indicates that transactions are not supported.
0088 //
0089 //___________________________________________________________________
0090 //
0091 // kTRANSACTION_READ_UNCOMMITTED
0092 // 
0093 // Dirty reads, non-repeatable reads and phantom reads can occur.
0094 // This level allows a row changed by one transaction to be read 
0095 // by another transaction before any changes in that row have been 
0096 // committed (a "dirty read"). If any of the changes are rolled back,
0097 // the second transaction will have retrieved an invalid row.
0098 //
0099 //___________________________________________________________________
0100 //
0101 // kTRANSACTION_READ_COMMITTED
0102 //
0103 //
0104 // Dirty reads are prevented; non-repeatable reads and phantom reads
0105 // can occur. This level only prohibits a transaction from reading a 
0106 // row with uncommitted changes in it.
0107 //
0108 //___________________________________________________________________
0109 //
0110 // kTRANSACTION_REPEATABLE_READ
0111 //
0112 // Dirty reads and non-repeatable reads are prevented; phantom reads 
0113 // can occur. This level prohibits a transaction from reading a row 
0114 // with uncommitted changes in it, and it also prohibits the situation 
0115 // where one transaction reads a row, a second transaction alters the 
0116 // row, and the first transaction rereads the row, getting different 
0117 // values the second   time (a "non-repeatable read").
0118 //
0119 //___________________________________________________________________
0120 //
0121 // kTRANSACTION_SERIALIZABLE
0122 //
0123 // Dirty reads, non-repeatable reads and phantom reads are prevented.
0124 // This level includes the prohibitions in kTRANSACTION_REPEATABLE_READ
0125 // and further prohibits the situation where one transaction reads 
0126 // all rows that satisfy a WHERE condition, a second transaction 
0127 // inserts a row that satisfies that WHERE condition, and the first 
0128 // transaction rereads for the same condition, retrieving the 
0129 // additional "phantom" row in the second read.
0130 //
0131 //
0132 /////////////////////////////////////////////////////////////////////
0133 
0134 #include <RDBC/TSQLConnection.h>
0135 #include <RDBC/TSQLStatement.h>
0136 #include <RDBC/TSQLPreparedStatement.h>
0137 #include <RDBC/TSQLCallableStatement.h>
0138 #include <RDBC/TSQLDatabaseMetaData.h>
0139 #include <RDBC/TSQLDriverManager.h>
0140 #include <RDBC/TSQLResultSet.h>
0141 #include <TList.h>
0142 #include <TNamed.h>
0143 
0144 #include "MySQLConnectionPrivate.h"
0145 
0146 ClassImpQ(TSQLConnection)
0147 
0148 
0149 ///////////////////////////////////////////////////////////////////// 
0150 //___________________________________________________________________
0151 TSQLConnection::TSQLConnection( void* imp ):TSQL(imp)
0152 {
0153    // private constructor called by 
0154  
0155    fImp = new ConnectionPrivate();
0156    fListOfStatements = new TList();
0157    fMetaData = new TSQLDatabaseMetaData(this,fImp)
0158 }
0159 
0160 //___________________________________________________________________
0161 TSQLConnection::TSQLConnection( const TString&  connectString ):TSQL(0)
0162 {
0163    // Attempts to establish a connection to the given database 
0164    // by specified connection string. This string is simply
0165    // a series of keyword/value pairs, searated by semicolons,
0166    // that contains information used to establish the connection.
0167    // The TSQLDriverManager attempts to select an appropriate driver
0168    // from the set of registered drivers.
0169    //
0170    // Parameters:
0171    //    connectString usually something like:
0172    //                   "dsn=minos;uid=scott;pwd=tiger"
0173    //
0174    // Throws:
0175    //    TSQLException - if a database access error occurs
0176 
0177    fImp = new ConnectionPrivate();
0178    fMetaData = new TSQLDatabaseMetaData(this,fImp)
0179    fListOfStatements = new TList();
0180 }
0181 
0182 //___________________________________________________________________
0183 TSQLConnection::TSQLConnection( const TString& url, 
0184                                 const TString& username, 
0185                                 const TString& password ): TSQL(0)
0186 {
0187    // Attempts to establish a connection to the given Data Source Name (DSN). 
0188    // The TSQLDriverManager attempts to select an appropriate driver  from  
0189    // the set of registered drivers.
0190    //
0191    // Parameters:
0192    //    url      - URL string
0193    //    username - the database user on whose behalf the TSQLConnection
0194    //                is being made
0195    //    password - the user's password
0196    //
0197    // Throws:
0198    //    TSQLException - if a database access error occurs
0199    //
0200 
0201    MySQLConnectionPrivate* imp = new MySQLConnectionPrivate();
0202    fImp = imp;
0203      
0204    imp->fUrl = url;
0205 
0206 //   imp->fMYSQL.options.compress = compress;
0207 //   imp->fMYSQL.options.connect_timeout=connect_timeout;
0208 //   locked = kTRUE; mysql.options.my_cnf_file="my";
0209  
0210    if( mysql_real_connect( imp->fMYSQL, url.GetHost().Data(), 
0211                                  username.Data(), password.Data(), 
0212                                  url.GetDatabase().Data(),
0213                                  url.GetPort(),  const char *unix_socket, unsigned int client_flag) compress,
0214        connect_timeout,socket_name, client_flag))
0215    {
0216       imp->fLocked = kFALSE;
0217       imp->fIsConnected = kTRUE;
0218    
0219    } else {
0220       imp->fLocked = kFALSE;
0221       imp->fIsConnected = kFALSE;
0222       Throw(new TSQLException(mysql_error(imp->fMYSQL),"",mysql_errno(imp->fMYSQL)));  //
0223       return;
0224    }
0225 
0226    fMetaData = new TSQLDatabaseMetaData(this,fImp);
0227    fListOfStatements = new TList(); 
0228 }
0229 
0230 //___________________________________________________________________
0231 TSQLConnection::~TSQLConnection()
0232 {
0233    // Destructor:
0234    //
0235    // - deallocate all statements produced by this connection
0236    // - disconnect this connection 
0237 
0238    Close();
0239 }
0240 
0241 //___________________________________________________________________
0242 TSQLStatement* TSQLConnection::CreateStatement()
0243 { 
0244    // Creates a TSQLStatement object for sending SQL statements 
0245    // to the database. SQL statements without parameters are 
0246    // normally executed using TSQLStatement objects. If the
0247    // same SQL statement is executed many times, it is more 
0248    // efficient to use a TSQLPreparedStatement. TSQLResultSet s 
0249    // created using the returned TSQLStatement will have 
0250    // forward-only type, and read-only concurrency, by default.
0251    //
0252    // Returns:
0253    //      a new TSQLStatement object
0254    //      zero - in case of  error  
0255    // Throws:
0256    //       TSQLException - if a database access error occurs     
0257 
0258    TSQLStatement* stmt = new TSQLStatement(this,imp);
0259    fListOfStatements->Add(stmt);
0260    return stmt;
0261 }
0262 
0263 //___________________________________________________________________
0264 TSQLStatement* TSQLConnection::CreateStatement( Int_t resultSetType,
0265                                           Int_t resultSetConcurrency )
0266 { 
0267    // Creates a TSQLStatement object that will generate TSQLResultSet
0268    // objects with the given type and concurrency. This method is the 
0269    // same as the CreateStatement() method above, but it allows the 
0270    // default result set type and result set concurrency type to be 
0271    // overridden.
0272    //
0273    // Parameters:
0274    //       resultSetType - a result set type; 
0275    //                       see TSQLResultSet::kTYPE_XXX
0276    //       resultSetConcurrency - a concurrency type; 
0277    //                       see TSQLResultSet::kCONCUR_XXX
0278    // Returns:
0279    //       a new TSQLStatement object
0280    // Throws:
0281    //       TSQLException - if a database access error occurs
0282 
0283    TSQLStatement* stmt = new TSQLStatement(this,imp);
0284    fListOfStatements->Add(stmt);
0285    return stmt; 
0286 }
0287 
0288 //___________________________________________________________________
0289 TSQLPreparedStatement* TSQLConnection::PrepareStatement(
0290                                                 const TString& sql )
0291 {
0292    // Creates a TSQLPreparedStatement object for sending 
0293    // parameterized SQL statements to the database. A SQL statement 
0294    // with or without IN parameters can be pre-compiled and stored 
0295    // in a TSQLPreparedStatement object. This object can then be 
0296    // used to efficiently execute this statement multiple times. 
0297    //
0298    // Note: This method is optimized for handling parametric SQL
0299    //       statements that benefit from precompilation.
0300    //       If the driver supports precompilation, the method 
0301    //       PrepareStatement() will send the statement to the database 
0302    //       for precompilation. Some drivers may not support precompilation. 
0303    //       In this case, the statement may not be sent to the database 
0304    //       until the TSQLPreparedStatement is executed. This has no direct
0305    //       effect on users; however, it does affect which method throws 
0306    //       certain TSQLException s. Result sets created using the returned 
0307    //       TSQLPreparedStatement will have forward-only type and read-only
0308    //       concurrency, by default.
0309    //
0310    // Parameters:
0311    //       sql - a SQL statement that may contain one or more '?' 
0312    //       IN parameter placeholders
0313    // Returns:
0314    //       a new TSQLPreparedStatement object containing the 
0315    //       pre-compiled statement
0316    // Throws:
0317    //       TSQLException - if a database access error occurs
0318 
0319    TSQLPreparedStatement* stmt = new TSQLPreparedStatement(this,imp); 
0320    fListOfStatements->Add(stmt);
0321    return stmt;
0322 }
0323 
0324 //___________________________________________________________________
0325 TSQLCallableStatement* TSQLConnection::PrepareCall( const TString& sql )
0326 {  
0327    // Creates a TSQLCallableStatement object for calling database 
0328    // stored procedures. The TSQLCallableStatement provides methods 
0329    // for setting up its IN and OUT parameters, and methods for 
0330    // executing the call to a stored procedure. 
0331    //
0332    // Note: This method is optimized for handling stored procedure 
0333    //       call statements. Some drivers may send the call statement 
0334    //       to the database when the method PrepareCall() is done; 
0335    //       others may wait until the TSQLCallableStatement is 
0336    //       executed. This has no direct effect on users; however, 
0337    //       it does affect which method throws certain SQLExceptions. 
0338    //       Result sets created using the returned 
0339    //       TSQLCallableStatement will have forward-only type and 
0340    //       read-only concurrency, by default.
0341    // Parameters:
0342    //       sql - a SQL statement that may contain one or more '?'
0343    //             parameter placeholders. Typically this statement is
0344    //             a function call escape string.
0345    // Returns:
0346    //       a new TSQLCallableStatement object containing the 
0347    //       pre-compiled SQL statement
0348    // Throws:
0349    //       TSQLException - if a database access error occurs
0350 
0351    Throw( new TSQLSQLException("Callable statements not supported.", "S1C00",4000); // 
0352    return 0;
0353 }
0354 
0355 //___________________________________________________________________
0356 TSQLPreparedStatement* TSQLConnection::PrepareStatement(
0357                                           const TString& sql,
0358                                           Int_t resultSetType, 
0359                                           Int_t resultSetConcurrency )
0360 {
0361    // Creates a TSQLPreparedStatement object that will generate
0362    // TSQLResultSet objects with the given type and concurrency. 
0363    // This method is the same as the PrepareStatement() method above,
0364    // but it allows the default result set type and result set 
0365    // concurrency type to be overridden.
0366    //   
0367    // Parameters:
0368    //       resultSetType - a result set type; 
0369    //                       see TSQLResultSet::kTYPE_XXX
0370    //       resultSetConcurrency - a concurrency type; 
0371    //                              see TSQLResultSet::kCONCUR_XXX
0372    // Returns:
0373    //       a new TSQLPreparedStatement object containing the 
0374    //       pre-compiled SQL statement
0375    // Throws:
0376    //       TSQLException - if a database access error occurs
0377 
0378    TSQLPreparedStatement* stmt = new TSQLPreparedStatement(this,imp);
0379    fListOfStatements->Add(stmt);
0380    return stmt;
0381 }
0382 
0383 //___________________________________________________________________
0384 TSQLCallableStatement* TSQLConnection::PrepareCall( 
0385                                           const TString& sql, 
0386                                           Int_t resultSetType, 
0387                                           Int_t resultSetConcurrency )
0388 {
0389    // Creates a TSQLCallableStatement object that will generate
0390    // TSQLResultSet objects with the given type and concurrency. 
0391    // This method is the same as the PrepareCall() method above,
0392    // but it allows the default result set type and result set 
0393    // concurrency type to be overridden.
0394    //
0395    // Parameters:
0396    //       resultSetType - a result set type; 
0397    //                         see TSQLResultSet::kTYPE_XXX
0398    //       resultSetConcurrency - a concurrency type;
0399    //                         see TSQLResultSet::kCONCUR_XXX
0400    //
0401    // Returns:
0402    //       a new TSQLCallableStatement object containing the 
0403    //       pre-compiled SQL statement
0404    // Throws:
0405    //       TSQLException - if a database access error occurs
0406 
0407    Throw( new TSQLSQLException("Callable statments not suppoted.", "S1C00",4000); // 
0408    return 0;
0409 }
0410 
0411 //___________________________________________________________________
0412 TString TSQLConnection::NativeSQL( const TString& sql )
0413 {
0414    // Converts the given SQL statement into the system's native SQL
0415    // grammar. A driver may convert the sql grammar into its system's
0416    // native SQL grammar prior to sending it; this method returns 
0417    // the native form of the statement that the driver would have 
0418    // sent.
0419    //
0420    // Parameters:
0421    //       sql - a SQL statement that may contain one or more '?'
0422    //             parameter placeholders
0423    // Returns:
0424    //       the native form of this statement
0425    // Throws:
0426    //       TSQLException - if a database access error occurs
0427 
0428    return sql;
0429 }
0430 
0431 //___________________________________________________________________
0432 void TSQLConnection::SetAutoCommit( Bool_t autoCommit )
0433 {
0434    // Sets this connection's auto-commit mode. If a connection is in
0435    // auto-commit mode, then all its SQL statements will be executed 
0436    // and committed as individual transactions. Otherwise, its SQL 
0437    // statements are grouped into transactions that are terminated 
0438    // by a call to either the method commit or the method rollback. 
0439    // By default, new connections are in auto-commit mode. The commit
0440    // occurs when the statement completes or the next execute occurs,
0441    // whichever comes first. In the case of statements returning a 
0442    // TSQLResultSet, the statement completes when the last row
0443    // of the TSQLResultSet has been retrieved or the TSQLResultSet 
0444    // has been closed. In advanced cases, a single statement may 
0445    // return multiple results as well as output parameter values. 
0446    // In these cases the commit occurs when all results and output 
0447    // parameter values have been retrieved.
0448    //
0449    // Parameters:
0450    //       autoCommit - kTRUE enables auto-commit; 
0451    //                    kFALSE disables auto-commit.
0452    // Throws:
0453    //       TSQLException - if a database access error occurs
0454    
0455    if (autoCommit == kFALSE) {
0456       Throw( new TSQLException("Cannot disable AUTO_COMMIT", "08003",)); //
0457    }
0458 }
0459 
0460 //___________________________________________________________________
0461 Bool_t TSQLConnection::GetAutoCommit()
0462 { 
0463    // Gets the current auto-commit state.
0464    //   
0465    // Returns:
0466    //       the current state of auto-commit mode
0467    // Throws:
0468    //       TSQLException - if a database access error occurs
0469    // See Also: 
0470    //       SetAutoCommit(Bool_t)
0471 
0472    return  kTRUE;
0473 }
0474 
0475 //___________________________________________________________________
0476 void TSQLConnection::Commit()
0477 {
0478    // Makes all changes made since the previous commit/rollback
0479    // permanent and releases any database locks currently held by 
0480    // the TSQLConnection. This method should be used only when 
0481    // auto-commit mode has been disabled.
0482    //
0483    // Throws:
0484    //       TSQLException - if a database access error occurs
0485    // See Also: 
0486    //       SetAutoCommit(Bool_t)
0487 
0488    if( IsClosed() ) {
0489       Throw( new TSQLException("Commit attempt on closed connection.", "08003", ); //
0490    }
0491 }
0492 
0493 //___________________________________________________________________
0494 void TSQLConnection::Rollback()
0495 { 
0496    // Drops all changes made since the previous commit/rollback and
0497    // releases any database locks currently held by this TSQLConnection. 
0498    // This method should be used only when auto-commit has been disabled.
0499    //
0500    // Throws:
0501    //       TSQLException - if a database access error occurs
0502    // See Also: 
0503    //       SetAutoCommit(Bool_t)
0504 
0505    if( IsClosed() ) {
0506       Throw( new TSQLException("[RDBC]Rollback attempt on closed connection.", "08003", ); //
0507    }
0508 }
0509 
0510 //___________________________________________________________________
0511 void TSQLConnection::Close()
0512 {
0513    // Releases a TSQLConnection's database and resources immediately
0514    // instead of waiting for them to be automatically released. 
0515    //
0516    // Note: A TSQLConnection is automatically closed when it is 
0517    //       garbage collected. Certain fatal errors also result in 
0518    //       a closed TSQLConnection.
0519    // Throws:
0520    //       TSQLException - if a database access error occurs
0521 
0522    if(IsClosed()) { 
0523       Throw(new TSQLException("[RDBC]Close attempt on closed connection.","08003",); //
0524       return;
0525    }
0526 
0527    TList* li = TSQLDriverManager::GetConnections();
0528    li->Remove(this);
0529 
0530    if(fMetaData) delete fMetaData;
0531 
0532    if(fListOfStatements) {    // deallocate all statements
0533       fListOfStatements->Delete();
0534       delete fListOfStatements;
0535    }
0536 
0537    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0538    mysql_close(imp->fMYSQL);
0539    fImp = 0;
0540    Destroyed();
0541    return;
0542 }
0543 
0544 //___________________________________________________________________
0545 Bool_t TSQLConnection::IsClosed()
0546 {
0547    // Tests to see if a TSQLConnection is closed.
0548    // 
0549    // Returns:
0550    //       kTRUE if the connection is closed; 
0551    //       kFALSE if it's still open
0552    // Throws:
0553    //       TSQLException - if a database access error occurs
0554  
0555    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0556 
0557    if(!imp->fIsClosed) {
0558          // Test the connection
0559          rs = execSQL(gPING_COMMAND, -1);
0560    }
0561    
0562    imp->fIsClosed = !rs;   // kFALSE if rs==0 
0563    return imp->fIsClosed;
0564 }
0565 
0566 //___________________________________________________________________
0567 TSQLDatabaseMetaData* TSQLConnection::GetMetaData()
0568 {
0569    // Gets the metadata regarding this connection's database. 
0570    // A TSQLConnection's database is able to provide information 
0571    // describing its tables, its supported SQL grammar, its
0572    // stored procedures, the capabilities of this connection,
0573    // and so on. This information is made available through a 
0574    // TSQLDatabaseMetaData object.
0575    //
0576    // Returns:
0577    //       a TSQLDatabaseMetaData object for this TSQLConnection
0578    // Throws:
0579    //       TSQLException - if a database access error occurs
0580  
0581    return fMetaData;
0582 }
0583 
0584 //___________________________________________________________________
0585 void TSQLConnection::SetReadOnly( Bool_t readOnly )
0586 {
0587    // Puts this connection in read-only mode as a hint to enable
0588    // database optimizations. 
0589    //
0590    // Note: This method cannot be called while in the middle of a
0591    // transaction.
0592    //
0593    // Parameters:
0594    //       readOnly - kTRUE enables read-only mode; 
0595    //                  kFALSE disables read-only mode.
0596    // Throws:
0597    //       TSQLException - if a database access error occurs
0598 
0599    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0600 
0601    if(IsClosed()) { 
0602       Throw(new TSQLException("SetReadOnly attempt on closed connection.","08003",); //
0603       return;
0604    }
0605 
0606    imp->fReadOnly = readOnly;
0607 }
0608 
0609 //___________________________________________________________________
0610 Bool_t TSQLConnection::IsReadOnly()
0611 {
0612    // Tests to see if the connection is in read-only mode.
0613    //   
0614    // Returns:
0615    //       kTRUE if connection is read-only and kFALSE otherwise
0616    // Throws:
0617    //       TSQLException - if a database access error occurs
0618 
0619    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0620    return imp->fReadOnly;
0621 }
0622 
0623 //___________________________________________________________________
0624 void TSQLConnection::SetCatalog( const TString& catalog )
0625 { 
0626    // Sets a catalog name in order to select a subspace of this
0627    // TSQLConnection's database in which to work. If the driver 
0628    // does not support catalogs, it will silently ignore this 
0629    // request.
0630    //
0631    // Throws:
0632    //       TSQLException - if a database access error occurs
0633 
0634    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0635 
0636    if(IsClosed()) { 
0637       Throw(new TSQLException("SetCatalog attempt on closed connection.","08003",); //
0638       return;
0639    }
0640 
0641    if( !mysql_select_db(imp->fMYSQL,catalog) ) {
0642       Throw( new TSQLException("SetCatalog attempt failed","",) );
0643       return;
0644    }  
0645    imp->fDatabase = catalog;
0646 }
0647 
0648 //___________________________________________________________________
0649 TString TSQLConnection::GetCatalog()
0650 {
0651    // Returns the TSQLConnection's current catalog name.
0652    //
0653    // Returns:
0654    //       the current catalog name or null string
0655    // Throws:
0656    //       TSQLException - if a database access error occurs
0657 
0658    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0659 
0660    if(IsClosed()) { 
0661       Throw(new TSQLException("GetCatalog attempt on closed connection.","08003",); //
0662       return "";
0663    }
0664 
0665    return imp->fDatabase; 
0666 }
0667 
0668 //___________________________________________________________________
0669 void TSQLConnection::SetTransactionIsolation( Int_t level )
0670 {
0671    // Attempts to change the transaction isolation level to the one
0672    // given. The constants defined in the interface TSQLConnection 
0673    // are the possible transaction isolation levels. 
0674    //
0675    // Note: This method cannot be called while in the middle of a
0676    //       transaction.
0677    //
0678    // Parameters:
0679    //       level - one of the kTRANSACTION_XXX isolation values with 
0680    //               the exception of kTRANSACTION_NONE; 
0681    //               some databases may not support other values
0682    // Throws:
0683    //        TSQLException - if a database access error occurs
0684    // 
0685    // See Also: 
0686    // TSQLDatabaseMetaData::SupportsTransactionIsolationLevel(Int_t)
0687 
0688    if(IsClosed()) { 
0689       Throw(new TSQLException("Transaction Isolation Levels are not supported.","S1C00",4000); //
0690    }
0691    return;
0692 }
0693 
0694 //___________________________________________________________________
0695 Int_t TSQLConnection::GetTransactionIsolation()
0696 { 
0697    // Gets this TSQLConnection's current transaction isolation level.
0698    //
0699    // Returns:
0700    //       the current kTRANSACTION_XXX mode value
0701    // Throws:
0702    //       TSQLException - if a database access error occurs
0703   
0704    return kTRANSACTION_SERIALIZABLE;
0705 }
0706 
0707 //___________________________________________________________________
0708 Bool_t TSQLConnection::GetTrace()
0709 {
0710    // Returns kTRUE if tracing is enabled on this connection 
0711 
0712    Throw(new TSQLException("Tracing is not enable","S1C00",4000));
0713    return kFALSE;
0714 }
0715 
0716 //___________________________________________________________________
0717 void TSQLConnection::SetTrace( Bool_t on )
0718 {
0719    // Sets tracing on or off
0720   
0721    Throw(new TSQLException("Tracing is not enable","S1C00",4000));
0722 }
0723 
0724 //___________________________________________________________________
0725 TString TSQLConnection::GetTraceFile()
0726 {
0727    // Returns the file tracing is currently written to  
0728    
0729    Throw(new TSQLException("Tracing is not enable","S1C00",4000));   
0730    return "";
0731 }
0732 
0733 //___________________________________________________________________
0734 void TSQLConnection::SetTraceFile( const TString& fn )
0735 {
0736    // Sets the file tracing is written to    
0737 
0738    Throw(new TSQLException("Tracing is not enable","S1C00",4000));
0739 }
0740 
0741 //___________________________________________________________________
0742 Bool_t TSQLConnection::HasBatchSupport()
0743 {
0744    // Returns kTRUE if batch are supported
0745    //
0746    // Throws:
0747    //       TSQLException - if a database access error occurs
0748   
0749    return kFALSE; // not ... for a moment
0750 }
0751 
0752 //___________________________________________________________________
0753 void TSQLConnection::SetURL(const TString& url)
0754 {
0755    // sets URL string
0756 
0757    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
0758    imp->fURL = url;
0759    fMetaData->SetURL(url);
0760 }
0761 
0762 //////////// functions used to print out dbmetadata /////////////////
0763 //___________________________________________________________________
0764 const char* s(Bool_t b)
0765 {
0766    //
0767    
0768    return b?"Yes":"No";
0769 }
0770 
0771 //___________________________________________________________________
0772 TString maybeQuote(const TString& str, const TString& qc)
0773 {
0774    //
0775    
0776    TString res; 
0777    if(qc!=" ")  res = qc + str + qc;
0778    else  res = str;
0779    return res;
0780 }
0781 
0782 //___________________________________________________________________
0783 void rsInfo( TSQLDatabaseMetaData* md, 
0784              Int_t rsType, const char* name)
0785 {
0786    //  prints result set info    
0787   
0788    if(md->SupportsResultSetType(rsType)) {
0789       printf("%s\n",name);
0790 
0791       if(md->SupportsResultSetConcurrency(rsType,kCONCUR_READ_ONLY)) {
0792               printf("  + kCONCUR_READ_ONLY\n");
0793       }
0794 
0795       if(md->SupportsResultSetConcurrency(rsType,kCONCUR_UPDATABLE)) {
0796               printf("  + kCONCUR_UPDATABLE\n");
0797       }
0798 
0799       if(md->OwnInsertsAreVisible(rsType)) {
0800               printf("    Own inserts are visible\n");
0801       }
0802 
0803       if(md->OwnUpdatesAreVisible(rsType)) {
0804               printf("    Own updates are visible\n");
0805       }
0806       if(md->OwnDeletesAreVisible(rsType)) {
0807               printf("    Own deletes are visible\n");
0808       }
0809    }
0810 }
0811 
0812 
0813 //___________________________________________________________________
0814 struct {
0815    int id;
0816    const char* name;
0817    } levels[] = {
0818       { kTRANSACTION_READ_UNCOMMITTED, "kTRANSACTION_READ_UNCOMMITTED" },
0819       { kTRANSACTION_READ_COMMITTED, "kTRANSACTION_READ_COMMITTED" },
0820       { kTRANSACTION_REPEATABLE_READ, "kTRANSACTION_REPEATABLE_READ" },
0821       { kTRANSACTION_SERIALIZABLE, "kTRANSACTION_SERIALIZABLE" },
0822       { 0,NULL }
0823    };
0824    
0825 //___________________________________________________________________
0826 void transactionInfo(TSQLDatabaseMetaData* md)
0827 {
0828    //prints out transaction info
0829   
0830    TString str;
0831 
0832    str = s(md->SupportsTransactions());
0833    printf("Supports transactions           : %s\n",str.Data()); 
0834 
0835    printf("\nTransaction support \n");
0836    printf("---------------------------------------------------\n");
0837 
0838    if(!md->SupportsTransactions()) {
0839       printf("This datasource does not support transactions.\n\n");
0840       return;
0841    }
0842 
0843    int defIsolation=md->GetDefaultTransactionIsolation();
0844 
0845    for(int i=0; levels[i].name!=NULL; i++) {
0846       if(md->SupportsTransactionIsolationLevel(levels[i].id)) {
0847          str = " +";
0848          str += levels[i].name;
0849          str += (levels[i].id==defIsolation) ? " (default)" :"";
0850          printf("%s\n",str.Data());
0851       }
0852    }
0853 
0854    // the longest method name I've ever seen!
0855    if(md->SupportsDataDefinitionAndDataManipulationTransactions()) {
0856       printf("  Both DML and DDL can be used within a transaction\n");
0857    } else if(md->SupportsDataManipulationTransactionsOnly()) {
0858       printf("  Only DML can be used within a transaction\n");
0859    } else if(md->DataDefinitionCausesTransactionCommit()) {
0860       printf("  DDL causes commit\n");
0861    } else if(md->DataDefinitionIgnoredInTransactions()) {
0862       printf("  DDL is ignored in transactions\n");
0863    }
0864 }
0865 
0866 //___________________________________________________________________
0867 void catalogInfo(TSQLDatabaseMetaData* md)
0868 {
0869    //
0870 
0871    Bool_t cdml = md->SupportsCatalogsInDataManipulation();
0872    Bool_t cproc = md->SupportsCatalogsInProcedureCalls();
0873    Bool_t ctd = md->SupportsCatalogsInTableDefinitions();
0874    Bool_t cid = md->SupportsCatalogsInIndexDefinitions();
0875    Bool_t cpd = md->SupportsCatalogsInPrivilegeDefinitions();
0876    Bool_t hasCatalogs = cdml || cproc || ctd || cid || cpd;
0877   
0878    if(hasCatalogs) {
0879       printf("Supported catalog uses\n");
0880       printf("--------------------------------------------------- \n");
0881       printf("Data manipulation    : %s\n",s(cdml) );
0882       printf("Procedure calls      : %s\n",s(cproc) );
0883       printf("Table definitions    : %s\n",s(ctd) );
0884       printf("Index definitions    : %s\n",s(cid) );
0885       printf("Privilege definitions: %s\n",s(cpd) );
0886    } else {
0887       printf("This datasource does not support catalogs\n");
0888    }
0889    printf("\n");
0890  
0891    TString id = md->GetTableTerm();
0892    if(hasCatalogs) {
0893       TString catSep;
0894       TString catTerm;
0895       catSep  = md->GetCatalogSeparator();
0896       catTerm = md->GetCatalogTerm(); 
0897       if(md->IsCatalogAtStart()) {
0898          id =  catTerm + catSep + id;
0899       } else {
0900               id = id + catSep + catTerm;
0901       }
0902    }
0903    printf("Preferred table identifier format: %s\n",id.Data());
0904 }
0905 
0906 //___________________________________________________________________
0907 void schemaInfo(TSQLDatabaseMetaData* md)
0908 {
0909    //
0910 
0911    Bool_t sdml = md->SupportsSchemasInDataManipulation();
0912    Bool_t sproc = md->SupportsSchemasInProcedureCalls();
0913    Bool_t std = md->SupportsSchemasInTableDefinitions();
0914    Bool_t sid = md->SupportsSchemasInIndexDefinitions();
0915    Bool_t spd = md->SupportsSchemasInPrivilegeDefinitions();
0916    Bool_t hasSchemas=sdml || sproc || std || sid || spd;
0917 
0918    if(hasSchemas) {
0919       printf("Supported schema uses\n");
0920       printf("--------------------------------------------------- \n");
0921       printf("Data manipulation    : %s\n",s(sdml) );
0922       printf("Procedure calls      : %s\n",s(sproc) );
0923       printf("Table definitions    : %s\n",s(std) );
0924       printf("Index definitions    : %s\n",s(sid) );
0925       printf("Privilege definitions: %s\n",s(spd) );
0926    } else {
0927       printf("This datasource does not support schemas\n");
0928    }
0929    printf("\n");
0930   
0931    TString idq = md->GetIdentifierQuoteString();
0932    // space means no quoting supported
0933 
0934    TString id = md->GetTableTerm();
0935 }
0936 
0937 //___________________________________________________________________
0938 void productInfo(TSQLDatabaseMetaData* md)
0939 {
0940    //
0941 
0942    TString str;
0943 
0944    str = md->GetDatabaseProductName();
0945    printf("Product name                    : %s\n",str.Data()); 
0946    
0947    str = md->GetDatabaseProductVersion(); 
0948    printf("Product version                 : %s\n",str.Data()); 
0949 }
0950 
0951 //___________________________________________________________________
0952 void driverInfo(TSQLDatabaseMetaData* md)
0953 {
0954    //
0955 
0956    TString str;
0957 
0958    str = md->GetDriverName(); 
0959         printf("Driver name                     : %s\n",str.Data());
0960    
0961    str = md->GetDriverVersion();
0962         printf("Driver version                  : %s\n",str.Data()); 
0963 }
0964 
0965 //___________________________________________________________________
0966 void funcInfo(TSQLDatabaseMetaData* md)
0967 {
0968    //
0969 
0970    TString str;
0971 
0972    str =  md->GetSystemFunctions();
0973    printf("Supported system functions \n");
0974    printf("--------------------------------------------------- \n");
0975    printf("%s\n\n",str.Data());
0976    
0977    printf("Supported string functions\n");
0978    printf("--------------------------------------------------- \n");
0979    str = md->GetStringFunctions();
0980    printf("%s\n\n",str.Data());
0981    
0982    printf("Supported time/date functions\n");
0983    printf("--------------------------------------------------- \n");
0984    str = md->GetTimeDateFunctions();
0985    printf("%s\n\n",str.Data());
0986       
0987    printf("Supported numeric functions\n");
0988    printf("---------------------------------------------------\n");
0989    str = md->GetNumericFunctions();
0990    printf("%s\n\n",str.Data());
0991 }
0992 
0993 //___________________________________________________________________
0994 void keywordInfo(TSQLDatabaseMetaData* md)
0995 {
0996    //
0997 
0998    TString str;
0999 
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")) {
1030       productInfo(fMetaData);
1031       printf("=================================================== \n\n");
1032    }
1033    if(opt.Contains("d") || opt.Contains("a")) {
1034       driverInfo(fMetaData);
1035       printf("=================================================== \n\n");
1036    }
1037    if(opt.Contains("t") || opt.Contains("a")) {
1038       transactionInfo(fMetaData);
1039       printf("=================================================== \n\n");
1040    }
1041    if(opt.Contains("f") || opt.Contains("a")) {
1042       funcInfo(fMetaData);
1043       printf("=================================================== \n\n");
1044    }
1045    if(opt.Contains("k") || opt.Contains("a")) {
1046       keywordInfo(fMetaData);
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")) {
1059       catalogInfo(fMetaData);
1060       printf("=================================================== \n\n");
1061    }
1062    if(opt.Contains("s") || opt.Contains("a")) {
1063       schemaInfo(fMetaData);
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 
1084 /////////// private methods used by TSQLDriverManager ///////////////
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 
1095    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
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 
1108    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
1109    return imp->fLoginTimeout;
1110 }
1111 
1112 //___________________________________________________________________
1113 void TSQLConnection::Shutdown()
1114 {
1115    // Should be called before an application is to exit
1116 
1117    MySQLConnectionPrivate* imp = (MySQLConnectionPrivate*)fImp;
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 }