Skip to content
Snippets Groups Projects
Commit 3b560ad1 authored by Steven Murray's avatar Steven Murray
Browse files

Added rdbms::DbConnPool

parent 589a4442
No related branches found
No related tags found
No related merge requests found
......@@ -25,11 +25,14 @@ set (RDBMS_LIB_SRC_FILES
ColumnNameToIdx.cpp
ColumnNameToIdxAndType.cpp
DbConn.cpp
DbConnFactory.cpp
DbConnPool.cpp
DbLogin.cpp
DbRset.cpp
DbStmt.cpp
NullDbValue.cpp
OcciConn.cpp
OcciConnFactory.cpp
OcciEnv.cpp
OcciEnvSingleton.cpp
OcciRset.cpp
......@@ -37,6 +40,7 @@ set (RDBMS_LIB_SRC_FILES
ParamNameToIdx.cpp
Sqlite.cpp
SqliteConn.cpp
SqliteConnFactory.cpp
SqliteRset.cpp
SqliteStmt.cpp)
......
/*
* 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 "DbConnFactory.hpp"
namespace cta {
namespace rdbms {
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
DbConnFactory::~DbConnFactory() throw() {
}
} // namespace rdbms
} // namespace cta
/*
* 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 "DbConn.hpp"
namespace cta {
namespace rdbms {
/**
* Abstract class that specifies the interface of a factory of DbConn objects.
*/
class DbConnFactory {
public:
/**
* Destructor.
*/
virtual ~DbConnFactory() throw() = 0;
/**
* Returns a newly created database connection.
*
* @return A newly created database connection.
*/
virtual DbConn *create() = 0;
}; // class DbConnFactory
} // namespace rdbms
} // namespace cta
/*
* 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 "common/exception/Exception.hpp"
#include "DbConnPool.hpp"
#include "OcciConnFactory.hpp"
#include "SqliteConnFactory.hpp"
#include <memory>
namespace cta {
namespace rdbms {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
DbConnPool::DbConnPool(const DbLogin &dbLogin, const uint64_t nbDbConns):
m_dbLogin(dbLogin),
m_nbDbConns(nbDbConns) {
try {
createDbConnFactory(dbLogin);
createDbConns(m_nbDbConns);
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// createDbConnFactory
//------------------------------------------------------------------------------
void DbConnPool::createDbConnFactory(const DbLogin &dbLogin) {
try {
switch(dbLogin.dbType) {
case rdbms::DbLogin::DBTYPE_IN_MEMORY:
m_dbConnFactory.reset(new SqliteConnFactory(":memory:"));
break;
case rdbms::DbLogin::DBTYPE_ORACLE:
m_dbConnFactory.reset(new OcciConnFactory(dbLogin.username, dbLogin.password, dbLogin.database));
break;
case rdbms::DbLogin::DBTYPE_SQLITE:
m_dbConnFactory.reset(new SqliteConnFactory(dbLogin.database));
break;
default:
{
exception::Exception ex;
ex.getMessage() << "Unknown database type: value=" << dbLogin.dbType;
throw ex;
}
}
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// createDbConns
//------------------------------------------------------------------------------
void DbConnPool::createDbConns(const uint64_t nbDbConns) {
try {
for(uint64_t i = 0; i < nbDbConns; i++) {
m_dbConns.push_back(m_dbConnFactory->create());
}
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
DbConnPool::~DbConnPool() throw() {
for(auto &dbConn: m_dbConns) {
delete dbConn;
}
}
//------------------------------------------------------------------------------
// getDbConn
//------------------------------------------------------------------------------
DbConn *DbConnPool::getDbConn() {
std::unique_lock<std::mutex> lock(m_dbConnsMutex);
while(m_dbConns.size() == 0) {
m_dbConnsCv.wait(lock);
}
DbConn *const dbConn = m_dbConns.front();
m_dbConns.pop_front();
return dbConn;
}
//------------------------------------------------------------------------------
// returnDbConn
//------------------------------------------------------------------------------
void DbConnPool::returnDbConn(DbConn *const dbConn) {
std::unique_lock<std::mutex> lock(m_dbConnsMutex);
m_dbConns.push_back(dbConn);
m_dbConnsCv.notify_one();
}
} // namespace rdbms
} // namespace cta
/*
* 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 "DbConn.hpp"
#include "DbConnFactory.hpp"
#include "DbLogin.hpp"
#include <condition_variable>
#include <memory>
#include <mutex>
namespace cta {
namespace rdbms {
/**
* A pool of database connections.
*/
class DbConnPool {
public:
/**
* Constructor.
*
* @param dbLogin The database login details to be used to create new
* connections.
* @param nbDbConns The number of database connections within the pool.
*/
DbConnPool(const DbLogin &dbLogin, const uint64_t nbDbConns);
/**
* Destructor.
*/
~DbConnPool() throw();
/**
* Takes a connection from the pool.
*
* Please note that this method will block if the pool is empty. In such a
* situation this method will unblock when a connection is returned to the
* pool.
*
* @return A connection from the pool.
*/
DbConn *getDbConn();
/**
* Returns the specified database connection to the pool.
*
* @param dbConn The connection to be returned to the pool.
*/
void returnDbConn(DbConn *const dbConn);
private:
/**
* The database login details to be used to create new connections.
*/
DbLogin m_dbLogin;
/**
* The database connection factory for the pool.
*/
std::unique_ptr<DbConnFactory> m_dbConnFactory;
/**
* The number of database connections within the pool.
*/
uint64_t m_nbDbConns;
/**
* Mutex used to serialize access to the database connections within the pool.
*/
std::mutex m_dbConnsMutex;
/**
* Condition variable used by threads returning connections to the pool to
* notify threads waiting for connections.
*/
std::condition_variable m_dbConnsCv;
/**
* The database connections within the pool.
*/
std::list<DbConn *> m_dbConns;
/**
* Creates the database connection factory for the pool based on the specified
* login details.
*
* @param dbLogin The database login details to be used to create new
* connections.
*/
void createDbConnFactory(const DbLogin &dbLogin);
/**
* Creates the specified number of database connections with the pool.
*
* @param nbDbConns The number of database connections to be created.
*/
void createDbConns(const uint64_t nbDbConns);
}; // class DbConnPool
} // namespace rdbms
} // namespace cta
/*
* 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 "common/exception/Exception.hpp"
#include "OcciConn.hpp"
#include "OcciConnFactory.hpp"
#include "OcciEnvSingleton.hpp"
namespace cta {
namespace rdbms {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
OcciConnFactory::OcciConnFactory(
const std::string &username,
const std::string &password,
const std::string &database):
m_username(username),
m_password(password),
m_database(database) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
OcciConnFactory::~OcciConnFactory() throw() {
}
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
DbConn *OcciConnFactory::create() {
try {
return OcciEnvSingleton::instance().createConn(m_username, m_password, m_database);
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
} // namespace rdbms
} // namespace cta
/*
* 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 "DbConnFactory.hpp"
namespace cta {
namespace rdbms {
/**
* A concrete factory of DbConn objects.
*/
class OcciConnFactory: public DbConnFactory {
public:
/**
* Constructor.
*
* @param username The database username.
* @param password The database password.
* @param database The database name.
*/
OcciConnFactory(
const std::string &username,
const std::string &password,
const std::string &database);
/**
* Destructor.
*/
virtual ~OcciConnFactory() throw();
/**
* Returns a newly created database connection.
*
* @return A newly created database connection.
*/
virtual DbConn *create();
private:
/**
* The database username.
*/
std::string m_username;
/**
* The database password.
*/
std::string m_password;
/**
* The database name.
*/
std::string m_database;
}; // class OcciConnFactory
} // namespace rdbms
} // namespace cta
/*
* 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 "common/exception/Exception.hpp"
#include "SqliteConn.hpp"
#include "SqliteConnFactory.hpp"
namespace cta {
namespace rdbms {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
SqliteConnFactory::SqliteConnFactory(const std::string &filename):
m_filename(filename) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
SqliteConnFactory::~SqliteConnFactory() throw() {
}
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
DbConn *SqliteConnFactory::create() {
try {
return new SqliteConn(m_filename);
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
} // namespace rdbms
} // namespace cta
/*
* 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 "DbConnFactory.hpp"
namespace cta {
namespace rdbms {
/**
* A concrete factory of DbConn objects.
*/
class SqliteConnFactory: public DbConnFactory {
public:
/**
* Constructor.
*
* @param filename The filename to be passed to the sqlite3_open() function.
*/
SqliteConnFactory(const std::string &filename);
/**
* Destructor.
*/
virtual ~SqliteConnFactory() throw();
/**
* Returns a newly created database connection.
*
* @return A newly created database connection.
*/
virtual DbConn *create();
private:
/**
* The filename to be passed to the sqlite3_open() function.
*/
std::string m_filename;
}; // class SqliteConnFactory
} // namespace rdbms
} // namespace cta
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment