TSapDBServer.cxx

Go to the documentation of this file.
00001 // @(#)root/sapdb:$Id: TSapDBServer.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Mark Hemberger & Fons Rademakers   03/08/2001
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2001, 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 #include "TSapDBServer.h"
00013 #include "TSapDBResult.h"
00014 #include "TSapDBRow.h"
00015 #include "TUrl.h"
00016 #include <ctype.h>
00017 
00018 
00019 ClassImp(TSapDBServer)
00020 
00021 //______________________________________________________________________________
00022 TSapDBServer::TSapDBServer(const char *db, const char *uid, const char *pw)
00023 {
00024    // Open a connection to a SapDB DB server. The db arguments should be
00025    // of the form "sapdb://<host>[:<port>][/<database>]", e.g.:
00026    // "sapdb://pcroot.cern.ch:3456/test". The uid is the username and pw
00027    // the password that should be used for the connection.
00028 
00029    fSapDB     = 0;
00030    fEnv       = 0;
00031    fStmt      = 0;
00032    fStmtCnt   = 0;
00033 
00034    TUrl url(db);
00035 
00036    if (!url.IsValid()) {
00037       Error("TSapDBServer", "malformed db argument %s", db);
00038       MakeZombie();
00039       return;
00040    }
00041 
00042    if (strncmp(url.GetProtocol(), "sapdb", 5)) {
00043       Error("TSapDBServer", "protocol in db argument should be sapdb it is %s",
00044             url.GetProtocol());
00045       MakeZombie();
00046       return;
00047    }
00048 
00049    const char *dbase = url.GetFile();
00050 
00051    // Allocate environment, connection, and statement handle
00052    RETCODE rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &fEnv);
00053    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00054       Error("TSapDBServer", "allocation of environment failed");
00055       MakeZombie();
00056       return;
00057    }
00058 
00059    rc = SQLAllocHandle(SQL_HANDLE_DBC, fEnv, &fSapDB);
00060    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00061       printSQLError(fSapDB, SQL_NULL_HSTMT);
00062       Error("TSapDBServer", "allocation of db failed");
00063       MakeZombie();
00064       return;
00065    }
00066 
00067    // Connect to data source
00068    const char *dbnam = Form("%s:%s", url.GetHost(), dbase);
00069    rc = SQLConnect(fSapDB, (SQLCHAR*) dbnam, SQL_NTS,
00070                    (SQLCHAR*) uid, SQL_NTS, (SQLCHAR*) pw, SQL_NTS);
00071 
00072    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00073       printSQLError(fSapDB, SQL_NULL_HSTMT);
00074       Error("TSapDBServer", "connection to %s:%s failed", url.GetHost(), dbase);
00075       MakeZombie();
00076       return;
00077    }
00078 
00079    rc = SQLAllocHandle(SQL_HANDLE_STMT, fSapDB, &fStmt);
00080    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00081       printSQLError(fSapDB, fStmt);
00082       Error("TSapDBServer", "allocation of statement handle failed");
00083       MakeZombie();
00084       return;
00085    }
00086    rc = SQLAllocHandle(SQL_HANDLE_STMT, fSapDB, &fStmtCnt);
00087    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00088       printSQLError(fSapDB, fStmtCnt);
00089       Error("TSapDBServer", "allocation of count statement handle failed");
00090       MakeZombie();
00091       return;
00092    }
00093 
00094    fType = "SapDB";
00095    fHost = url.GetHost();
00096    fDB   = dbase;
00097    fPort = url.GetPort();
00098 }
00099 
00100 //______________________________________________________________________________
00101 TSapDBServer::~TSapDBServer()
00102 {
00103    // Close connection to SapDB DB server.
00104 
00105    if (IsConnected())
00106       Close();
00107 }
00108 
00109 //______________________________________________________________________________
00110 void TSapDBServer::Close(Option_t *)
00111 {
00112    // Close connection to SapDB DB server.
00113 
00114    // Disconnect from the data source and free all handles
00115    RETCODE rc = SQLDisconnect(fSapDB);
00116    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00117       printSQLError(fSapDB, SQL_NULL_HSTMT);
00118       Error("TSapDBServer", "disconnect during close failed");
00119    }
00120 
00121    rc = SQLFreeHandle(SQL_HANDLE_STMT, fStmt);
00122    if (rc != SQL_SUCCESS) {
00123       //Error("TSapDBServer", "free statement handle during close failed");
00124    }
00125 
00126    rc = SQLFreeHandle(SQL_HANDLE_STMT, fStmtCnt);
00127    if (rc != SQL_SUCCESS) {
00128       //Error("TSapDBServer", "free count statement handle during close failed");
00129    }
00130 
00131    rc = SQLFreeHandle(SQL_HANDLE_DBC, fSapDB);
00132    if (rc != SQL_SUCCESS) {
00133       printSQLError(fSapDB, SQL_NULL_HSTMT);
00134       Error("TSapDBServer", "free database handle during close failed");
00135    }
00136 
00137    rc = SQLFreeHandle(SQL_HANDLE_ENV, fEnv);
00138    if (rc != SQL_SUCCESS) {
00139       Error("TSapDBServer", "free environment handle during close failed");
00140    }
00141 
00142   fPort = -1;
00143 }
00144 
00145 //______________________________________________________________________________
00146 TSQLResult *TSapDBServer::Query(const char *sql)
00147 {
00148    // Execute SQL command. Result object must be deleted by the user.
00149    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00150    // The result object must be deleted by the user.
00151 
00152    if (!IsConnected()) {
00153       Error("Query", "not connected");
00154       return 0;
00155    }
00156 
00157    RETCODE rc = SQLFreeHandle(SQL_HANDLE_STMT, fStmt);
00158    if (rc != SQL_SUCCESS) {
00159       printSQLError(fSapDB, fStmt);
00160       Error("TSapDBServer", "free statement handle failed");
00161    }
00162 
00163    rc = SQLAllocHandle(SQL_HANDLE_STMT, fSapDB, &fStmt);
00164    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00165       printSQLError(fSapDB, fStmt);
00166       Error("TSapDBServer", "allocation statement handle failed");
00167    }
00168 
00169    rc = SQLFreeHandle(SQL_HANDLE_STMT, fStmtCnt);
00170    if (rc != SQL_SUCCESS) {
00171       printSQLError(fSapDB, fStmtCnt);
00172       Error("TSapDBServer", "free count statement handle failed");
00173    }
00174 
00175    rc = SQLAllocHandle(SQL_HANDLE_STMT, fSapDB, &fStmtCnt);
00176    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
00177       printSQLError(fSapDB, fStmtCnt);
00178       Error("TSapDBServer", "allocation count statement handle failed");
00179    }
00180 
00181    SDWORD slRowCount;
00182    TString sqlcnt = "SELECT COUNT(*) ";
00183    TString sqlt = sql;
00184    sqlt = sqlt.Strip(TString::kBoth);
00185 
00186    if (sqlt.BeginsWith("SELECT", TString::kIgnoreCase)) {
00187       Ssiz_t i = sqlt.Index("FROM", 0, TString::kIgnoreCase);
00188       if (i != kNPOS)
00189          sqlcnt += sqlt(i, sqlt.Length());
00190 
00191       if (SQLExecDirect(fStmtCnt, (SQLCHAR*)sqlcnt.Data(), SQL_NTS) !=
00192           SQL_SUCCESS) {
00193          printSQLError(fSapDB, fStmtCnt);
00194          return 0;
00195       }
00196 
00197       SQLBindCol(fStmtCnt, 1, SQL_C_LONG, &slRowCount, 0, 0);
00198       rc = SQLFetch(fStmtCnt);
00199       //if (rc == SQL_SUCCESS)
00200       //   printf("RowCount: %ld\n", slRowCount);
00201    }
00202 
00203    if (SQLPrepare(fStmt, (SQLCHAR*)sqlt.Data(), SQL_NTS) != SQL_SUCCESS) {
00204       printSQLError(fSapDB, fStmt);
00205       return 0;
00206    }
00207 
00208    if (SQLExecute(fStmt) != SQL_SUCCESS) {
00209       printSQLError(fSapDB, fStmt);
00210       return 0;
00211    }
00212    if (SQLEndTran(SQL_HANDLE_DBC, fSapDB, SQL_COMMIT) != SQL_SUCCESS) {
00213       printSQLError(fSapDB, fStmt);
00214       return 0;
00215    }
00216 
00217    return new TSapDBResult(fStmt, slRowCount);
00218 }
00219 
00220 //______________________________________________________________________________
00221 Int_t TSapDBServer::SelectDataBase(const char *dbname)
00222 {
00223    // Select a database. Returns 0 if successful, non-zero otherwise.
00224    // For SapDB: only to be used to check the dbname.
00225 
00226    if (!IsConnected()) {
00227       Error("SelectDataBase", "not connected");
00228       return -1;
00229    }
00230 
00231    if (fDB != dbname) {
00232       Error("SelectDataBase", "no such database");
00233       return -1;
00234    }
00235 
00236    return 0;
00237 }
00238 
00239 //______________________________________________________________________________
00240 TSQLResult *TSapDBServer::GetDataBases(const char *wild)
00241 {
00242    // List all available databases. Wild is for wildcarding "t%" list all
00243    // databases starting with "t".
00244    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00245    // The result object must be deleted by the user.
00246    // For SapDB: you are connected to a certain database, so give me a
00247    // list of tables
00248 
00249    if (!IsConnected()) {
00250       Error("GetDataBases", "not connected");
00251       return 0;
00252    }
00253 
00254    return GetTables(fDB, wild);
00255 }
00256 
00257 //______________________________________________________________________________
00258 TSQLResult *TSapDBServer::GetTables(const char * /*dbname*/, const char *wild)
00259 {
00260    // List all tables in the specified database. Wild is for wildcarding
00261    // "t%" list all tables starting with "t".
00262    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00263    // The result object must be deleted by the user.
00264 
00265    if (!IsConnected()) {
00266       Error("GetTables", "not connected");
00267       return 0;
00268    }
00269 
00270    TString sql = "SELECT TABLENAME FROM TABLES";
00271    if (wild)
00272       sql += Form(" WHERE TABLENAME LIKE '%s'", wild);
00273 
00274    return Query(sql);
00275 }
00276 
00277 //______________________________________________________________________________
00278 TSQLResult *TSapDBServer::GetColumns(const char *dbname, const char *table,
00279                                      const char *wild)
00280 {
00281    // List all columns in specified table in the specified database.
00282    // Wild is for wildcarding "t%" list all columns starting with "t".
00283    // Returns a pointer to a TSQLResult object if successful, 0 otherwise.
00284    // The result object must be deleted by the user.
00285 
00286    if (!IsConnected()) {
00287       Error("GetColumns", "not connected");
00288       return 0;
00289    }
00290 
00291    if (SelectDataBase(dbname) == 0) {
00292       Error("GetColumns", "no such database %s", dbname);
00293       return 0;
00294    }
00295 
00296    char *sql;
00297    if (wild)
00298       sql = Form("SELECT COLUMNNAME FROM COLUMNS WHERE TABLENAME LIKE '%s' AND COLUMNNAME LIKE '%s'", table, wild);
00299    else
00300       sql = Form("SELECT COLUMNNAME FROM COLUMNS WHERE TABLENAME LIKE '%s'", table);
00301 
00302    return Query(sql);
00303 }
00304 
00305 //______________________________________________________________________________
00306 Int_t TSapDBServer::CreateDataBase(const char * /*dbname*/)
00307 {
00308    // Create a database. Returns 0 if successful, non-zero otherwise.
00309    // For SapDB: do nothing
00310 
00311    if (!IsConnected()) {
00312       Error("CreateDataBase", "not connected");
00313       return -1;
00314    }
00315 
00316    Error("CreateDataBase", "not implemented");
00317    return 0;
00318 }
00319 
00320 //______________________________________________________________________________
00321 Int_t TSapDBServer::DropDataBase(const char * /*dbname*/)
00322 {
00323    // Drop (i.e. delete) a database. Returns 0 if successful, non-zero
00324    // otherwise.
00325    // For SapDB: do nothing
00326 
00327    if (!IsConnected()) {
00328       Error("DropDataBase", "not connected");
00329       return -1;
00330    }
00331 
00332    Error("DropDataBase", "not implemented");
00333    return 0;
00334 }
00335 
00336 //______________________________________________________________________________
00337 Int_t TSapDBServer::Reload()
00338 {
00339    // Reload permission tables. Returns 0 if successful, non-zero
00340    // otherwise. User must have reload permissions.
00341    // For SapDB: do nothing
00342 
00343    if (!IsConnected()) {
00344       Error("Reload", "not connected");
00345       return -1;
00346    }
00347 
00348    Error("Reload", "not implemented");
00349    return 0;
00350 }
00351 
00352 //______________________________________________________________________________
00353 Int_t TSapDBServer::Shutdown()
00354 {
00355    // Shutdown the database server. Returns 0 if successful, non-zero
00356    // otherwise. User must have shutdown permissions.
00357    // for SapDB: do nothing
00358 
00359    if (!IsConnected()) {
00360       Error("Shutdown", "not connected");
00361       return -1;
00362    }
00363 
00364    Error("Shutdown", "not implemented");
00365    return 0;
00366 }
00367 
00368 //______________________________________________________________________________
00369 const char *TSapDBServer::ServerInfo()
00370 {
00371    // Return server info.
00372 
00373    if (!IsConnected()) {
00374       Error("ServerInfo", "not connected");
00375       return 0;
00376    }
00377 
00378    TString sql = "SELECT KERNEL,RUNTIMEENVIRONMENT FROM DOMAIN.VERSIONS";
00379    TSQLResult *res_info = Query(sql);
00380 
00381    TSQLRow *row_info = res_info->Next();
00382 
00383    TString info;
00384    while (row_info) {
00385       info  = row_info->GetField(0);
00386       info += " ";
00387       info += row_info->GetField(1);
00388       row_info = res_info->Next();
00389    }
00390 
00391    delete res_info;
00392    delete row_info;
00393 
00394    return info;
00395 }
00396 
00397 //______________________________________________________________________________
00398 Int_t TSapDBServer::printSQLError(SQLHDBC hdbc, SQLHSTMT hstmt)
00399 {
00400    // Print SapDB error message.
00401 
00402    UCHAR  sqlstate[10];
00403    SDWORD sqlcode;
00404    UCHAR  errortxt[512+1];
00405    SWORD  usederrortxt;
00406 
00407    SQLError(SQL_NULL_HENV, hdbc, hstmt, sqlstate, &sqlcode, errortxt,
00408             512, &usederrortxt);
00409 
00410    printf ("SQL state: %s\n", sqlstate);
00411    printf ("SQL code:  %ld\n", long(sqlcode));
00412    printf ("SQL Errortext:\n%s\n\n", errortxt);
00413 
00414    return 0;
00415 }

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