From a2b38dd49f1e10f354432f1f6ecaf2abfc27ac5e Mon Sep 17 00:00:00 2001 From: Fons Rademakers <Fons.Rademakers@cern.ch> Date: Mon, 28 Feb 2005 19:11:00 +0000 Subject: [PATCH] From Yan Liu and Shaowen Wang: This is the first version of the new oracle plugin. To build this plugin one needs to install the following Oracle InstantClient rpms: oracle-instantclient-basic-10.1.0.3-1 oracle-instantclient-devel-10.1.0.3-1 And the following environment variables in your .[bash_]profile: export ORACLEINCDIR=/usr/include/oracle/10.1.0.3/client export ORACLELIBDIR=/usr/lib/oracle/10.1.0.3/client/lib export LD_LIBRARY_PATH=$ORACLELIBDIR:$LD_LIBRARY_PATH git-svn-id: http://root.cern.ch/svn/root/trunk@11203 27541ba8-7e3a-0410-8455-c3a389f83636 --- Makefile | 8 +- config/Makefile.in | 4 + configure | 98 ++++++++---- oracle/Module.mk | 71 +++++++++ oracle/inc/LinkDef.h | 22 +++ oracle/inc/TOracleResult.h | 66 ++++++++ oracle/inc/TOracleRow.h | 53 +++++++ oracle/inc/TOracleServer.h | 59 +++++++ oracle/src/TOracleResult.cxx | 139 +++++++++++++++++ oracle/src/TOracleRow.cxx | 132 ++++++++++++++++ oracle/src/TOracleServer.cxx | 293 +++++++++++++++++++++++++++++++++++ 11 files changed, 916 insertions(+), 29 deletions(-) create mode 100644 oracle/Module.mk create mode 100644 oracle/inc/LinkDef.h create mode 100644 oracle/inc/TOracleResult.h create mode 100644 oracle/inc/TOracleRow.h create mode 100644 oracle/inc/TOracleServer.h create mode 100644 oracle/src/TOracleResult.cxx create mode 100644 oracle/src/TOracleRow.cxx create mode 100644 oracle/src/TOracleServer.cxx diff --git a/Makefile b/Makefile index aec37467166..a9f2c0daf79 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,11 @@ ifneq ($(MYSQLCLILIB),) MODULES += mysql endif endif +ifneq ($(ORACLEINCDIR),) +ifneq ($(ORACLECLILIB),) +MODULES += oracle +endif +endif ifneq ($(PGSQLINCDIR),) ifneq ($(PGSQLCLILIB),) MODULES += pgsql @@ -189,7 +194,7 @@ MODULES += unix winnt x11 x11ttf win32 win32gdk gl rfio thread \ pythia pythia6 venus table mysql pgsql sapdb srputils x3d \ rootx rootd proofd dcache chirp hbook alien asimage ldap \ mlp krb5auth rpdutils globusauth pyroot xml ruby qt qtroot \ - xrootd netx clarens peac + xrootd netx clarens peac oracle MODULES := $(sort $(MODULES)) # removes duplicates endif @@ -871,6 +876,7 @@ showbuild: @echo "SHIFTLIB = $(SHIFTLIB)" @echo "DCAPLIB = $(DCAPLIB)" @echo "MYSQLINCDIR = $(MYSQLINCDIR)" + @echo "ORACLEINCDIR = $(ORACLEINCDIR)" @echo "PGSQLINCDIR = $(PGSQLINCDIR)" @echo "PYTHONLIBDIR = $(PYTHONLIBDIR)" @echo "PYTHONLIB = $(PYTHONLIB)" diff --git a/config/Makefile.in b/config/Makefile.in index 785ba034c5d..0190bea37bb 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -59,6 +59,10 @@ MYSQLLIBDIR := @mysqllibdir@ MYSQLCLILIB := @mysqllib@ MYSQLINCDIR := @mysqlincdir@ +ORACLELIBDIR := @oraclelibdir@ +ORACLECLILIB := @oraclelib@ +ORACLEINCDIR := @oracleincdir@ + PGSQLLIBDIR := @pgsqllibdir@ PGSQLCLILIB := @pgsqllib@ PGSQLINCDIR := @pgsqlincdir@ diff --git a/configure b/configure index 6b81669598e..00fff73cf50 100755 --- a/configure +++ b/configure @@ -36,6 +36,7 @@ options=" \ enable_ldap \ enable_mysql \ enable_opengl \ + enable_oracle \ enable_peac \ enable_pgsql \ enable_pythia \ @@ -84,6 +85,7 @@ THREAD \ OPENGL \ IVROOT \ MYSQL \ +ORACLE \ PGSQL \ QTDIR \ SAPDB \ @@ -579,6 +581,7 @@ enable/disable options, prefix with either --enable- or --disable- ldap LDAP support, requires (Open)LDAP libs mysql MySQL support, requires libmysqlclient opengl OpenGL support, requires libGL and libGLU + oracle Oracle support, requires libclntsh peac PEAC, PROOF Enabled Analysis Center, requires Clarens pgsql PostgreSQL support, requires libpq pythia Pythia5 EG support, requires libPythia @@ -620,6 +623,8 @@ with options, prefix with --with-, enables corresponding support mysql-libdir MySQL support, location of libmysqlclient opengl-incdir OpenGL support, location of GL/gl.h opengl-libdir OpenGL support, location of libGL + oracle-incdir Oracle support, location of occi.h + oracle-libdir Oracle support, location of libclntsh pgsql-incdir PostgreSQL support, location of libpq-fe.h pgsql-libdir PostgreSQL support, location of libpq pythia-libdir PYHTIA support, location of libPythia @@ -755,6 +760,8 @@ if test $# -gt 0 ; then --with-mysql-libdir=*) mysqllibdir=$optarg ; enable_mysql="yes" ;; --with-opengl-incdir=*) openglincdir=$optarg ; enable_opengl="yes" ;; --with-opengl-libdir=*) opengllibdir=$optarg ; enable_opengl="yes" ;; + --with-oracle-incdir=*) oracleincdir=$optarg ; enable_oracle="yes" ;; + --with-oracle-libdir=*) oraclelibdir=$optarg ; enable_oracle="yes" ;; --with-pgsql-incdir=*) pgsqlincdir=$optarg ; enable_pgsql="yes" ;; --with-pgsql-libdir=*) pgsqllibdir=$optarg ; enable_pgsql="yes" ;; --with-pythia-libdir=*) pythialibdir=$optarg ; enable_pythia="yes" ;; @@ -1071,6 +1078,38 @@ if test ! "x$enable_mysql" = "xno"; then fi fi +###################################################################### +# +### echo %%% Oracle Support - Third party libraries +# +# (See oracle.com) +# +# If the user has set the flags "--disable-oracle", we don't check for +# Oracle at all. +# +if test ! "x$enable_oracle" = "xno"; then + # Check for oracle include and library + check_header "occi.h" "$oracleincdir" \ + $ORACLE $ORACLE/include $ORACLEINCDIR /usr/local/include \ + /usr/include + oracleinc=$found_hdr + oracleincdir=$found_dir + + keeplibdir=$oraclelibdir + check_library "libclntsh" "$enable_shared" "$oraclelibdir" \ + $ORACLE $ORACLE/lib $ORACLELIBDIR /usr/local/lib /usr/lib + oraclelib=$found_lib + oraclelibdir=$found_dir + + check_library "libocci" "$enable_shared" "$keeplibdir" \ + $ORACLE $ORACLE/lib $ORACLELIBDIR /usr/local/lib /usr/lib + oraclelib="$oraclelib $found_lib" + + if test "x$oracleincdir" = "x" || test "x$oraclelib" = "x"; then + enable_oracle="no" + fi +fi + ###################################################################### # ### echo %%% PostgreSQL Support - Third party libraries @@ -1102,32 +1141,6 @@ if test ! "x$enable_pgsql" = "xno"; then fi fi -###################################################################### -# -### echo %%% Qt Support - Optional alternative graphics backend -# -# If the user has set the flags "--disable-qt", we don't check for -# Qt at all. -# -if test ! "x$enable_qt" = "xno"; then - # Check for Qt include and library - check_header "qt.h" "$qtincdir" $QTDIR $QTDIR/include \ - /usr/local/include /usr/local/qt/include /usr/include \ - /usr/include/qt - qtinc=$found_hdr - qtincdir=$found_dir - - check_library "libqt-mt libqt qt-mt* qt" "$enable_shared" \ - "$qtlibdir" $QTDIR $QTDIR/lib /usr/local/lib /usr/local/qt/lib \ - /usr/lib /usr/qt/lib - qtlib=$found_lib - qtlibdir=$found_dir - - if test "x$qtincdir" = "x" || test "x$qtlib" = "x"; then - enable_qt="no" - fi -fi - ###################################################################### # ### echo %%% SapDB Support - Third party libraries @@ -1164,6 +1177,32 @@ if test ! "x$enable_sapdb" = "xno"; then fi fi +###################################################################### +# +### echo %%% Qt Support - Optional alternative graphics backend +# +# If the user has set the flags "--disable-qt", we don't check for +# Qt at all. +# +if test ! "x$enable_qt" = "xno"; then + # Check for Qt include and library + check_header "qt.h" "$qtincdir" $QTDIR $QTDIR/include \ + /usr/local/include /usr/local/qt/include /usr/include \ + /usr/include/qt + qtinc=$found_hdr + qtincdir=$found_dir + + check_library "libqt-mt libqt qt-mt* qt" "$enable_shared" \ + "$qtlibdir" $QTDIR $QTDIR/lib /usr/local/lib /usr/local/qt/lib \ + /usr/lib /usr/qt/lib + qtlib=$found_lib + qtlibdir=$found_dir + + if test "x$qtincdir" = "x" || test "x$qtlib" = "x"; then + enable_qt="no" + fi +fi + ###################################################################### # ### echo %%% CASTOR Support - Third party libraries @@ -1615,7 +1654,7 @@ if test ! "x$enable_xml" = "xno" ; then /opt/libxml2/include /usr/local/include/libxml2 /usr/include/libxml2 xmlincdir=$found_dir - keeplib=$xmllibdir + keeplibdir=$xmllibdir check_library "libxml2_a libxml2" "$enable_shared" "$xmllibdir" $XMLDIR \ $XMLDIR/lib $XMLDIR/.libs /opt/libxml2/lib /usr/local/lib /usr/lib xmllib=$found_lib @@ -1627,7 +1666,7 @@ if test ! "x$enable_xml" = "xno" ; then /opt/libxml2/include /usr/local/include/libxml2 /usr/include/libxml2 iconvincdir=$found_dir - check_library "iconv_a" "$enable_shared" "$keeplib" $ICONVDIR \ + check_library "iconv_a" "$enable_shared" "$keeplibdir" $ICONVDIR \ $ICONVDIR/lib $XMLDIR $XMLDIR/lib $XMLDIR/.libs \ /opt/libxml2/lib /usr/local/lib /usr/lib iconvlib=$found_lib @@ -2787,6 +2826,9 @@ sed -e "s|@ldflags@||" \ -e "s|@opengllib@|$opengllib|" \ -e "s|@opengllibdir@|$opengllibdir|" \ -e "s|@openglulib@|$openglulib|" \ + -e "s|@oracleincdir@|$oracleincdir|" \ + -e "s|@oraclelib@|$oraclelib|" \ + -e "s|@oraclelibdir@|$oraclelibdir|" \ -e "s|@pgsqlincdir@|$pgsqlincdir|" \ -e "s|@pgsqllib@|$pgsqllib|" \ -e "s|@pgsqllibdir@|$pgsqllibdir|" \ diff --git a/oracle/Module.mk b/oracle/Module.mk new file mode 100644 index 00000000000..39604eb50b8 --- /dev/null +++ b/oracle/Module.mk @@ -0,0 +1,71 @@ +# Module.mk for oracle module +# Copyright (c) 2005 Rene Brun and Fons Rademakers +# +# Author: Yan Liu, 11/17/2004 + +MODDIR := oracle +MODDIRS := $(MODDIR)/src +MODDIRI := $(MODDIR)/inc + +ORACLEDIR := $(MODDIR) +ORACLEDIRS := $(ORACLEDIR)/src +ORACLEDIRI := $(ORACLEDIR)/inc + +##### libOracle ##### +ORACLEL := $(MODDIRI)/LinkDef.h +ORACLEDS := $(MODDIRS)/G__Oracle.cxx +ORACLEDO := $(ORACLEDS:.cxx=.o) +ORACLEDH := $(ORACLEDS:.cxx=.h) + +ORACLEH := $(filter-out $(MODDIRI)/LinkDef%,$(wildcard $(MODDIRI)/*.h)) +ORACLES := $(filter-out $(MODDIRS)/G__%,$(wildcard $(MODDIRS)/*.cxx)) +ORACLEO := $(ORACLES:.cxx=.o) + +ORACLEDEP := $(ORACLEO:.o=.d) $(ORACLEDO:.o=.d) + +ORACLELIB := $(LPATH)/libOracle.$(SOEXT) + +# used in the main Makefile +ALLHDRS += $(patsubst $(MODDIRI)/%.h,include/%.h,$(ORACLEH)) +ALLLIBS += $(ORACLELIB) + +# include all dependency files +INCLUDEFILES += $(ORACLEDEP) + +##### local rules ##### +include/%.h: $(ORACLEDIRI)/%.h + cp $< $@ + +$(ORACLELIB): $(ORACLEO) $(ORACLEDO) $(MAINLIBS) + @$(MAKELIB) $(PLATFORM) $(LD) "$(LDFLAGS)" \ + "$(SOFLAGS)" libOracle.$(SOEXT) $@ "$(ORACLEO) $(ORACLEDO)" \ + "$(ORACLELIBEXTRA) $(ORACLELIBDIR) $(ORACLECLILIB)" + +$(ORACLEDS): $(ORACLEH) $(ORACLEL) $(ROOTCINTTMP) + @echo "Generating dictionary $@..." + $(ROOTCINTTMP) -f $@ -c $(ORACLEH) $(ORACLEL) + +$(ORACLEDO): $(ORACLEDS) + $(CXX) $(NOOPT) $(CXXFLAGS) -I$(ORACLEINCDIR) -I. -o $@ -c $< + +all-oracle: $(ORACLELIB) + +map-oracle: $(RLIBMAP) + $(RLIBMAP) -r $(ROOTMAP) -l $(ORACLELIB) \ + -d $(ORACLELIBDEP) -c $(ORACLEL) + +map:: map-oracle + +clean-oracle: + @rm -f $(ORACLEO) $(ORACLEDO) + +clean:: clean-oracle + +distclean-oracle: clean-oracle + @rm -f $(ORACLEDEP) $(ORACLEDS) $(ORACLEDH) $(ORACLELIB) + +distclean:: distclean-oracle + +##### extra rules ###### +$(ORACLEO): %.o: %.cxx + $(CXX) $(OPT) $(CXXFLAGS) -I$(ORACLEINCDIR) -o $@ -c $< diff --git a/oracle/inc/LinkDef.h b/oracle/inc/LinkDef.h new file mode 100644 index 00000000000..4f4268ab9da --- /dev/null +++ b/oracle/inc/LinkDef.h @@ -0,0 +1,22 @@ +// @(#)root/oracle:$Name: v4-00-08 $:$Id: LinkDef.h,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class TOracleServer; +#pragma link C++ class TOracleResult; +#pragma link C++ class TOracleRow; + +#endif diff --git a/oracle/inc/TOracleResult.h b/oracle/inc/TOracleResult.h new file mode 100644 index 00000000000..4844a62a428 --- /dev/null +++ b/oracle/inc/TOracleResult.h @@ -0,0 +1,66 @@ +// @(#)root/physics:$Name: v4-00-08 $:$Id: TOracleResult.h,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TOracleResult +#define ROOT_TOracleResult + +#ifndef ROOT_TSQLResult +#include "TSQLResult.h" +#endif + +#if !defined(__CINT__) +#ifndef R__WIN32 +#include <sys/time.h> +#endif +#include <occi.h> +using namespace std; +using namespace oracle::occi; +#else +/*namespace oracle { + namespace occi { class Statement; } + namespace occi { class ResultSet; } + namespace occi { class MetaData; } +} +namespace std { + using vector: +}*/ +class Statement; +class ResultSet; +class MetaData; +#endif + + +class TOracleResult : public TSQLResult { + +private: + Statement *fStmt; + ResultSet *fResult; // query result (rows) + vector<MetaData> *fFieldInfo; // info for each field in the row + Int_t fFieldCount; // num of fields in resultset + UInt_t fUpdateCount; //for dml query, mutual exclusive with above + Int_t fResultType; // 0 - Update(dml); 1 - Select; -1 - empty + + Bool_t IsValid(Int_t field); + void GetMetaDataInfo(); + +public: + TOracleResult(Statement *stmt); + ~TOracleResult(); + + void Close(Option_t *opt=""); + Int_t GetFieldCount(); + const char *GetFieldName(Int_t field); + TSQLRow *Next(); + + ClassDef(TOracleResult,0) // Oracle query result +}; + +#endif diff --git a/oracle/inc/TOracleRow.h b/oracle/inc/TOracleRow.h new file mode 100644 index 00000000000..383574c4f57 --- /dev/null +++ b/oracle/inc/TOracleRow.h @@ -0,0 +1,53 @@ +// @(#)root/physics:$Name: v4-00-08 $:$Id: TOracleRow.h,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TOracleRow +#define ROOT_TOracleRow + +#ifndef ROOT_TSQLRow +#include "TSQLRow.h" +#endif + +#if !defined(__CINT__) +#ifndef R__WIN32 +#include <sys/time.h> +#endif +#include <occi.h> +using namespace std; +using namespace oracle::occi; +#else +class ResultSet; +class MetaData; +#endif + +class TOracleRow : public TSQLRow { + +private: + ResultSet *fResult; // current result set + vector<MetaData> *fFieldInfo; // metadata for columns + UInt_t fUpdateCount; // for dml queries + Int_t fResultType; // 0 - Update(dml); 1 - Select; -1 - empty + + Bool_t IsValid(Int_t field); + +public: + TOracleRow(ResultSet *rs, vector<MetaData> *fieldMetaData); + TOracleRow(UInt_t updateCount); + ~TOracleRow(); + + void Close(Option_t *opt=""); + ULong_t GetFieldLength(Int_t field); + const char *GetField(Int_t field); + + ClassDef(TOracleRow,0) // One row of Oracle query result +}; + +#endif diff --git a/oracle/inc/TOracleServer.h b/oracle/inc/TOracleServer.h new file mode 100644 index 00000000000..2331793f41c --- /dev/null +++ b/oracle/inc/TOracleServer.h @@ -0,0 +1,59 @@ +// @(#)root/physics:$Name: v4-00-08 $:$Id: TOracleServer.h,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#ifndef ROOT_TOracleServer +#define ROOT_TOracleServer + +#ifndef ROOT_TSQLServer +#include "TSQLServer.h" +#endif + +#if !defined(__CINT__) +#ifndef R__WIN32 +#include <sys/time.h> +#endif +#include <occi.h> +using namespace std; +using namespace oracle::occi; +#else +class Environment; +class Connection; +class Statement; +#endif + + +class TOracleServer : public TSQLServer { + +private: + Environment *fEnv; // environment of Oracle access + Connection *fConn; // connection to Oracle server + Statement *fStmt; // resusable statement object + +public: + TOracleServer(const char *db, const char *uid, const char *pw); + ~TOracleServer(); + + void Close(Option_t *opt=""); + TSQLResult *Query(const char *sql); + Int_t SelectDataBase(const char *dbname); + TSQLResult *GetDataBases(const char *wild = 0); + TSQLResult *GetTables(const char *dbname, const char *wild = 0); + TSQLResult *GetColumns(const char *dbname, const char *table, const char *wild = 0); + Int_t CreateDataBase(const char *dbname); + Int_t DropDataBase(const char *dbname); + Int_t Reload(); + Int_t Shutdown(); + const char *ServerInfo(); + + ClassDef(TOracleServer,0) // Connection to Oracle server +}; + +#endif diff --git a/oracle/src/TOracleResult.cxx b/oracle/src/TOracleResult.cxx new file mode 100644 index 00000000000..bff5fc76a21 --- /dev/null +++ b/oracle/src/TOracleResult.cxx @@ -0,0 +1,139 @@ +// @(#)root/oracle:$Name: v4-00-08 $:$Id: TOracleResult.cxx,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TOracleResult.h" +#include "TOracleRow.h" + + +ClassImp(TOracleResult) + +//______________________________________________________________________________ +void TOracleResult::GetMetaDataInfo() +{ + // Set fFieldInfo, fFieldCount, and fRowCount? + + if (!fResult) + return; + fFieldInfo = new vector<MetaData>(fResult->getColumnListMetaData()); + fFieldCount = fFieldInfo->size(); + fRowCount = -1; //doesn't provide row count +} + +//______________________________________________________________________________ +TOracleResult::TOracleResult(Statement *stmt) +{ + // Oracle query result. + + if (!stmt) { + Error("TOracleResult", "construction: empty statement"); + fResultType = -1; + } else { + fStmt = stmt; + if (stmt->status() == Statement::RESULT_SET_AVAILABLE) { + fResultType = 1; + fResult = stmt->getResultSet(); + GetMetaDataInfo(); + fUpdateCount = 0; + printf("type:%d columnsize:%d \n", fResultType, fFieldCount); + } else if (stmt->status() == Statement::UPDATE_COUNT_AVAILABLE) { + fResultType = 0; + fResult = 0; + fRowCount = 0; + fFieldInfo = 0; + fFieldCount= 0; + fUpdateCount = stmt->getUpdateCount(); + } else { + fResultType = -1; + } + } +} + +//______________________________________________________________________________ +TOracleResult::~TOracleResult() +{ + // Cleanup Oracle query result. + + if (fResult) + Close(); +} + +//______________________________________________________________________________ +void TOracleResult::Close(Option_t *) +{ + // Close query result. + + if (!fResult || !fStmt) + return; + fResultType = -1; + fStmt->closeResultSet(fResult); + fResult = 0; + fFieldInfo = 0; + fRowCount = 0; +} + +//______________________________________________________________________________ +Bool_t TOracleResult::IsValid(Int_t field) +{ + // Check if result set is open and field index within range. + + if (!fResult) { + Error("IsValid", "result set closed"); + return kFALSE; + } + if (field < 0 || field >= fFieldCount) { + Error("IsValid", "field index out of bounds"); + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Int_t TOracleResult::GetFieldCount() +{ + // Get number of fields in result. + + if (!fResult) { + Error("GetFieldCount", "result set closed"); + return 0; + } + return fFieldCount; +} + +//______________________________________________________________________________ +const char *TOracleResult::GetFieldName(Int_t field) +{ + // Get name of specified field. + + if (!IsValid(field)) + return 0; + string s = (*fFieldInfo)[field].getString(MetaData::ATTR_NAME); + return (const char *)s.c_str(); +} + +//______________________________________________________________________________ +TSQLRow *TOracleResult::Next() +{ + // Get next query result row. The returned object must be + // deleted by the user. + + if (fResultType == -1) { + Error("Next", "result set closed"); + return 0; + } + + if (fResultType == 0) { + // if dml query, ... + return new TOracleRow(fUpdateCount); + } + // if select query, + fResult->next(); + return new TOracleRow(fResult, fFieldInfo); +} diff --git a/oracle/src/TOracleRow.cxx b/oracle/src/TOracleRow.cxx new file mode 100644 index 00000000000..2c802c7b941 --- /dev/null +++ b/oracle/src/TOracleRow.cxx @@ -0,0 +1,132 @@ +// @(#)root/oracle:$Name: v4-00-08 $:$Id: TOracleRow.cxx,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TOracleRow.h" + +ClassImp(TOracleRow); + +//______________________________________________________________________________ +TOracleRow::TOracleRow(ResultSet *rs, vector<MetaData> *fieldMetaData) +{ + // Single row of query result. + + fResult = rs; + fFieldInfo = fieldMetaData; + fUpdateCount = 0; + fResultType = 1; +} + +//______________________________________________________________________________ +TOracleRow::TOracleRow(UInt_t updateCount) +{ + fUpdateCount = updateCount; + fResultType = 0; +} + +//______________________________________________________________________________ +TOracleRow::~TOracleRow() +{ + // Destroy row object. + + if (fResultType >= 0) { + Close(); + } +} + +//______________________________________________________________________________ +void TOracleRow::Close(Option_t *) +{ + // Close row. + + if (fResultType == -1) + return; + + fFieldInfo = 0; + fResult = 0; + fResultType = 0; +} + +//______________________________________________________________________________ +Bool_t TOracleRow::IsValid(Int_t field) +{ + // Check if row is open and field index within range. + + if (!fResult) { + Error("IsValid", "row closed"); + return kFALSE; + } + if (field < 0 || field >= (Int_t)fFieldInfo->size()) { + Error("IsValid", "field index out of bounds"); + return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +ULong_t TOracleRow::GetFieldLength(Int_t field) +{ + // Get length in bytes of specified field. + + if (!IsValid(field) || fFieldInfo->size() <= 0) + return 0; + + MetaData fieldMD = (*fFieldInfo)[field]; + + return fieldMD.getInt(MetaData::ATTR_DATA_SIZE); +} + +//______________________________________________________________________________ +const char *TOracleRow::GetField(Int_t field) +{ + // Note: Index starts from 0, not 1 as oracle call does. + // Data Type conversion: + // C++type OracleType + // Uint 2:0:x [type:precision:scale] + // float 2:noneZero:nonZero + // double 2:nonZero:-127 + // string 1:x:x + // string 188:0:x - Timestamp + + // Get specified field from row (0 <= field < GetFieldCount()). + + if (!IsValid(field) || !fResult || !fFieldInfo) { + Error("TOracleRow","GetField(): out-of-range or No ResultSet/MetaData"); + return 0; + } + int fDataType, fDataSize, fPrecision, fScale; + fDataType = (*fFieldInfo)[field].getInt(MetaData::ATTR_DATA_TYPE); + fDataSize = (*fFieldInfo)[field].getInt(MetaData::ATTR_DATA_SIZE); + fPrecision = (*fFieldInfo)[field].getInt(MetaData::ATTR_PRECISION); + fScale = (*fFieldInfo)[field].getInt(MetaData::ATTR_SCALE); + + switch (fDataType) { + case 2: //NUMBER + if (fScale == 0) { + return (const char *)(new unsigned int(fResult->getUInt(field+1))); + } else if (fPrecision != 0 && fScale == -127) { + return (const char *)(new double(fResult->getDouble(field+1))); + } else if (fScale > 0) { + return (const char *)(new float(fResult->getFloat(field+1))); + } + break; + case 1: //VARCHAR2 + return (const char *)(new string(fResult->getString(field+1))); + case 188: //Timestamp - oracle's date/time class. convert to string + { + Timestamp ts = fResult->getTimestamp(field+1); + string s = ts.toText("MM/dd/YYYY, HH:MM:SS",0); + return (const char *)s.c_str(); + } + default: + return 0; + } + return 0; +} diff --git a/oracle/src/TOracleServer.cxx b/oracle/src/TOracleServer.cxx new file mode 100644 index 00000000000..8422a2cd470 --- /dev/null +++ b/oracle/src/TOracleServer.cxx @@ -0,0 +1,293 @@ +// @(#)root/oracle:$Name: v4-00-08 $:$Id: TOracleServer.cxx,v 1.0 2004/12/04 17:00:45 rdm Exp $ +// Author: Yan Liu and Shaowen Wang 23/11/04 + +/************************************************************************* + * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. * + * All rights reserved. * + * * + * For the licensing terms see $ROOTSYS/LICENSE. * + * For the list of contributors see $ROOTSYS/README/CREDITS. * + *************************************************************************/ + +#include "TOracleServer.h" +#include "TOracleResult.h" +#include "TUrl.h" + + +ClassImp(TOracleServer) + +//______________________________________________________________________________ +TOracleServer::TOracleServer(const char *db, const char *uid, const char *pw) +{ + // Open a connection to a Oracle DB server. The db arguments should be + // of the form "oracle://connection_identifier][/<database>]", e.g.: + // "oracle://cmscald.fnal.gov/test". The uid is the username and pw + // the password that should be used for the connection. + + fEnv = 0; + fConn = 0; + fStmt = 0; + + TUrl url(db); + + if (!url.IsValid()) { + Error("TOracleServer", "malformed db argument %s", db); + MakeZombie(); + return; + } + + if (strncmp(url.GetProtocol(), "oracle", 6)) { + Error("TOracleServer", "protocol in db argument should be oracle it is %s", + url.GetProtocol()); + MakeZombie(); + return; + } + + const char *conn_str = 0; + if (strcmp(url.GetFile(), "/")) + conn_str = url.GetFile()+1; + + if (conn_str == 0) { + Error("TOracleServer", "Host name or database name missing in url %s", + url.GetUrl()); + MakeZombie(); + return; + } + + try { + fEnv = Environment::createEnvironment(); + fConn = fEnv->createConnection(uid, pw, conn_str); + + fType = "Oracle"; + fHost = url.GetHost(); + fDB = conn_str; + fPort = url.GetPort(); + fPort = (fPort) ? fPort : 1521; + //fPort = 1521; + } catch (SQLException &oraex) { + Error("TOracleServer", "connection to Oracle database %s failed (error: %s)",conn_str, (oraex.getMessage()).c_str()); + MakeZombie(); + } +} + +//______________________________________________________________________________ +TOracleServer::~TOracleServer() +{ + // Close connection to Oracle DB server. + + if (IsConnected()) + Close(); +} + +//______________________________________________________________________________ +void TOracleServer::Close(Option_t *) +{ + // Close connection to Oracle DB server. + try { + if (fStmt) + fConn->terminateStatement(fStmt); + if (fConn) + fEnv->terminateConnection(fConn); + if (fEnv) + Environment::terminateEnvironment(fEnv); + } catch (SQLException &oraex) { + Error("TOracleServer", "close connection failed: (error: %s)", (oraex.getMessage()).c_str()); + //MakeZombie(); + } + + fPort = -1; +} + +//______________________________________________________________________________ +TSQLResult *TOracleServer::Query(const char *sql) +{ + // Execute SQL command. Result object must be deleted by the user. + // Returns a pointer to a TSQLResult object if successful, 0 otherwise. + // The result object must be deleted by the user. + + if (!IsConnected()) { + Error("Query", "not connected"); + return 0; + } + + try { + if (!fStmt) + fStmt = fConn->createStatement(); + fStmt->setSQL(sql); + fStmt->execute(); + return new TOracleResult(fStmt); + } catch (SQLException &oraex) { + Error("TOracleServer", "query failed: (error: %s)", (oraex.getMessage()).c_str()); + //MakeZombie(); + } + + return 0; +} + +//______________________________________________________________________________ +TSQLResult *TOracleServer::GetTables(const char *dbname, const char *wild) +{ + // List all tables in the specified database. Wild is for wildcarding + // "t%" list all tables starting with "t". + // Returns a pointer to a TSQLResult object if successful, 0 otherwise. + // The result object must be deleted by the user. + + // user must be granted priveledge to query object "sys" + + if (!IsConnected()) { + Error("GetTables", "not connected"); + return 0; + } + + if (SelectDataBase(dbname) != 0) { + Error("GetTables", "no such database %s", dbname); + return 0; + } + + TSQLResult *tabRs; + if (wild) + { + char sql[256]; + sprintf(sql, "select TABLE_NAME FROM sys.user_tables where TABLE_NAME LIKE %s", wild); + tabRs = Query(sql); + } + else + tabRs = Query("select TABLE_NAME FROM sys.user_tables"); + return tabRs; +} + +//______________________________________________________________________________ +TSQLResult *TOracleServer::GetColumns(const char *dbname, const char *table, + const char *wild) +{ + // List all columns in specified table in the specified database. + // Wild is for wildcarding "t%" list all columns starting with "t". + // Returns a pointer to a TSQLResult object if successful, 0 otherwise. + // The result object must be deleted by the user. + + // user must be granted priveledge to query object "sys" + // TODO: to take adv of OCCI, should use MetaData to get column names + // + conn->getMetaData(table, MetaData::PTYPE_TABLE) + // + getVector(ATTR_LIST_COLUMNS) + // + getString(ATTR_NAME) + + if (!IsConnected()) { + Error("GetColumns", "not connected"); + return 0; + } + + if (SelectDataBase(dbname) != 0) { + Error("GetColumns", "no such database %s", dbname); + return 0; + } + + char sql[256]; + if (wild) { + sprintf(sql, "select column_name from sys.user_tab_columns where (table_name=%s) AND (column_name like %s)", table, wild); + } else { + sprintf(sql, "select column_name from sys.user_tab_columns where table_name=%s",table); + } + TSQLResult *tabRs = Query(sql); + return tabRs; +} + +//______________________________________________________________________________ +Int_t TOracleServer::SelectDataBase(const char * /*dbname*/) +{ + // NOT IMPLEMENTED + // Select a database. Returns 0 if successful, non-zero otherwise. + + if (!IsConnected()) { + Error("SelectDataBase", "not connected"); + return -1; + } + + // do nothing and return success code + return 0; +} + +//______________________________________________________________________________ +TSQLResult *TOracleServer::GetDataBases(const char * /*wild*/) +{ + // NOT IMPLEMENTED + // List all available databases. Wild is for wildcarding "t%" list all + // databases starting with "t". + // Returns a pointer to a TSQLResult object if successful, 0 otherwise. + // The result object must be deleted by the user. + + if (!IsConnected()) { + Error("GetDataBases", "not connected"); + return 0; + } + + return 0; +} + +//______________________________________________________________________________ +Int_t TOracleServer::CreateDataBase(const char * /*dbname*/) +{ + // NOT IMPLEMENTED + // Create a database. Returns 0 if successful, non-zero otherwise. + + if (!IsConnected()) { + Error("CreateDataBase", "not connected"); + return -1; + } + return -1; +} + +//______________________________________________________________________________ +Int_t TOracleServer::DropDataBase(const char * /*dbname*/) +{ + // NOT IMPLEMENTED + // Drop (i.e. delete) a database. Returns 0 if successful, non-zero + // otherwise. + + if (!IsConnected()) { + Error("DropDataBase", "not connected"); + return -1; + } + + return -1; +} + +//______________________________________________________________________________ +Int_t TOracleServer::Reload() +{ + // NOT IMPLEMENTED + // Reload permission tables. Returns 0 if successful, non-zero + // otherwise. User must have reload permissions. + + if (!IsConnected()) { + Error("Reload", "not connected"); + return -1; + } + return -1; +} + +//______________________________________________________________________________ +Int_t TOracleServer::Shutdown() +{ + // NOT IMPLEMENTED + // Shutdown the database server. Returns 0 if successful, non-zero + // otherwise. User must have shutdown permissions. + + if (!IsConnected()) { + Error("Shutdown", "not connected"); + return -1; + } + return -1; +} + +//______________________________________________________________________________ +const char *TOracleServer::ServerInfo() +{ + // NOT IMPLEMENTED + // Return server info. + + if (!IsConnected()) { + Error("ServerInfo", "not connected"); + return 0; + } + return "Oracle"; +} -- GitLab