#include "TOracleServer.h"
#include "TOracleResult.h"
#include "TOracleStatement.h"
#include "TSQLColumnInfo.h"
#include "TSQLTableInfo.h"
#include "TUrl.h"
#include "TList.h"
#include "TObjString.h"
ClassImp(TOracleServer)
const char* TOracleServer::fgDatimeFormat = "MM/DD/YYYY, HH24:MI:SS";
#define CheckConnect(method, res) \
ClearError(); \
if (!IsConnected()) { \
SetError(-1,"Oracle database is not connected",method); \
return res; \
}
#define CatchError(method) \
catch (SQLException &oraex) { \
SetError(oraex.getErrorCode(), oraex.getMessage().c_str(), method); \
}
TOracleServer::TOracleServer(const char *db, const char *uid, const char *pw)
{
fEnv = 0;
fConn = 0;
TUrl url(db);
if (!url.IsValid()) {
TString errmsg = "Malformed db argument ";
errmsg+=db;
SetError(-1, errmsg.Data(), "TOracleServer");
MakeZombie();
return;
}
if (strncmp(url.GetProtocol(), "oracle", 6)) {
SetError(-1, "protocol in db argument should be oracle://", "TOracleServer");
MakeZombie();
return;
}
const char *conn_str = url.GetFile();
if (conn_str!=0)
if (*conn_str == '/') conn_str++;
try {
TString options = url.GetOptions();
Int_t pos = options.Index("ObjectMode");
if (pos != kNPOS) {
fEnv = Environment::createEnvironment(Environment::OBJECT);
} else {
fEnv = Environment::createEnvironment();
}
fConn = fEnv->createConnection(uid, pw, conn_str);
fType = "Oracle";
fHost = url.GetHost();
fDB = conn_str;
fPort = url.GetPort();
fPort = (fPort>0) ? fPort : 1521;
return;
} CatchError("TOracleServer")
MakeZombie();
}
TOracleServer::~TOracleServer()
{
if (IsConnected())
Close();
}
void TOracleServer::Close(Option_t *)
{
ClearError();
try {
if (fConn)
fEnv->terminateConnection(fConn);
if (fEnv)
Environment::terminateEnvironment(fEnv);
} CatchError("Close")
fPort = -1;
}
TSQLStatement *TOracleServer::Statement(const char *sql, Int_t niter)
{
CheckConnect("Statement",0);
if (!sql || !*sql) {
SetError(-1, "no query string specified","Statement");
return 0;
}
try {
oracle::occi::Statement *stmt = fConn->createStatement(sql);
Blob parblob(fConn);
return new TOracleStatement(fEnv, fConn, stmt, niter, fErrorOut);
} CatchError("Statement")
return 0;
}
TSQLResult *TOracleServer::Query(const char *sql)
{
CheckConnect("Query",0);
if (!sql || !*sql) {
SetError(-1, "no query string specified","Query");
return 0;
}
try {
oracle::occi::Statement *stmt = fConn->createStatement();
stmt->setSQL(sql);
stmt->setPrefetchRowCount(1000);
stmt->setPrefetchMemorySize(1000000);
stmt->execute();
TOracleResult *res = new TOracleResult(fConn, stmt);
return res;
} CatchError("Query")
return 0;
}
Bool_t TOracleServer::Exec(const char* sql)
{
CheckConnect("Exec", kFALSE);
if (!sql || !*sql) {
SetError(-1, "no query string specified","Exec");
return kFALSE;
}
oracle::occi::Statement *stmt = 0;
Bool_t res = kFALSE;
try {
stmt = fConn->createStatement(sql);
stmt->execute();
res = kTRUE;
} CatchError("Exec")
try {
fConn->terminateStatement(stmt);
} CatchError("Exec")
return res;
}
TSQLResult *TOracleServer::GetTables(const char *dbname, const char * )
{
CheckConnect("GetTables",0);
TString sqlstr("SELECT object_name,owner FROM ALL_OBJECTS WHERE object_type='TABLE'");
if (dbname && dbname[0])
sqlstr = sqlstr + " AND owner='" + dbname + "'";
return Query(sqlstr.Data());
}
TList* TOracleServer::GetTablesList(const char* wild)
{
CheckConnect("GetTablesList",0);
TString cmd("SELECT table_name FROM user_tables");
if ((wild!=0) && (*wild!=0))
cmd+=Form(" WHERE table_name LIKE '%s'", wild);
TSQLStatement* stmt = Statement(cmd);
if (stmt==0) return 0;
TList* lst = 0;
if (stmt->Process()) {
stmt->StoreResult();
while (stmt->NextResultRow()) {
const char* tablename = stmt->GetString(0);
if (tablename==0) continue;
if (lst==0) {
lst = new TList;
lst->SetOwner(kTRUE);
}
lst->Add(new TObjString(tablename));
}
}
delete stmt;
return lst;
}
TSQLTableInfo *TOracleServer::GetTableInfo(const char* tablename)
{
CheckConnect("GetTableInfo",0);
if ((tablename==0) || (*tablename==0)) return 0;
TString table(tablename);
table.ToUpper();
TString sql;
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());
TSQLStatement* stmt = Statement(sql.Data(), 10);
if (stmt==0) return 0;
if (!stmt->Process()) {
delete stmt;
return 0;
}
TList* lst = 0;
stmt->StoreResult();
while (stmt->NextResultRow()) {
const char* columnname = stmt->GetString(0);
TString data_type = stmt->GetString(1);
Int_t data_length = stmt->GetInt(2);
Int_t data_precision = stmt->GetInt(3);
Int_t data_scale = stmt->GetInt(4);
const char* nstr = stmt->GetString(5);
Int_t char_col_decl_length = stmt->GetInt(6);
Int_t data_sign = -1;
Int_t sqltype = kSQL_NONE;
if (data_type=="NUMBER") {
sqltype = kSQL_NUMERIC;
if (data_precision<=0) {
data_precision = -1;
data_scale = -1;
} else
if (data_scale<=0)
data_scale = -1;
data_sign = 1;
} else
if (data_type=="CHAR") {
sqltype = kSQL_CHAR;
data_precision = char_col_decl_length;
data_scale = -1;
} else
if ((data_type=="VARCHAR") || (data_type=="VARCHAR2")) {
sqltype = kSQL_VARCHAR;
data_precision = char_col_decl_length;
data_scale = -1;
} else
if (data_type=="FLOAT") {
sqltype = kSQL_FLOAT;
data_scale = -1;
if (data_precision==126) data_precision = -1;
data_sign = 1;
} else
if (data_type=="BINARY_FLOAT") {
sqltype = kSQL_FLOAT;
data_scale = -1;
data_precision = -1;
data_sign = 1;
} else
if (data_type=="BINARY_DOUBLE") {
sqltype = kSQL_DOUBLE;
data_scale = -1;
data_precision = -1;
data_sign = 1;
} else
if (data_type=="LONG") {
sqltype = kSQL_VARCHAR;
data_length = 0x7fffffff;
data_precision = -1;
data_scale = -1;
} else
if (data_type.Contains("TIMESTAMP")) {
sqltype = kSQL_TIMESTAMP;
data_precision = -1;
}
Bool_t IsNullable = kFALSE;
if (nstr!=0)
IsNullable = (*nstr=='Y') || (*nstr=='y');
TSQLColumnInfo* info =
new TSQLColumnInfo(columnname,
data_type,
IsNullable,
sqltype,
data_length,
data_precision,
data_scale,
data_sign);
if (lst==0) lst = new TList;
lst->Add(info);
}
delete stmt;
return new TSQLTableInfo(tablename, lst);
}
TSQLResult *TOracleServer::GetColumns(const char * , const char *tablename,
const char * wild)
{
CheckConnect("GetColumns",0);
TString sql;
TString table(tablename);
table.ToUpper();
if (wild && wild[0])
sql.Form("SELECT COLUMN_NAME FROM user_tab_columns WHERE table_name like '%s' ORDER BY COLUMN_ID", wild);
else
sql.Form("SELECT COLUMN_NAME FROM user_tab_columns WHERE table_name = '%s' ORDER BY COLUMN_ID", table.Data());
return Query(sql);
}
Int_t TOracleServer::SelectDataBase(const char * )
{
CheckConnect("SelectDataBase", -1);
return 0;
}
TSQLResult *TOracleServer::GetDataBases(const char * )
{
CheckConnect("GetDataBases",0);
return 0;
}
Int_t TOracleServer::CreateDataBase(const char * )
{
CheckConnect("CreateDataBase",-1);
return -1;
}
Int_t TOracleServer::DropDataBase(const char * )
{
CheckConnect("DropDataBase",-1);
return -1;
}
Int_t TOracleServer::Reload()
{
CheckConnect("Reload", -1);
return -1;
}
Int_t TOracleServer::Shutdown()
{
CheckConnect("Shutdown", -1);
return -1;
}
const char *TOracleServer::ServerInfo()
{
CheckConnect("ServerInfo", 0);
fInfo = "Oracle";
TSQLStatement* stmt = Statement("select * from v$version");
if (stmt!=0) {
stmt->EnableErrorOutput(kFALSE);
if (stmt->Process()) {
fInfo = "";
stmt->StoreResult();
while (stmt->NextResultRow()) {
if (fInfo.Length()>0) fInfo += "\n";
fInfo += stmt->GetString(0);
}
}
delete stmt;
}
return fInfo.Data();
}
Bool_t TOracleServer::StartTransaction()
{
return Commit();
}
Bool_t TOracleServer::Commit()
{
CheckConnect("Commit", kFALSE);
try {
fConn->commit();
return kTRUE;
} CatchError("Commit")
return kFALSE;
}
Bool_t TOracleServer::Rollback()
{
CheckConnect("Rollback", kFALSE);
try {
fConn->rollback();
return kTRUE;
} CatchError("Rollback")
return kFALSE;
}
void TOracleServer::SetDatimeFormat(const char* fmt)
{
if (fmt==0) fmt = "MM/DD/YYYY, HH24:MI:SS";
fgDatimeFormat = fmt;
}
const char* TOracleServer::GetDatimeFormat()
{
return fgDatimeFormat;
}