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