Commit b7c04ca4 authored by Steven Murray's avatar Steven Murray
Browse files

Added OcciRset

parent 4b33bd2f
......@@ -27,6 +27,7 @@ set (CATALOGUE_LIB_SRC_FILES
DummyCatalogue.cpp
OcciConn.cpp
OcciEnv.cpp
OcciRset.cpp
OcciStmt.cpp
Sqlite.cpp
SqliteCatalogue.cpp
......@@ -43,6 +44,7 @@ target_link_libraries (ctacatalogue
${SQLITE_LIBRARIES})
set (CATALOGUE_UNIT_TESTS_LIB_SRC_FILES
OcciConnTest.cpp
OcciEnvTest.cpp
SqliteCatalogueTest.cpp
SqliteStmtTest.cpp)
......
......@@ -89,7 +89,7 @@ namespace {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::DbLogin::DbLogin(
cta::catalogue::DbLogin::DbLogin(
const std::string &username,
const std::string &password,
const std::string &database):
......@@ -101,7 +101,8 @@ cta::DbLogin::DbLogin(
//------------------------------------------------------------------------------
// readFromFile
//------------------------------------------------------------------------------
cta::DbLogin cta::DbLogin::readFromFile(const std::string &filename) {
cta::catalogue::DbLogin cta::catalogue::DbLogin::readFromFile(
const std::string &filename) {
const std::string fileFormat = "username/password@database";
const std::list<std::string> lines = readNonEmptyLines(filename);
......
......@@ -21,6 +21,7 @@
#include <string>
namespace cta {
namespace catalogue {
/**
* A set of database login details.
......@@ -67,4 +68,5 @@ struct DbLogin {
}; // class DbLogin
} // namespace catalogue
} // namespace cta
......@@ -17,17 +17,23 @@
*/
#include "catalogue/OcciConn.hpp"
#include "catalogue/OcciEnv.hpp"
#include "catalogue/OcciStmt.hpp"
#include "common/exception/Exception.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::catalogue::OcciConn::OcciConn(oracle::occi::Environment *const env,
const DbLogin &dbLogin):
cta::catalogue::OcciConn::OcciConn(OcciEnv &env,
oracle::occi::Connection *const conn):
m_env(env),
m_conn(m_env->createConnection(
dbLogin.username,
dbLogin.password,
dbLogin.database)) {
m_conn(conn) {
if(NULL == conn) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << "failed"
": The OCCI connection is a NULL pointer";
throw ex;
}
}
//------------------------------------------------------------------------------
......@@ -72,5 +78,13 @@ oracle::occi::Connection *cta::catalogue::OcciConn::operator->() const {
//------------------------------------------------------------------------------
cta::catalogue::OcciStmt *cta::catalogue::OcciConn::createStmt(
const std::string &sql) {
return NULL;
oracle::occi::Statement *const stmt = m_conn->createStatement(sql.c_str());
if(NULL == stmt) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed"
": oracle::occi::createStatement() return a NULL pointer";
throw ex;
}
return new OcciStmt(sql, *this, stmt);
}
......@@ -18,8 +18,6 @@
#pragma once
#include "catalogue/DbLogin.hpp"
#include <occi.h>
#include <mutex>
#include <string>
......@@ -27,6 +25,12 @@
namespace cta {
namespace catalogue {
/**
* Forward declaraion to avoid a circular dependency beween OcciConn and
* OcciEnv.
*/
class OcciEnv;
/**
* Forward declaraion to avoid a circular dependency beween OcciConn and
* OcciStmt.
......@@ -42,11 +46,13 @@ public:
/**
* Constructor.
*
* This method will throw an exception if the OCCI connection is a NULL
* pointer.
*
* @param env The OCCI environment.
* @param dbLogin The database connetion details.
* @param conn The OCCI connection.
*/
OcciConn(oracle::occi::Environment *const env,
const DbLogin &dbLogin);
OcciConn(OcciEnv &env, oracle::occi::Connection *const conn);
/**
* Destructor.
......@@ -85,14 +91,14 @@ public:
private:
/**
* Mutex used to serialize access to the database connection.
* Mutex used to serialize access to this object.
*/
std::mutex m_mutex;
/**
* The OCCI environment.
*/
oracle::occi::Environment *m_env;
OcciEnv &m_env;
/**
* The OCCI connection.
......
......@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/OcciEnv.hpp"
#include "catalogue/OcciConn.hpp"
#include "common/exception/Exception.hpp"
......@@ -34,15 +35,15 @@ protected:
}
};
TEST_F(cta_catalogue_OcciConnTest, constructor) {
TEST_F(cta_catalogue_OcciConnTest, constructor_null_connection) {
using namespace cta;
using namespace cta::catalogue;
// WARNING - The database whose connection details are specified in the
// following database configuration file will be destroyed
const std::string testDbConfigFile = "cta_catalogue_test_db.conf";
const DbLogin dbLogin = DbLogin::readFromFile(testDbConfigFile);
OcciEnv env;
oracle::occi::Connection *const underlyingOcciConn = NULL;
std::unique_ptr<OcciConn> conn;
ASSERT_THROW(conn.reset(new OcciConn(env, underlyingOcciConn)),
exception::Exception);
}
} // namespace unitTests
......@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/DbLogin.hpp"
#include "catalogue/OcciConn.hpp"
#include "catalogue/OcciEnv.hpp"
#include "common/exception/Exception.hpp"
......@@ -28,7 +30,7 @@ cta::catalogue::OcciEnv::OcciEnv() {
if(NULL == m_env) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed"
": createEnvironment() returned a NULL pointer";
": oracle::occi::createEnvironment() returned a NULL pointer";
throw ex;
}
}
......@@ -55,3 +57,21 @@ oracle::occi::Environment *cta::catalogue::OcciEnv::get() const {
oracle::occi::Environment *cta::catalogue::OcciEnv::operator->() const {
return get();
}
//------------------------------------------------------------------------------
// creatConn
//------------------------------------------------------------------------------
cta::catalogue::OcciConn *cta::catalogue::OcciEnv::createConn(
const DbLogin &dbLogin) {
oracle::occi::Connection *const conn = m_env->createConnection(
dbLogin.username,
dbLogin.password,
dbLogin.database);
if(NULL == conn) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed"
": oracle::occi::createConnection() returned a NULL pointer";
throw ex;
}
return new OcciConn(*this, conn);
}
......@@ -23,6 +23,9 @@
namespace cta {
namespace catalogue {
class DbLogin;
class OcciConn;
/**
* A convenience wrapper around an OCCI environment.
*/
......@@ -57,6 +60,14 @@ public:
*/
oracle::occi::Environment *operator->() const;
/**
* Creates an OCCI connection.
*
* @param dbLogin The details of the database connection.
* @return The newly created OCCI connection.
*/
OcciConn *createConn(const DbLogin &dbLogin);
private:
/**
......
/*
* 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/OcciRset.hpp"
#include "catalogue/OcciStmt.hpp"
#include "common/exception/Exception.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta::catalogue::OcciRset::OcciRset(OcciStmt &stmt,
oracle::occi::ResultSet *const rset):
m_stmt(stmt),
m_rset(rset) {
if(NULL == rset) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed"
": The result set is a NULL pointer";
throw ex;
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta::catalogue::OcciRset::~OcciRset() throw() {
try {
close(); // Idempotenet close()
} catch(...) {
// Destructor does not throw
}
}
//------------------------------------------------------------------------------
// close
//------------------------------------------------------------------------------
void cta::catalogue::OcciRset::close() {
std::lock_guard<std::mutex> lock(m_mutex);
if(NULL != m_rset) {
m_stmt->closeResultSet(m_rset);
m_rset = NULL;
}
}
//------------------------------------------------------------------------------
// get
//------------------------------------------------------------------------------
oracle::occi::ResultSet *cta::catalogue::OcciRset::get() const {
return m_rset;
}
//------------------------------------------------------------------------------
// operator->
//------------------------------------------------------------------------------
oracle::occi::ResultSet *cta::catalogue::OcciRset::operator->() const {
return get();
}
/*
* 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 <mutex>
#include <occi.h>
namespace cta {
namespace catalogue {
/**
* Forward declaraion to avoid a circular dependency beween OcciRset and
* OcciStmt.
*/
class OcciStmt;
/**
* A convenience wrapper around an OCCI result set.
*/
class OcciRset {
public:
/**
* Constructor.
*
* This constructor will throw an exception if the result set is a NULL
* pointer.
*
* @param stmt The OCCI statement.
* @param rset The OCCI result set.
*/
OcciRset(OcciStmt &stmt, oracle::occi::ResultSet *const rset);
/**
* Destructor.
*/
~OcciRset() throw();
/**
* Idempotent close() method. The destructor calls this method.
*/
void close();
/**
* Returns the underlying OCCI result set.
*
* This method will always return a valid pointer.
*
* @return The underlying OCCI result set.
*/
oracle::occi::ResultSet *get() const;
/**
* An alias for the get() method.
*
* @return The underlying OCCI result set.
*/
oracle::occi::ResultSet *operator->() const;
private:
/**
* Mutex used to serialize access to this object.
*/
std::mutex m_mutex;
/**
* The OCCI statement.
*/
OcciStmt &m_stmt;
/**
* The OCCI result set.
*/
oracle::occi::ResultSet *m_rset;
}; // class OcciRset
} // namespace catalogue
} // namespace cta
......@@ -28,6 +28,12 @@ cta::catalogue::OcciStmt::OcciStmt(const std::string &sql, OcciConn &conn,
m_sql(sql),
m_conn(conn),
m_stmt(stmt) {
if(NULL == stmt) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed"
": OCCI statment is a NULL pointer";
throw ex;
}
}
//------------------------------------------------------------------------------
......@@ -60,6 +66,20 @@ const std::string &cta::catalogue::OcciStmt::getSql() const {
return m_sql;
}
//------------------------------------------------------------------------------
// get
//------------------------------------------------------------------------------
oracle::occi::Statement *cta::catalogue::OcciStmt::get() const {
return m_stmt;
}
//------------------------------------------------------------------------------
// operator->
//------------------------------------------------------------------------------
oracle::occi::Statement *cta::catalogue::OcciStmt::operator->() const {
return get();
}
//------------------------------------------------------------------------------
// bind
//------------------------------------------------------------------------------
......
......@@ -42,6 +42,9 @@ public:
/**
* Constructor.
*
* This constructor will throw an exception if the OCCI statement is a NULL
* pointer.
*
* @param sql The SQL statement.
* @param conn The database connection.
......@@ -67,6 +70,20 @@ public:
*/
const std::string &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;
/**
* Binds an SQL parameter.
*
......@@ -86,7 +103,7 @@ public:
private:
/**
* Mutex used to serialize access to the prepared statement.
* Mutex used to serialize access to this object.
*/
std::mutex m_mutex;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment