00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "TOracleServer.h"
00050 #include "TOracleResult.h"
00051 #include "TOracleStatement.h"
00052 #include "TSQLColumnInfo.h"
00053 #include "TSQLTableInfo.h"
00054 #include "TUrl.h"
00055 #include "TList.h"
00056 #include "TObjString.h"
00057
00058 ClassImp(TOracleServer)
00059
00060 const char* TOracleServer::fgDatimeFormat = "MM/DD/YYYY, HH24:MI:SS";
00061
00062
00063
00064 #define CheckConnect(method, res) \
00065 ClearError(); \
00066 if (!IsConnected()) { \
00067 SetError(-1,"Oracle database is not connected",method); \
00068 return res; \
00069 }
00070
00071
00072 #define CatchError(method) \
00073 catch (SQLException &oraex) { \
00074 SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), method); \
00075 }
00076
00077
00078 TOracleServer::TOracleServer(const char *db, const char *uid, const char *pw)
00079 {
00080
00081
00082
00083
00084
00085 fEnv = 0;
00086 fConn = 0;
00087
00088 TUrl url(db);
00089
00090 if (!url.IsValid()) {
00091 TString errmsg = "Malformed db argument ";
00092 errmsg+=db;
00093 SetError(-1, errmsg.Data(), "TOracleServer");
00094 MakeZombie();
00095 return;
00096 }
00097
00098 if (strncmp(url.GetProtocol(), "oracle", 6)) {
00099 SetError(-1, "protocol in db argument should be oracle://", "TOracleServer");
00100 MakeZombie();
00101 return;
00102 }
00103
00104 const char *conn_str = url.GetFile();
00105 if (conn_str!=0)
00106 if (*conn_str == '/') conn_str++;
00107
00108 try {
00109
00110 TString options = url.GetOptions();
00111 Int_t pos = options.Index("ObjectMode");
00112
00113 if (pos != kNPOS) {
00114 fEnv = Environment::createEnvironment(Environment::OBJECT);
00115 } else {
00116 fEnv = Environment::createEnvironment();
00117 }
00118 fConn = fEnv->createConnection(uid, pw, conn_str ? conn_str : "");
00119
00120 fType = "Oracle";
00121 fHost = url.GetHost();
00122 fDB = conn_str;
00123 fPort = url.GetPort();
00124 fPort = (fPort>0) ? fPort : 1521;
00125 return;
00126
00127 } CatchError("TOracleServer")
00128
00129 MakeZombie();
00130 }
00131
00132
00133 TOracleServer::~TOracleServer()
00134 {
00135
00136
00137 if (IsConnected())
00138 Close();
00139 }
00140
00141
00142
00143 void TOracleServer::Close(Option_t *)
00144 {
00145
00146
00147 ClearError();
00148
00149 try {
00150 if (fConn)
00151 fEnv->terminateConnection(fConn);
00152 if (fEnv)
00153 Environment::terminateEnvironment(fEnv);
00154 } CatchError("Close")
00155
00156 fPort = -1;
00157 }
00158
00159
00160 TSQLStatement *TOracleServer::Statement(const char *sql, Int_t niter)
00161 {
00162 CheckConnect("Statement",0);
00163
00164 if (!sql || !*sql) {
00165 SetError(-1, "no query string specified","Statement");
00166 return 0;
00167 }
00168
00169 try {
00170 oracle::occi::Statement *stmt = fConn->createStatement(sql);
00171
00172 Blob parblob(fConn);
00173
00174 return new TOracleStatement(fEnv, fConn, stmt, niter, fErrorOut);
00175
00176 } CatchError("Statement")
00177
00178 return 0;
00179 }
00180
00181
00182 TSQLResult *TOracleServer::Query(const char *sql)
00183 {
00184
00185
00186
00187 CheckConnect("Query",0);
00188
00189 if (!sql || !*sql) {
00190 SetError(-1, "no query string specified","Query");
00191 return 0;
00192 }
00193
00194 try {
00195 oracle::occi::Statement *stmt = fConn->createStatement();
00196
00197
00198
00199
00200
00201
00202
00203 stmt->setSQL(sql);
00204 stmt->setPrefetchRowCount(1000);
00205 stmt->setPrefetchMemorySize(1000000);
00206 stmt->execute();
00207
00208 TOracleResult *res = new TOracleResult(fConn, stmt);
00209 return res;
00210 } CatchError("Query")
00211
00212 return 0;
00213 }
00214
00215
00216 Bool_t TOracleServer::Exec(const char* sql)
00217 {
00218
00219
00220
00221 CheckConnect("Exec", kFALSE);
00222
00223 if (!sql || !*sql) {
00224 SetError(-1, "no query string specified","Exec");
00225 return kFALSE;
00226 }
00227
00228 oracle::occi::Statement *stmt = 0;
00229
00230 Bool_t res = kFALSE;
00231
00232 try {
00233 stmt = fConn->createStatement(sql);
00234 stmt->execute();
00235 res = kTRUE;
00236 } CatchError("Exec")
00237
00238 try {
00239 fConn->terminateStatement(stmt);
00240 } CatchError("Exec")
00241
00242 return res;
00243 }
00244
00245
00246 TSQLResult *TOracleServer::GetTables(const char *dbname, const char * )
00247 {
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 CheckConnect("GetTables",0);
00261
00262 TString sqlstr("SELECT object_name,owner FROM ALL_OBJECTS WHERE object_type='TABLE'");
00263 if (dbname && dbname[0])
00264 sqlstr = sqlstr + " AND owner='" + dbname + "'";
00265
00266 return Query(sqlstr.Data());
00267 }
00268
00269
00270 TList* TOracleServer::GetTablesList(const char* wild)
00271 {
00272 CheckConnect("GetTablesList",0);
00273
00274 TString cmd("SELECT table_name FROM user_tables");
00275 if ((wild!=0) && (*wild!=0))
00276 cmd+=Form(" WHERE table_name LIKE '%s'", wild);
00277
00278 TSQLStatement* stmt = Statement(cmd);
00279 if (stmt==0) return 0;
00280
00281 TList* lst = 0;
00282
00283 if (stmt->Process()) {
00284 stmt->StoreResult();
00285 while (stmt->NextResultRow()) {
00286 const char* tablename = stmt->GetString(0);
00287 if (tablename==0) continue;
00288 if (lst==0) {
00289 lst = new TList;
00290 lst->SetOwner(kTRUE);
00291 }
00292 lst->Add(new TObjString(tablename));
00293 }
00294 }
00295
00296 delete stmt;
00297
00298 return lst;
00299 }
00300
00301
00302 TSQLTableInfo *TOracleServer::GetTableInfo(const char* tablename)
00303 {
00304
00305
00306
00307 CheckConnect("GetTableInfo",0);
00308
00309 if ((tablename==0) || (*tablename==0)) return 0;
00310
00311 TString table(tablename);
00312 table.ToUpper();
00313 TString sql;
00314 sql.Form("SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, CHAR_COL_DECL_LENGTH FROM user_tab_columns WHERE table_name = '%s' ORDER BY COLUMN_ID", table.Data());
00315
00316 TSQLStatement* stmt = Statement(sql.Data(), 10);
00317 if (stmt==0) return 0;
00318
00319 if (!stmt->Process()) {
00320 delete stmt;
00321 return 0;
00322 }
00323
00324 TList* lst = 0;
00325
00326 stmt->StoreResult();
00327
00328 while (stmt->NextResultRow()) {
00329 const char* columnname = stmt->GetString(0);
00330 TString data_type = stmt->GetString(1);
00331 Int_t data_length = stmt->GetInt(2);
00332 Int_t data_precision = stmt->GetInt(3);
00333 Int_t data_scale = stmt->GetInt(4);
00334 const char* nstr = stmt->GetString(5);
00335 Int_t char_col_decl_length = stmt->GetInt(6);
00336 Int_t data_sign = -1;
00337
00338 Int_t sqltype = kSQL_NONE;
00339
00340 if (data_type=="NUMBER") {
00341 sqltype = kSQL_NUMERIC;
00342 if (data_precision<=0) {
00343 data_precision = -1;
00344 data_scale = -1;
00345 } else
00346 if (data_scale<=0)
00347 data_scale = -1;
00348 data_sign = 1;
00349 } else
00350
00351 if (data_type=="CHAR") {
00352 sqltype = kSQL_CHAR;
00353 data_precision = char_col_decl_length;
00354 data_scale = -1;
00355 } else
00356
00357 if ((data_type=="VARCHAR") || (data_type=="VARCHAR2")) {
00358 sqltype = kSQL_VARCHAR;
00359 data_precision = char_col_decl_length;
00360 data_scale = -1;
00361 } else
00362
00363 if (data_type=="FLOAT") {
00364 sqltype = kSQL_FLOAT;
00365 data_scale = -1;
00366 if (data_precision==126) data_precision = -1;
00367 data_sign = 1;
00368 } else
00369
00370 if (data_type=="BINARY_FLOAT") {
00371 sqltype = kSQL_FLOAT;
00372 data_scale = -1;
00373 data_precision = -1;
00374 data_sign = 1;
00375 } else
00376
00377 if (data_type=="BINARY_DOUBLE") {
00378 sqltype = kSQL_DOUBLE;
00379 data_scale = -1;
00380 data_precision = -1;
00381 data_sign = 1;
00382 } else
00383
00384 if (data_type=="LONG") {
00385 sqltype = kSQL_VARCHAR;
00386 data_length = 0x7fffffff;
00387 data_precision = -1;
00388 data_scale = -1;
00389 } else
00390
00391 if (data_type.Contains("TIMESTAMP")) {
00392 sqltype = kSQL_TIMESTAMP;
00393 data_precision = -1;
00394 }
00395
00396 Bool_t IsNullable = kFALSE;
00397 if (nstr!=0)
00398 IsNullable = (*nstr=='Y') || (*nstr=='y');
00399
00400 TSQLColumnInfo* info =
00401 new TSQLColumnInfo(columnname,
00402 data_type,
00403 IsNullable,
00404 sqltype,
00405 data_length,
00406 data_precision,
00407 data_scale,
00408 data_sign);
00409
00410 if (lst==0) lst = new TList;
00411 lst->Add(info);
00412 }
00413
00414 delete stmt;
00415
00416 return new TSQLTableInfo(tablename, lst);
00417 }
00418
00419
00420 TSQLResult *TOracleServer::GetColumns(const char * , const char *tablename,
00421 const char * wild)
00422 {
00423
00424
00425
00426
00427
00428 CheckConnect("GetColumns",0);
00429
00430
00431
00432
00433
00434
00435
00436 TString sql;
00437 TString table(tablename);
00438 table.ToUpper();
00439 if (wild && wild[0])
00440 sql.Form("select COLUMN_NAME, concat(concat(concat(data_type,'('),data_length),')') \"Type\" FROM user_tab_columns WHERE table_name like '%s' ORDER BY COLUMN_ID", wild);
00441 else
00442 sql.Form("select COLUMN_NAME, concat(concat(concat(data_type,'('),data_length),')') \"Type\" FROM user_tab_columns WHERE table_name = '%s' ORDER BY COLUMN_ID", table.Data());
00443 return Query(sql);
00444 }
00445
00446
00447 Int_t TOracleServer::SelectDataBase(const char * )
00448 {
00449
00450
00451
00452 CheckConnect("SelectDataBase", -1);
00453
00454
00455 return 0;
00456 }
00457
00458
00459 TSQLResult *TOracleServer::GetDataBases(const char * )
00460 {
00461
00462
00463
00464
00465
00466
00467 CheckConnect("GetDataBases",0);
00468
00469 return 0;
00470 }
00471
00472
00473 Int_t TOracleServer::CreateDataBase(const char * )
00474 {
00475
00476
00477
00478 CheckConnect("CreateDataBase",-1);
00479
00480 return -1;
00481 }
00482
00483
00484 Int_t TOracleServer::DropDataBase(const char * )
00485 {
00486
00487
00488
00489
00490 CheckConnect("DropDataBase",-1);
00491
00492 return -1;
00493 }
00494
00495
00496 Int_t TOracleServer::Reload()
00497 {
00498
00499
00500
00501
00502 CheckConnect("Reload", -1);
00503
00504 return -1;
00505 }
00506
00507
00508 Int_t TOracleServer::Shutdown()
00509 {
00510
00511
00512
00513
00514 CheckConnect("Shutdown", -1);
00515
00516 return -1;
00517 }
00518
00519
00520 const char *TOracleServer::ServerInfo()
00521 {
00522
00523
00524 CheckConnect("ServerInfo", 0);
00525
00526 fInfo = "Oracle";
00527 TSQLStatement* stmt = Statement("select * from v$version");
00528 if (stmt!=0) {
00529 stmt->EnableErrorOutput(kFALSE);
00530 if (stmt->Process()) {
00531 fInfo = "";
00532 stmt->StoreResult();
00533 while (stmt->NextResultRow()) {
00534 if (fInfo.Length()>0) fInfo += "\n";
00535 fInfo += stmt->GetString(0);
00536 }
00537 }
00538 delete stmt;
00539 }
00540
00541 return fInfo.Data();
00542 }
00543
00544
00545 Bool_t TOracleServer::StartTransaction()
00546 {
00547
00548
00549
00550 return Commit();
00551 }
00552
00553
00554 Bool_t TOracleServer::Commit()
00555 {
00556
00557
00558
00559 CheckConnect("Commit", kFALSE);
00560
00561 try {
00562 fConn->commit();
00563 return kTRUE;
00564 } CatchError("Commit")
00565
00566 return kFALSE;
00567 }
00568
00569
00570 Bool_t TOracleServer::Rollback()
00571 {
00572
00573
00574
00575 CheckConnect("Rollback", kFALSE);
00576
00577 try {
00578 fConn->rollback();
00579 return kTRUE;
00580 } CatchError("Rollback")
00581
00582 return kFALSE;
00583 }
00584
00585
00586 void TOracleServer::SetDatimeFormat(const char* fmt)
00587 {
00588
00589
00590
00591 if (fmt==0) fmt = "MM/DD/YYYY, HH24:MI:SS";
00592 fgDatimeFormat = fmt;
00593 }
00594
00595
00596 const char* TOracleServer::GetDatimeFormat()
00597 {
00598
00599
00600 return fgDatimeFormat;
00601 }