From 725a35f2ac42fbbbed4f0d94c0a3db4da138ee93 Mon Sep 17 00:00:00 2001
From: Steven Murray <steven.murray@cern.ch>
Date: Thu, 19 May 2016 11:23:51 +0200
Subject: [PATCH] OcciStmt now inherits from DbStmt

---
 catalogue/CMakeLists.txt   |  1 +
 catalogue/DbStmt.cpp       | 31 ++++++++++++++
 catalogue/DbStmt.hpp       | 82 ++++++++++++++++++++++++++++++++++++++
 catalogue/OcciRsetTest.cpp |  8 ++--
 catalogue/OcciStmt.cpp     | 32 +++++++--------
 catalogue/OcciStmt.hpp     | 42 +++++++++----------
 catalogue/OcciStmtTest.cpp |  2 +-
 7 files changed, 157 insertions(+), 41 deletions(-)
 create mode 100644 catalogue/DbStmt.cpp
 create mode 100644 catalogue/DbStmt.hpp

diff --git a/catalogue/CMakeLists.txt b/catalogue/CMakeLists.txt
index a2b0588a39..a68517ce8b 100644
--- a/catalogue/CMakeLists.txt
+++ b/catalogue/CMakeLists.txt
@@ -25,6 +25,7 @@ set (CATALOGUE_LIB_SRC_FILES
   Catalogue.cpp
   DbLogin.cpp
   DbRset.cpp
+  DbStmt.cpp
   TapeFileWritten.cpp
   OcciConn.cpp
   OcciEnv.cpp
diff --git a/catalogue/DbStmt.cpp b/catalogue/DbStmt.cpp
new file mode 100644
index 0000000000..eeb73bcc7c
--- /dev/null
+++ b/catalogue/DbStmt.cpp
@@ -0,0 +1,31 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "catalogue/DbStmt.hpp"
+
+namespace cta {
+namespace catalogue {
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+DbStmt::~DbStmt() throw() {
+}
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/DbStmt.hpp b/catalogue/DbStmt.hpp
new file mode 100644
index 0000000000..297ac6a711
--- /dev/null
+++ b/catalogue/DbStmt.hpp
@@ -0,0 +1,82 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "catalogue/DbRset.hpp"
+
+#include <stdint.h>
+
+namespace cta {
+namespace catalogue {
+
+/**
+ * Abstract class specifying the interface to a database statement.
+ *
+ * Please note that this interface intentionally uses C-strings instead of
+ * std::string so that it can be used by code compiled against the CXX11 ABI and
+ * by code compiled against a pre-CXX11 ABI.
+ */
+class DbStmt {
+public:
+
+  /**
+   * Destructor.
+   */
+  virtual ~DbStmt() throw() = 0;
+
+  /**
+   * Idempotent close() method.  The destructor calls this method.
+   */
+  virtual void close() = 0;
+
+  /**
+   * Returns the SQL statement.
+   *
+   * @return The SQL statement.
+   */
+  virtual const char *getSql() const = 0;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  virtual void bind(const char *const paramName, const uint64_t paramValue) = 0;
+
+  /** 
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */ 
+  virtual void bind(const char*paramName, const char *paramValue) = 0;
+
+  /**
+   *  Executes the statement and returns the result set.
+   *
+   *  @return The result set.  Please note that it is the responsibility of the
+   *  caller to free the memory associated with the result set.
+   */
+  virtual DbRset *executeQuery() = 0;
+
+}; // class DbStmt
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/OcciRsetTest.cpp b/catalogue/OcciRsetTest.cpp
index c59e60b7fa..a19151bf44 100644
--- a/catalogue/OcciRsetTest.cpp
+++ b/catalogue/OcciRsetTest.cpp
@@ -51,7 +51,7 @@ TEST_F(cta_catalogue_OcciRsetTest, executeQuery) {
     dbLogin.database.c_str()));
   const char *const sql = "SELECT DUMMY FROM DUAL";
   std::unique_ptr<OcciStmt> stmt(conn->createStmt(sql));
-  std::unique_ptr<OcciRset> rset(stmt->executeQuery());
+  std::unique_ptr<DbRset> rset(stmt->executeQuery());
   ASSERT_TRUE(rset->next());
   std::string text(rset->columnText("DUMMY"));
   ASSERT_EQ(std::string("X"), text);
@@ -70,13 +70,13 @@ TEST_F(cta_catalogue_OcciRsetTest, executeQueryRelyOnRsetDestructorForCacheDelet
     dbLogin.database.c_str()));
   const char *const sql = "SELECT DUMMY FROM DUAL";
   std::unique_ptr<OcciStmt> stmt(conn->createStmt(sql));
-  std::unique_ptr<OcciRset> rset(stmt->executeQuery());
+  std::unique_ptr<DbRset> rset(stmt->executeQuery());
   ASSERT_TRUE(rset->next());
   std::string text(rset->columnText("DUMMY"));
   ASSERT_EQ(std::string("X"), text);
 }
 
-TEST_F(cta_catalogue_OcciRsetTest, eexcuteQuery_uint32_t) {
+TEST_F(cta_catalogue_OcciRsetTest, executeQuery_uint32_t) {
   using namespace cta;
   using namespace cta::catalogue;
 
@@ -88,7 +88,7 @@ TEST_F(cta_catalogue_OcciRsetTest, eexcuteQuery_uint32_t) {
     dbLogin.database.c_str()));
   const char *const sql = "SELECT 1234 AS I FROM DUAL";
   std::unique_ptr<OcciStmt> stmt(conn->createStmt(sql));
-  std::unique_ptr<OcciRset> rset(stmt->executeQuery());
+  std::unique_ptr<DbRset> rset(stmt->executeQuery());
   ASSERT_TRUE(rset->next());
   const uint32_t i = rset->columnUint64("I");
   ASSERT_EQ(1234, i);
diff --git a/catalogue/OcciStmt.cpp b/catalogue/OcciStmt.cpp
index 7abb6923d9..9c9aa3da18 100644
--- a/catalogue/OcciStmt.cpp
+++ b/catalogue/OcciStmt.cpp
@@ -80,20 +80,6 @@ const char *OcciStmt::getSql() const {
   return m_sql.get();
 }
 
-//------------------------------------------------------------------------------
-// get
-//------------------------------------------------------------------------------
-oracle::occi::Statement *OcciStmt::get() const {
-  return m_stmt;
-}
-
-//------------------------------------------------------------------------------
-// operator->
-//------------------------------------------------------------------------------
-oracle::occi::Statement *OcciStmt::operator->() const {
-  return get();
-}
-
 //------------------------------------------------------------------------------
 // bind
 //------------------------------------------------------------------------------
@@ -113,16 +99,30 @@ void OcciStmt::bind(const char *paramName, const char *paramValue) {
 //------------------------------------------------------------------------------
 // executeQuery
 //------------------------------------------------------------------------------
-OcciRset *OcciStmt::executeQuery() {
+DbRset *OcciStmt::executeQuery() {
   using namespace oracle;
 
   try {
     return new OcciRset(*this, m_stmt->executeQuery());
   } catch(std::exception &ne) {
     throw std::runtime_error(std::string(__FUNCTION__) + " failed for SQL statement " + getSql() +
-      ": " + ne.what());
+                             ": " + ne.what());
   }
 }
 
+//------------------------------------------------------------------------------
+// get
+//------------------------------------------------------------------------------
+oracle::occi::Statement *OcciStmt::get() const {
+  return m_stmt;
+}
+
+//------------------------------------------------------------------------------
+// operator->
+//------------------------------------------------------------------------------
+oracle::occi::Statement *OcciStmt::operator->() const {
+  return get();
+}
+
 } // namespace catalogue
 } // namespace cta
diff --git a/catalogue/OcciStmt.hpp b/catalogue/OcciStmt.hpp
index c4aaf7347f..efc1a6db6b 100644
--- a/catalogue/OcciStmt.hpp
+++ b/catalogue/OcciStmt.hpp
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include "catalogue/DbStmt.hpp"
+
 #include <memory>
 #include <mutex>
 #include <occi.h>
@@ -45,7 +47,7 @@ class OcciRset;
  * different with respect to _GLIBCXX_USE_CXX11_ABI.  For example this wrapper
  * does not expose the std::string data type.
  */
-class OcciStmt {
+class OcciStmt: public DbStmt {
 public:
 
   /**
@@ -74,28 +76,14 @@ public:
   /**
    * Idempotent close() method.  The destructor calls this method.
    */
-  void close();
+  virtual void close();
 
   /**
    * Returns the SQL statement.
    *
    * @return The SQL statement.
    */
-  const char *getSql() const;
-
-  /**
-   * Returns the underlying OCCI result set.
-   *
-   * @return The underlying OCCI result set.
-   */
-  oracle::occi::Statement *get() const;
-
-  /**
-   * Alias for the get() method.
-   *
-   * @return The underlying OCCI result set.
-   */
-  oracle::occi::Statement *operator->() const;
+  virtual const char *getSql() const;
 
   /**
    * Binds an SQL parameter.
@@ -105,12 +93,12 @@ public:
    */
   void bind(const char *const paramName, const uint64_t paramValue);
 
-  /** 
+  /**
    * Binds an SQL parameter.
    *
    * @param paramName The name of the parameter.
    * @param paramValue The value to be bound.
-   */ 
+   */
   void bind(const char*paramName, const char *paramValue);
 
   /**
@@ -119,7 +107,21 @@ public:
    *  @return The result set.  Please note that it is the responsibility of the
    *  caller to free the memory associated with the result set.
    */
-  OcciRset *executeQuery();
+  DbRset *executeQuery();
+
+  /**
+   * Returns the underlying OCCI result set.
+   *
+   * @return The underlying OCCI result set.
+   */
+  oracle::occi::Statement *get() const;
+
+  /**
+   * Alias for the get() method.
+   *
+   * @return The underlying OCCI result set.
+   */
+  oracle::occi::Statement *operator->() const;
 
 private:
 
diff --git a/catalogue/OcciStmtTest.cpp b/catalogue/OcciStmtTest.cpp
index b728eaf8f5..4f37d9bfa6 100644
--- a/catalogue/OcciStmtTest.cpp
+++ b/catalogue/OcciStmtTest.cpp
@@ -50,7 +50,7 @@ TEST_F(cta_catalogue_OcciStmtTest, executeQuery) {
     dbLogin.database.c_str()));
   const char *const sql = "SELECT * FROM DUAL";
   std::unique_ptr<OcciStmt> stmt(conn->createStmt(sql));
-  std::unique_ptr<OcciRset> rset(stmt->executeQuery());
+  std::unique_ptr<DbRset> rset(stmt->executeQuery());
 }
 
 } // namespace unitTests
-- 
GitLab