00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00025
00026
00027
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
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
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
00104
00105 if (IsConnected())
00106 Close();
00107 }
00108
00109
00110 void TSapDBServer::Close(Option_t *)
00111 {
00112
00113
00114
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
00124 }
00125
00126 rc = SQLFreeHandle(SQL_HANDLE_STMT, fStmtCnt);
00127 if (rc != SQL_SUCCESS) {
00128
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
00149
00150
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
00200
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
00224
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
00243
00244
00245
00246
00247
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 * , const char *wild)
00259 {
00260
00261
00262
00263
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
00282
00283
00284
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 * )
00307 {
00308
00309
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 * )
00322 {
00323
00324
00325
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
00340
00341
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
00356
00357
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
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
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 }