From 925f63e8abec6dfd9696e2cd5f7b29246cfff072 Mon Sep 17 00:00:00 2001
From: Steven Murray <steven.murray@cern.ch>
Date: Fri, 1 Jul 2016 13:44:53 +0200
Subject: [PATCH] Implemented empty OracleCatalogue methods

This reverts commit 38cee8f68617fabd3096b034383123908aaeb1c7.
---
 catalogue/CMakeLists.txt                      |   7 +-
 catalogue/OcciConn.cpp                        |  14 ++-
 catalogue/OracleCatalogue.cpp                 | 117 +++++++++++++++++-
 .../create_oracle_catalogue_schema_header.sql |   8 ++
 catalogue/drop_oracle_catalogue_schema.sql    |   1 +
 5 files changed, 140 insertions(+), 7 deletions(-)

diff --git a/catalogue/CMakeLists.txt b/catalogue/CMakeLists.txt
index 5ac85ffc78..574c8c842b 100644
--- a/catalogue/CMakeLists.txt
+++ b/catalogue/CMakeLists.txt
@@ -65,7 +65,12 @@ target_link_libraries (ctacatalogue
 add_custom_command (OUTPUT create_sqlite_catalogue_schema.sql create_oracle_catalogue_schema.sql
   COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/create_sqlite_catalogue_schema_header.sql ${CMAKE_CURRENT_SOURCE_DIR}/catalogue_common_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/create_sqlite_catalogue_schema_trailer.sql > create_sqlite_catalogue_schema.sql
   COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/create_oracle_catalogue_schema_header.sql ${CMAKE_CURRENT_SOURCE_DIR}/catalogue_common_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/create_oracle_catalogue_schema_trailer.sql > create_oracle_catalogue_schema.sql
-  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/create_sqlite_catalogue_schema_header.sql catalogue_common_schema.sql ${CMAKE_CURRENT_SOURCE_DIR}/create_sqlite_catalogue_schema_trailer.sql)
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/catalogue_common_schema.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/create_sqlite_catalogue_schema_header.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/create_sqlite_catalogue_schema_trailer.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/create_oracle_catalogue_schema_header.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/create_oracle_catalogue_schema_trailer.sql)
 
 install (FILES ${CMAKE_CURRENT_BINARY_DIR}/create_sqlite_catalogue_schema.sql
   DESTINATION usr/share/cta-${CTA_VERSION}/sql
diff --git a/catalogue/OcciConn.cpp b/catalogue/OcciConn.cpp
index 1817b0e050..972226504c 100644
--- a/catalogue/OcciConn.cpp
+++ b/catalogue/OcciConn.cpp
@@ -99,14 +99,22 @@ DbStmt *OcciConn::createStmt(const std::string &sql) {
 // commit
 //------------------------------------------------------------------------------
 void OcciConn::commit() {
-  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
+  try {
+    m_conn->commit();
+  } catch(std::exception &se) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + se.what());
+  }
 }
 
 //------------------------------------------------------------------------------
-// commit
+// rollback
 //------------------------------------------------------------------------------
 void OcciConn::rollback() {
-  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
+  try {
+    m_conn->rollback();
+  } catch(std::exception &se) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + se.what());
+  }
 }
 
 } // namespace catalogue
diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp
index b49c517196..0d3e49fbfd 100644
--- a/catalogue/OracleCatalogue.cpp
+++ b/catalogue/OracleCatalogue.cpp
@@ -19,6 +19,7 @@
 #include "catalogue/OcciConn.hpp"
 #include "catalogue/OcciEnvSingleton.hpp"
 #include "catalogue/OracleCatalogue.hpp"
+#include "catalogue/UserError.hpp"
 #include "common/exception/Exception.hpp"
 #include "common/utils/utils.hpp"
 
@@ -45,14 +46,124 @@ OracleCatalogue::~OracleCatalogue() {
 // deleteArchiveFile
 //------------------------------------------------------------------------------
 common::dataStructures::ArchiveFile OracleCatalogue::deleteArchiveFile(const uint64_t archiveFileId) {
-  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
+  try {
+    std::unique_ptr<common::dataStructures::ArchiveFile> archiveFile;
+
+    const char *selectSql =
+      "SELECT "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID,"
+        "ARCHIVE_FILE.DISK_INSTANCE AS DISK_INSTANCE,"
+        "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID,"
+        "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
+        "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
+        "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
+        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
+        "ARCHIVE_FILE.FILE_SIZE AS FILE_SIZE,"
+        "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
+        "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
+        "ARCHIVE_FILE.STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
+        "ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME,"
+        "ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME,"
+        "TAPE_FILE.VID AS VID,"
+        "TAPE_FILE.FSEQ AS FSEQ,"
+        "TAPE_FILE.BLOCK_ID AS BLOCK_ID,"
+        "TAPE_FILE.COMPRESSED_SIZE AS COMPRESSED_SIZE,"
+        "TAPE_FILE.COPY_NB AS COPY_NB,"
+        "TAPE_FILE.CREATION_TIME AS TAPE_FILE_CREATION_TIME "
+      "FROM "
+        "ARCHIVE_FILE "
+      "LEFT OUTER JOIN TAPE_FILE ON "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID = TAPE_FILE.ARCHIVE_FILE_ID "
+      "WHERE "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID "
+      "FOR UPDATE";
+    std::unique_ptr<DbStmt> selectStmt(m_conn->createStmt(selectSql));
+    selectStmt->bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
+    std::unique_ptr<DbRset> selectRset(selectStmt->executeQuery());
+    while(selectRset->next()) {
+      if(NULL == archiveFile.get()) {
+        archiveFile.reset(new common::dataStructures::ArchiveFile);
+
+        archiveFile->archiveFileID = selectRset->columnUint64("ARCHIVE_FILE_ID");
+        archiveFile->diskInstance = selectRset->columnText("DISK_INSTANCE");
+        archiveFile->diskFileId = selectRset->columnText("DISK_FILE_ID");
+        archiveFile->diskFileInfo.path = selectRset->columnText("DISK_FILE_PATH");
+        archiveFile->diskFileInfo.owner = selectRset->columnText("DISK_FILE_USER");
+        archiveFile->diskFileInfo.group = selectRset->columnText("DISK_FILE_GROUP");
+        archiveFile->diskFileInfo.recoveryBlob = selectRset->columnText("DISK_FILE_RECOVERY_BLOB");
+        archiveFile->fileSize = selectRset->columnUint64("FILE_SIZE");
+        archiveFile->checksumType = selectRset->columnText("CHECKSUM_TYPE");
+        archiveFile->checksumValue = selectRset->columnText("CHECKSUM_VALUE");
+        archiveFile->storageClass = selectRset->columnText("STORAGE_CLASS_NAME");
+        archiveFile->creationTime = selectRset->columnUint64("ARCHIVE_FILE_CREATION_TIME");
+        archiveFile->reconciliationTime = selectRset->columnUint64("RECONCILIATION_TIME");
+      }
+
+      // If there is a tape file
+      if(!selectRset->columnIsNull("VID")) {
+        // Add the tape file to the archive file's in-memory structure
+        common::dataStructures::TapeFile tapeFile;
+        tapeFile.vid = selectRset->columnText("VID");
+        tapeFile.fSeq = selectRset->columnUint64("FSEQ");
+        tapeFile.blockId = selectRset->columnUint64("BLOCK_ID");
+        tapeFile.compressedSize = selectRset->columnUint64("COMPRESSED_SIZE");
+        tapeFile.copyNb = selectRset->columnUint64("COPY_NB");
+        tapeFile.creationTime = selectRset->columnUint64("TAPE_FILE_CREATION_TIME");
+        archiveFile->tapeFiles[selectRset->columnUint64("COPY_NB")] = tapeFile;
+      }
+    }
+
+    if(NULL == archiveFile.get()) {
+      UserError ue;
+      ue.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " because it does not exist";
+      throw ue;
+    }
+
+    {
+      const char *const sql = "DELETE FROM TAPE_FILE WHERE ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
+      std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
+      stmt->bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
+      stmt->executeNonQuery();
+    }
+
+    {
+      const char *const sql = "DELETE FROM ARCHIVE_FILE WHERE ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
+      std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
+      stmt->bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
+      stmt->executeNonQuery();
+    }
+
+    m_conn->commit();
+
+    return *archiveFile;
+  } catch(UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
 }
 
 //------------------------------------------------------------------------------
 // getNextArchiveFileId
 //------------------------------------------------------------------------------
 uint64_t OracleCatalogue::getNextArchiveFileId() {
-  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
+  try {
+    const char *const sql =
+      "SELECT "
+        "ARCHIVE_FILE_ID_SEQ.NEXTVAL AS ARCHIVE_FILE_ID "
+      "FROM "
+        "DUAL";
+
+    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
+    std::unique_ptr<DbRset> rset(stmt->executeQuery());
+    if (!rset->next()) {
+      throw exception::Exception(std::string("Result set is unexpectedly empty"));
+    }
+
+    return rset->columnUint64("ARCHIVE_FILE_ID");
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
 }
 
 //------------------------------------------------------------------------------
@@ -95,7 +206,7 @@ common::dataStructures::Tape OracleCatalogue::selectTapeForUpdate(const std::str
         "TAPE "
       "WHERE "
         "VID = :VID "
-      "FOR UPDATE;";
+      "FOR UPDATE";
 
     std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
     stmt->bindString(":VID", vid);
diff --git a/catalogue/create_oracle_catalogue_schema_header.sql b/catalogue/create_oracle_catalogue_schema_header.sql
index e69de29bb2..30f920df6c 100644
--- a/catalogue/create_oracle_catalogue_schema_header.sql
+++ b/catalogue/create_oracle_catalogue_schema_header.sql
@@ -0,0 +1,8 @@
+CREATE SEQUENCE ARCHIVE_FILE_ID_SEQ
+  INCREMENT BY 1
+  START WITH 0
+  NOMAXVALUE
+  MINVALUE 0
+  NOCYCLE
+  CACHE 20
+  NOORDER;
diff --git a/catalogue/drop_oracle_catalogue_schema.sql b/catalogue/drop_oracle_catalogue_schema.sql
index 6d95422535..581e2b436a 100644
--- a/catalogue/drop_oracle_catalogue_schema.sql
+++ b/catalogue/drop_oracle_catalogue_schema.sql
@@ -10,4 +10,5 @@ DROP TABLE STORAGE_CLASS;
 DROP TABLE TAPE_POOL;
 DROP TABLE LOGICAL_LIBRARY;
 DROP TABLE MOUNT_POLICY;
+DROP SEQUENCE ARCHIVE_FILE_ID_SEQ;
 QUIT
-- 
GitLab