TMySQLServer.cxx

Go to the documentation of this file.
00001 // @(#)root/mysql:$Id: TMySQLServer.cxx 30522 2009-09-29 08:37:38Z brun $
00002 // Author: Fons Rademakers   15/02/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TMySQLServer                                                         //
00015 //                                                                      //
00016 // MySQL server plugin implementing the TSQLServer interface.           //
00017 //                                                                      //
00018 // To open a connection to a server use the static method Connect().    //
00019 // The db argument of Connect() is of the form:                         //
00020 //    mysql://<host>[:<port>][/<database>], e.g.                        //
00021 // mysql://pcroot.cern.ch:3456/test                                     //
00022 //                                                                      //
00023 // As an example of connecting to mysql we assume that the server is    //
00024 // running on the local host and that you have access to a database     //
00025 // named "test" by connecting using an account that has a username and  //
00026 // password of "tuser" and "tpass". You can set up this account         //
00027 // by using the "mysql" program to connect to the server as the MySQL   //
00028 // root user and issuing the following statement:                       //
00029 //                                                                      //
00030 // mysql> GRANT ALL ON test.* TO 'tuser'@'localhost' IDENTIFIED BY 'tpass';
00031 //                                                                      //
00032 // If the test database does not exist, create it with this statement:  //
00033 //                                                                      //
00034 // mysql> CREATE DATABASE test;                                         //
00035 //                                                                      //
00036 // If you want to use a different server host, username, password,      //
00037 // or database name, just substitute the appropriate values.            //
00038 // To connect do:                                                       //
00039 //                                                                      //
00040 // TSQLServer *db = TSQLServer::Connect("mysql://localhost/test", "tuser", "tpass");
00041 //                                                                      //
00042 //////////////////////////////////////////////////////////////////////////
00043 
00044 #include "TMySQLServer.h"
00045 #include "TMySQLResult.h"
00046 #include "TMySQLStatement.h"
00047 #include "TSQLColumnInfo.h"
00048 #include "TSQLTableInfo.h"
00049 #include "TSQLRow.h"
00050 #include "TUrl.h"
00051 #include "TList.h"
00052 #include "TObjString.h"
00053 #include "TObjArray.h"
00054 
00055 #include <my_global.h>
00056 
00057 
00058 ClassImp(TMySQLServer)
00059 
00060 //______________________________________________________________________________
00061 TMySQLServer::TMySQLServer(const char *db, const char *uid, const char *pw)
00062 {
00063    // Open a connection to a MySQL DB server. The db arguments should be
00064    // of the form "mysql://<host>[:<port>][/<database>]", e.g.:
00065    // "mysql://pcroot.cern.ch:3456/test". The uid is the username and pw
00066    // the password that should be used for the connection.
00067    //
00068    // In addition, several parameters can be specified in url after "?" symbol:
00069    //    timeout=N           n is connect timeout is seconds
00070    //    socket=socketname   socketname should be name of Unix socket, used
00071    //                        for connection
00072    //    multi_statements    tell the server that the client may send multiple
00073    //                        statements in a single string (separated by ;);
00074    //    multi_results       tell the server that the client can handle multiple
00075    //                        result sets from multiple-statement executions or
00076    //                        stored procedures
00077    //    reconnect=0|1       enable or disable automatic reconnection to the server
00078    //                        if the connection is found to have been lost
00079    //    compress            use the compressed client/server protocol
00080    //    cnf_file=filename   Read options from the named option file instead of
00081    //                        from my.cnf
00082    //    cnf_group=groupname Read options from the named group from my.cnf or the
00083    //                        file specified with cnf_file option
00084    // If several parameters are specified, they should be separated by "&" symbol
00085    // Example of connection argument:
00086    //    TSQLServer::Connect("mysql://host.domain/test?timeout=10&multi_statements");
00087 
00088    fMySQL = 0;
00089    fInfo = "MySQL";
00090 
00091    TUrl url(db);
00092 
00093    if (!url.IsValid()) {
00094       TString errmsg("malformed db argument ");
00095       errmsg += db;
00096       SetError(-1, errmsg.Data(), "TMySQLServer");
00097       MakeZombie();
00098       return;
00099    }
00100 
00101    if (strncmp(url.GetProtocol(), "mysql", 5)) {
00102       SetError(-1, "protocol in db argument should be mysql://", "TMySQLServer");
00103       MakeZombie();
00104       return;
00105    }
00106 
00107    const char* dbase = url.GetFile();
00108    if (dbase!=0)
00109       if (*dbase=='/') dbase++; //skip leading "/" if appears
00110 
00111    fMySQL = new MYSQL;
00112    mysql_init(fMySQL);
00113 
00114    ULong_t client_flag = 0;
00115    TString socket;
00116 
00117    TString optstr = url.GetOptions();
00118    TObjArray* optarr = optstr.Tokenize("&");
00119    if (optarr!=0) {
00120       TIter next(optarr);
00121       TObject *obj = 0;
00122       while ((obj = next()) != 0) {
00123          TString opt = obj->GetName();
00124          opt.ToLower();
00125          opt.ReplaceAll(" ","");
00126          if (opt.Contains("timeout=")) {
00127             opt.Remove(0, 8);
00128             Int_t timeout = opt.Atoi();
00129             if (timeout > 0) {
00130                UInt_t mysqltimeout = (UInt_t) timeout;
00131                mysql_options(fMySQL, MYSQL_OPT_CONNECT_TIMEOUT, (const char*) &mysqltimeout);
00132                if (gDebug) Info("TMySQLServer","Set timeout %d",timeout);
00133             }
00134          } else
00135          if (opt.Contains("read_timeout=")) {
00136            #if MYSQL_VERSION_ID >= 40101
00137             opt.Remove(0, 13);
00138             Int_t timeout = opt.Atoi();
00139             if (timeout > 0) {
00140                UInt_t mysqltimeout = (UInt_t) timeout;
00141                mysql_options(fMySQL, MYSQL_OPT_READ_TIMEOUT, (const char*) &mysqltimeout);
00142                if (gDebug) Info("TMySQLServer","Set read timeout %d", timeout);
00143             }
00144            #else
00145             Warning("TMySQLServer","MYSQL_OPT_READ_TIMEOUT option not supported by this version of MySql");
00146            #endif
00147 
00148          } else
00149          if (opt.Contains("write_timeout=")) {
00150            #if MYSQL_VERSION_ID >= 40101
00151             opt.Remove(0, 14);
00152             Int_t timeout = opt.Atoi();
00153             if (timeout > 0) {
00154                UInt_t mysqltimeout = (UInt_t) timeout;
00155                mysql_options(fMySQL, MYSQL_OPT_WRITE_TIMEOUT, (const char*) &mysqltimeout);
00156                if (gDebug) Info("TMySQLServer","Set write timeout %d", timeout);
00157             }
00158            #else
00159             Warning("TMySQLServer","MYSQL_OPT_WRITE_TIMEOUT option not supported by this version of MySql");
00160            #endif
00161          } else
00162          if (opt.Contains("reconnect=")) {
00163            #if MYSQL_VERSION_ID >= 50013
00164             opt.Remove(0, 10);
00165             my_bool reconnect_on = (opt=="1") || (opt=="true");
00166             mysql_options(fMySQL, MYSQL_OPT_RECONNECT, (const char*) &reconnect_on);
00167             if (gDebug) Info("TMySQLServer","Set reconnect options %s", (reconnect_on ? "ON" : "OFF"));
00168            #else
00169             Warning("TMySQLServer","MYSQL_OPT_RECONNECT option not supported by this version of MySql");
00170            #endif
00171          } else
00172          if (opt.Contains("socket=")) {
00173             socket = (obj->GetName()+7);
00174             if (gDebug) Info("TMySQLServer","Use socket %s", socket.Data());
00175          } else
00176          if (opt.Contains("multi_statements")) {
00177            #if MYSQL_VERSION_ID >= 40100
00178             client_flag = client_flag | CLIENT_MULTI_STATEMENTS;
00179             if (gDebug) Info("TMySQLServer","Use CLIENT_MULTI_STATEMENTS");
00180            #else
00181             Warning("TMySQLServer","CLIENT_MULTI_STATEMENTS not supported by this version of MySql");
00182            #endif
00183          } else
00184          if (opt.Contains("multi_results")) {
00185            #if MYSQL_VERSION_ID >= 40100
00186             client_flag = client_flag | CLIENT_MULTI_RESULTS;
00187             if (gDebug) Info("TMySQLServer","Use CLIENT_MULTI_RESULTS");
00188            #else
00189             Warning("TMySQLServer","CLIENT_MULTI_RESULTS not supported by this version of MySql");
00190            #endif
00191          } else
00192          if (opt.Contains("compress")) {
00193             mysql_options(fMySQL, MYSQL_OPT_COMPRESS, 0);
00194             if (gDebug) Info("TMySQLServer","Use compressed client/server protocol");
00195          } else
00196          if (opt.Contains("cnf_file=")) {
00197             const char* filename = (obj->GetName()+9);
00198             mysql_options(fMySQL, MYSQL_READ_DEFAULT_FILE, filename);
00199             if (gDebug) Info("TMySQLServer","Read mysql options from %s file", filename);
00200          } else
00201          if (opt.Contains("cnf_group=")) {
00202             const char* groupname = (obj->GetName()+10);
00203             mysql_options(fMySQL, MYSQL_READ_DEFAULT_GROUP, groupname);
00204             if (gDebug) Info("TMySQLServer","Read mysql options from %s group of my.cnf file", groupname);
00205          }
00206       }
00207       optarr->Delete();
00208       delete optarr;
00209    }
00210 
00211    Int_t port = 3306;
00212    if (url.GetPort()>0) port = url.GetPort();
00213 
00214    if (mysql_real_connect(fMySQL, url.GetHost(), uid, pw, dbase, port,
00215                          (socket.Length()>0) ? socket.Data() : 0 , client_flag)) {
00216       fType = "MySQL";
00217       fHost = url.GetHost();
00218       fDB   = dbase;
00219       fPort = port;
00220    } else {
00221       SetError(mysql_errno(fMySQL), mysql_error(fMySQL), "TMySQLServer");
00222       MakeZombie();
00223    }
00224 }
00225 
00226 //______________________________________________________________________________
00227 TMySQLServer::~TMySQLServer()
00228 {
00229    // Close connection to MySQL DB server.
00230 
00231    if (IsConnected())
00232       Close();
00233    delete fMySQL;
00234 }
00235 
00236 // Reset error and check that server connected
00237 #define CheckConnect(method, res)                       \
00238    {                                                    \
00239       ClearError();                                     \
00240       if (!IsConnected()) {                             \
00241          SetError(-1,"MySQL server is not connected",method); \
00242          return res;                                    \
00243       }                                                 \
00244    }
00245 
00246 
00247 // check last mysql error code
00248 #define CheckErrNo(method, force, res)                  \
00249    {                                                    \
00250       unsigned int sqlerrno = mysql_errno(fMySQL);         \
00251       if ((sqlerrno!=0) || force) {                        \
00252          const char* sqlerrmsg = mysql_error(fMySQL);      \
00253          if (sqlerrno==0) { sqlerrno = 11111; sqlerrmsg = "MySQL error"; } \
00254          SetError(sqlerrno, sqlerrmsg, method);               \
00255          return res;                                    \
00256       }                                                 \
00257    }
00258 
00259 
00260 //______________________________________________________________________________
00261 void TMySQLServer::Close(Option_t *)
00262 {
00263    // Close connection to MySQL DB server.
00264 
00265    ClearError();
00266 
00267    if (!fMySQL)
00268       return;
00269 
00270    mysql_close(fMySQL);
00271    fPort = -1;
00272 }
00273 
00274 //______________________________________________________________________________
00275 TSQLResult *TMySQLServer::Query(const char *sql)
00276 {
00277    // Execute SQL command. Result object must be deleted by the user.
00278    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00279    // The result object must be deleted by the user.
00280 
00281    CheckConnect("Query", 0);
00282 
00283    if (mysql_query(fMySQL, sql))
00284       CheckErrNo("Query",kTRUE,0);
00285 
00286    MYSQL_RES *res = mysql_store_result(fMySQL);
00287    CheckErrNo("Query", kFALSE, 0);
00288 
00289    return new TMySQLResult(res);
00290 }
00291 
00292 //______________________________________________________________________________
00293 Bool_t TMySQLServer::Exec(const char* sql)
00294 {
00295    // Execute SQL command which does not produce any result sets.
00296    // Returns kTRUE if successful.
00297 
00298    CheckConnect("Exec", kFALSE);
00299 
00300    if (mysql_query(fMySQL, sql))
00301       CheckErrNo("Exec",kTRUE,kFALSE);
00302 
00303    return !IsError();
00304 }
00305 
00306 //______________________________________________________________________________
00307 Int_t TMySQLServer::SelectDataBase(const char *dbname)
00308 {
00309    // Select a database. Returns 0 if successful, non-zero otherwise.
00310 
00311    CheckConnect("SelectDataBase", -1);
00312 
00313    Int_t res = mysql_select_db(fMySQL, dbname);
00314    if (res==0) fDB = dbname;
00315           else CheckErrNo("SelectDataBase", kTRUE, res);
00316 
00317    return res;
00318 }
00319 
00320 //______________________________________________________________________________
00321 TSQLResult *TMySQLServer::GetDataBases(const char *wild)
00322 {
00323    // List all available databases. Wild is for wildcarding "t%" list all
00324    // databases starting with "t".
00325    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00326    // The result object must be deleted by the user.
00327 
00328    CheckConnect("GetDataBases", 0);
00329 
00330    MYSQL_RES *res = mysql_list_dbs(fMySQL, wild);
00331 
00332    CheckErrNo("GetDataBases", kFALSE, 0);
00333 
00334    return new TMySQLResult(res);
00335 }
00336 
00337 //______________________________________________________________________________
00338 TSQLResult *TMySQLServer::GetTables(const char *dbname, const char *wild)
00339 {
00340    // List all tables in the specified database. Wild is for wildcarding
00341    // "t%" list all tables starting with "t".
00342    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00343    // The result object must be deleted by the user.
00344 
00345    CheckConnect("GetTables", 0);
00346 
00347    if (SelectDataBase(dbname) != 0) return 0;
00348 
00349    MYSQL_RES *res = mysql_list_tables(fMySQL, wild);
00350 
00351    CheckErrNo("GetTables", kFALSE, 0);
00352 
00353    return new TMySQLResult(res);
00354 }
00355 
00356 
00357 //______________________________________________________________________________
00358 TList* TMySQLServer::GetTablesList(const char* wild)
00359 {
00360    // Return list of tables with specified wildcard.
00361 
00362    CheckConnect("GetTablesList", 0);
00363 
00364    MYSQL_RES *res = mysql_list_tables(fMySQL, wild);
00365 
00366    CheckErrNo("GetTablesList", kFALSE, 0);
00367 
00368    MYSQL_ROW row = mysql_fetch_row(res);
00369 
00370    TList* lst = 0;
00371 
00372    while (row!=0) {
00373       CheckErrNo("GetTablesList", kFALSE, lst);
00374 
00375       const char* tablename = row[0];
00376 
00377       if (tablename!=0) {
00378          if (lst==0) {
00379             lst = new TList();
00380             lst->SetOwner(kTRUE);
00381          }
00382          lst->Add(new TObjString(tablename));
00383       }
00384 
00385       row = mysql_fetch_row(res);
00386    }
00387 
00388    mysql_free_result(res);
00389 
00390    return lst;
00391 }
00392 
00393 //______________________________________________________________________________
00394 TSQLTableInfo *TMySQLServer::GetTableInfo(const char* tablename)
00395 {
00396    // Produces SQL table info.
00397    // Object must be deleted by user.
00398 
00399    CheckConnect("GetTableInfo", 0);
00400 
00401    if ((tablename==0) || (*tablename==0)) return 0;
00402 
00403    TString sql;
00404    sql.Form("SELECT * FROM `%s` LIMIT 1", tablename);
00405 
00406    if (mysql_query(fMySQL, sql.Data()) != 0)
00407       CheckErrNo("GetTableInfo", kTRUE, 0);
00408 
00409    MYSQL_RES *res = mysql_store_result(fMySQL);
00410    CheckErrNo("GetTableInfo", kFALSE, 0);
00411 
00412    unsigned int numfields = mysql_num_fields(res);
00413 
00414    MYSQL_FIELD* fields = mysql_fetch_fields(res);
00415 
00416    sql.Form("SHOW COLUMNS FROM `%s`", tablename);
00417    TSQLResult* showres = Query(sql.Data());
00418 
00419    if (showres==0) {
00420       mysql_free_result(res);
00421       return 0;
00422    }
00423 
00424    TList* lst = 0;
00425 
00426    unsigned int nfield = 0;
00427 
00428    TSQLRow* row = 0;
00429 
00430    while ((row = showres->Next()) != 0) {
00431       const char* column_name = row->GetField(0);
00432       const char* type_name = row->GetField(1);
00433 
00434       if ((nfield>=numfields) ||
00435           (strcmp(column_name, fields[nfield].name)!=0))
00436       {
00437          SetError(-1,"missmatch in column names","GetTableInfo");
00438          break;
00439       }
00440 
00441       Int_t sqltype = kSQL_NONE;
00442 
00443       Int_t data_size = -1;    // size in bytes
00444       Int_t data_length = -1;  // declaration like VARCHAR(n) or NUMERIC(n)
00445       Int_t data_scale = -1;   // second argument in declaration
00446       Int_t data_sign = -1; // signed type or not
00447 
00448       if (IS_NUM(fields[nfield].type)) {
00449          if (fields[nfield].flags & UNSIGNED_FLAG)
00450             data_sign = 0;
00451          else
00452             data_sign = 1;
00453       }
00454 
00455       Bool_t nullable = (fields[nfield].flags & NOT_NULL_FLAG) == 0;
00456 
00457       data_length = fields[nfield].length;
00458       if (data_length==0) data_length = -1;
00459 
00460 #if MYSQL_VERSION_ID >= 40100
00461 
00462       switch (fields[nfield].type) {
00463          case MYSQL_TYPE_TINY:
00464          case MYSQL_TYPE_SHORT:
00465          case MYSQL_TYPE_LONG:
00466          case MYSQL_TYPE_INT24:
00467          case MYSQL_TYPE_LONGLONG:
00468             sqltype = kSQL_INTEGER;
00469             break;
00470          case MYSQL_TYPE_DECIMAL:
00471             sqltype = kSQL_NUMERIC;
00472             data_scale = fields[nfield].decimals;
00473             break;
00474          case MYSQL_TYPE_FLOAT:
00475             sqltype = kSQL_FLOAT;
00476             break;
00477          case MYSQL_TYPE_DOUBLE:
00478             sqltype = kSQL_DOUBLE;
00479             break;
00480          case MYSQL_TYPE_TIMESTAMP:
00481             sqltype = kSQL_TIMESTAMP;
00482             break;
00483          case MYSQL_TYPE_DATE:
00484          case MYSQL_TYPE_TIME:
00485          case MYSQL_TYPE_DATETIME:
00486          case MYSQL_TYPE_YEAR:
00487             break;
00488          case MYSQL_TYPE_STRING:
00489             if (fields[nfield].charsetnr==63)
00490                sqltype = kSQL_BINARY;
00491             else
00492                sqltype = kSQL_CHAR;
00493             data_size = data_length;
00494             break;
00495          case MYSQL_TYPE_VAR_STRING:
00496             if (fields[nfield].charsetnr==63)
00497                sqltype = kSQL_BINARY;
00498             else
00499                sqltype = kSQL_VARCHAR;
00500             data_size = data_length;
00501             break;
00502          case MYSQL_TYPE_BLOB:
00503             if (fields[nfield].charsetnr==63)
00504                sqltype = kSQL_BINARY;
00505             else
00506                sqltype = kSQL_VARCHAR;
00507             data_size = data_length;
00508             break;
00509          case MYSQL_TYPE_SET:
00510          case MYSQL_TYPE_ENUM:
00511          case MYSQL_TYPE_GEOMETRY:
00512          case MYSQL_TYPE_NULL:
00513             break;
00514          default:
00515             if (IS_NUM(fields[nfield].type))
00516                sqltype = kSQL_NUMERIC;
00517       }
00518 
00519 #endif
00520 
00521       if (!lst)
00522          lst = new TList;
00523       lst->Add(new TSQLColumnInfo(column_name,
00524                                   type_name,
00525                                   nullable,
00526                                   sqltype,
00527                                   data_size,
00528                                   data_length,
00529                                   data_scale,
00530                                   data_sign));
00531 
00532       nfield++;
00533       delete row;
00534    }
00535 
00536    mysql_free_result(res);
00537    delete showres;
00538 
00539    sql.Form("SHOW TABLE STATUS LIKE '%s'", tablename);
00540 
00541    TSQLTableInfo* info = 0;
00542 
00543    TSQLResult* stats = Query(sql.Data());
00544 
00545    if (stats!=0) {
00546       row = 0;
00547 
00548       while ((row = stats->Next()) != 0) {
00549          if (strcmp(row->GetField(0), tablename)!=0) {
00550             delete row;
00551             continue;
00552          }
00553          const char* comments = 0;
00554          const char* engine = 0;
00555          const char* create_time = 0;
00556          const char* update_time = 0;
00557 
00558          for (int n=1;n<stats->GetFieldCount();n++) {
00559             TString fname = stats->GetFieldName(n);
00560             fname.ToLower();
00561             if (fname=="engine") engine = row->GetField(n); else
00562             if (fname=="comment") comments = row->GetField(n); else
00563             if (fname=="create_time") create_time = row->GetField(n); else
00564             if (fname=="update_time") update_time = row->GetField(n);
00565          }
00566 
00567          info = new TSQLTableInfo(tablename,
00568                                   lst,
00569                                   comments,
00570                                   engine,
00571                                   create_time,
00572                                   update_time);
00573 
00574          delete row;
00575          break;
00576       }
00577       delete stats;
00578    }
00579 
00580    if (info==0)
00581       info = new TSQLTableInfo(tablename, lst);
00582 
00583    return info;
00584 }
00585 
00586 //______________________________________________________________________________
00587 TSQLResult *TMySQLServer::GetColumns(const char *dbname, const char *table,
00588                                      const char *wild)
00589 {
00590    // List all columns in specified table in the specified database.
00591    // Wild is for wildcarding "t%" list all columns starting with "t".
00592    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00593    // The result object must be deleted by the user.
00594 
00595    CheckConnect("GetColumns", 0);
00596 
00597    if (SelectDataBase(dbname) != 0) return 0;
00598 
00599    TString sql;
00600    if (wild)
00601       sql.Form("SHOW COLUMNS FROM %s LIKE '%s'", table, wild);
00602    else
00603       sql.Form("SHOW COLUMNS FROM %s", table);
00604 
00605    return Query(sql.Data());
00606 }
00607 
00608 //______________________________________________________________________________
00609 Int_t TMySQLServer::CreateDataBase(const char *dbname)
00610 {
00611    // Create a database. Returns 0 if successful, non-zero otherwise.
00612 
00613    CheckConnect("CreateDataBase", -1);
00614 
00615    Int_t res = mysql_query(fMySQL, Form("CREATE DATABASE %s",dbname));
00616 
00617    CheckErrNo("CreateDataBase", kFALSE, res);
00618 
00619    return res;
00620 }
00621 
00622 //______________________________________________________________________________
00623 Int_t TMySQLServer::DropDataBase(const char *dbname)
00624 {
00625    // Drop (i.e. delete) a database. Returns 0 if successful, non-zero
00626    // otherwise.
00627 
00628    CheckConnect("DropDataBase", -1);
00629 
00630    Int_t res = mysql_query(fMySQL, Form("DROP DATABASE %s",dbname));
00631 
00632    CheckErrNo("DropDataBase", kFALSE, res);
00633 
00634    return res;
00635 }
00636 
00637 //______________________________________________________________________________
00638 Int_t TMySQLServer::Reload()
00639 {
00640    // Reload permission tables. Returns 0 if successful, non-zero
00641    // otherwise. User must have reload permissions.
00642 
00643    CheckConnect("Reload", -1);
00644 
00645    Int_t res = mysql_reload(fMySQL);
00646 
00647    CheckErrNo("Reload", kFALSE, res);
00648 
00649    return res;
00650 }
00651 
00652 //______________________________________________________________________________
00653 Int_t TMySQLServer::Shutdown()
00654 {
00655    // Shutdown the database server. Returns 0 if successful, non-zero
00656    // otherwise. User must have shutdown permissions.
00657 
00658    CheckConnect("Shutdown", -1);
00659 
00660    Int_t res;
00661 
00662 #if MYSQL_VERSION_ID >= 50001 || \
00663     (MYSQL_VERSION_ID < 50000 && MYSQL_VERSION_ID >= 40103)
00664    res = mysql_shutdown(fMySQL, SHUTDOWN_DEFAULT);
00665 #else
00666    res = mysql_shutdown(fMySQL);
00667 #endif
00668 
00669    CheckErrNo("Shutdown", kFALSE, res);
00670 
00671    return res;
00672 }
00673 
00674 //______________________________________________________________________________
00675 const char *TMySQLServer::ServerInfo()
00676 {
00677    // Return server info in form "MySQL <vesrion>".
00678 
00679    CheckConnect("ServerInfo", 0);
00680 
00681    const char* res = mysql_get_server_info(fMySQL);
00682 
00683    CheckErrNo("ServerInfo", kFALSE, res);
00684 
00685    fInfo = "MySQL ";
00686    fInfo += res;
00687 
00688    return fInfo.Data();
00689 }
00690 
00691 //______________________________________________________________________________
00692 Bool_t TMySQLServer::HasStatement() const
00693 {
00694    // Return kTRUE if TSQLStatement class is supported.
00695    // Starts from MySQL 4.1.
00696 
00697 #if MYSQL_VERSION_ID < 40100
00698    return kFALSE;
00699 #else
00700    return kTRUE;
00701 #endif
00702 }
00703 
00704 
00705 //______________________________________________________________________________
00706 TSQLStatement *TMySQLServer::Statement(const char *sql, Int_t)
00707 {
00708    // Produce TMySQLStatement.
00709 
00710 #if MYSQL_VERSION_ID < 40100
00711    ClearError();
00712    SetError(-1, "Statement class does not supported by MySQL version < 4.1", "Statement");
00713    return 0;
00714 #else
00715 
00716    CheckConnect("Statement", 0);
00717 
00718    if (!sql || !*sql) {
00719       SetError(-1, "no query string specified","Statement");
00720       return 0;
00721    }
00722 
00723    MYSQL_STMT *stmt = mysql_stmt_init(fMySQL);
00724    if (!stmt)
00725       CheckErrNo("Statement", kTRUE, 0);
00726 
00727    if (mysql_stmt_prepare(stmt, sql, strlen(sql))) {
00728       SetError(mysql_errno(fMySQL), mysql_error(fMySQL), "Statement");
00729       mysql_stmt_close(stmt);
00730       return 0;
00731    }
00732 
00733    return new TMySQLStatement(stmt, fErrorOut);
00734 
00735 #endif
00736 }
00737 
00738 //______________________________________________________________________________
00739 Bool_t TMySQLServer::StartTransaction()
00740 {
00741    // Start transaction
00742 
00743    CheckConnect("StartTransaction", kFALSE);
00744 
00745    return TSQLServer::StartTransaction();
00746 }
00747 
00748 //______________________________________________________________________________
00749 Bool_t TMySQLServer::Commit()
00750 {
00751    // Commit changes
00752 
00753    CheckConnect("Commit", kFALSE);
00754 
00755 #if MYSQL_VERSION_ID >= 40100
00756 
00757    if (mysql_commit(fMySQL))
00758       CheckErrNo("Commit", kTRUE, kFALSE);
00759 
00760    return kTRUE;
00761 
00762 #else
00763 
00764    return TSQLServer::Commit();
00765 
00766 #endif
00767 
00768 }
00769 
00770 //______________________________________________________________________________
00771 Bool_t TMySQLServer::Rollback()
00772 {
00773    // Rollback changes
00774 
00775    CheckConnect("Rollback", kFALSE);
00776 
00777 #if MYSQL_VERSION_ID >= 40100
00778 
00779    if (mysql_rollback(fMySQL))
00780       CheckErrNo("Rollback", kTRUE, kFALSE);
00781 
00782    return kTRUE;
00783 
00784 #else
00785 
00786    return TSQLServer::Rollback();
00787 
00788 #endif
00789 
00790 }
00791 
00792 //______________________________________________________________________________
00793 Bool_t TMySQLServer::PingVerify()
00794 {
00795    // Execute Ping to SQL Connection.
00796    // Since mysql_ping tries to reconnect by itself,
00797    // a double call to the mysql function is implemented.
00798    // Returns kTRUE if successful
00799 
00800    CheckConnect("Ping", kFALSE);
00801 
00802    if (mysql_ping(fMySQL)) {
00803       if (mysql_ping(fMySQL)) {
00804          Error("PingVerify", "not able to automatically reconnect a second time");
00805          CheckErrNo("Ping", kTRUE, kFALSE);
00806       } else
00807          Info("PingVerify", "connection was lost, but could automatically reconnect");
00808    }
00809 
00810    return !IsError();
00811 }
00812 
00813 //______________________________________________________________________________
00814 Int_t TMySQLServer::Ping()
00815 {
00816    // Execute Ping to SQL Connection using the mysql_ping function.
00817    // Returns 0 if successful, non-zero in case an error occured.
00818 
00819    CheckConnect("PingInt", kFALSE);
00820 
00821    return mysql_ping(fMySQL);
00822 }

Generated on Tue Jul 5 15:14:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1