From 27512e1fe271ec8efdb120a25be1a0333c727751 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 19 Nov 2015 21:32:03 +0000 Subject: Add a database connection pool. --- libdbpp/Jamfile.jam | 2 ++ libdbpp/connectionPool.cpp | 27 +++++++++++++++++++++ libdbpp/connectionPool.h | 32 +++++++++++++++++++++++++ libdbpp/unittests/Jamfile.jam | 13 ++++++++++ libdbpp/unittests/testConnectionPool.cpp | 41 ++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+) create mode 100644 libdbpp/connectionPool.cpp create mode 100644 libdbpp/connectionPool.h create mode 100644 libdbpp/unittests/testConnectionPool.cpp diff --git a/libdbpp/Jamfile.jam b/libdbpp/Jamfile.jam index 1e09e94..ff52020 100644 --- a/libdbpp/Jamfile.jam +++ b/libdbpp/Jamfile.jam @@ -8,6 +8,7 @@ alias glibmm : : : : lib boost_date_time : : boost_date_time ; lib boost_filesystem ; lib boost_system ; +lib boost_thread ; lib adhocutil : : : : /usr/include/adhocutil ; lib boost_utf : : boost_unit_test_framework ; @@ -16,6 +17,7 @@ lib dbppcore : glibmm adhocutil boost_system + boost_thread boost_filesystem -fvisibility=hidden release:-flto diff --git a/libdbpp/connectionPool.cpp b/libdbpp/connectionPool.cpp new file mode 100644 index 0000000..24a78fa --- /dev/null +++ b/libdbpp/connectionPool.cpp @@ -0,0 +1,27 @@ +#include "connectionPool.h" +#include + +template class AdHoc::ResourcePool; +template class AdHoc::ResourceHandle; + +namespace DB { + ConnectionPool::ConnectionPool(unsigned int m, unsigned int k, const std::string & t, const std::string & cs) : + ResourcePool(m, k), + factory(ConnectionFactory::get(t)), + connectionString(cs) + { + } + + Connection * + ConnectionPool::createResource() const + { + return factory->create(connectionString); + } + + void + ConnectionPool::testResource(const Connection * c) const + { + c->ping(); + } +} + diff --git a/libdbpp/connectionPool.h b/libdbpp/connectionPool.h new file mode 100644 index 0000000..c2ce950 --- /dev/null +++ b/libdbpp/connectionPool.h @@ -0,0 +1,32 @@ +#ifndef DB_CONNECTIONPOOL_H +#define DB_CONNECTIONPOOL_H + +#include +#include +#include "connection.h" + +namespace DB { + /// Specialisation of AdHoc::ResourcePool for database connections. + class DLL_PUBLIC ConnectionPool : public AdHoc::ResourcePool { + public: + /// Create a new connection pool. + /// @param max Maximum number of concurrent database connections. + /// @param keep Number of connections to keep open after use. + /// @param type Database connection factory name. + /// @param connectionString Connection string to pass to the connection factory. + ConnectionPool(unsigned int max, unsigned int keep, const std::string & type, const std::string & connectionString); + + protected: + /// Create a new connection. + Connection * createResource() const override; + /// Ping a connection. + void testResource(const Connection *) const override; + + private: + const ConnectionFactory * factory; + const std::string connectionString; + }; +} + +#endif + diff --git a/libdbpp/unittests/Jamfile.jam b/libdbpp/unittests/Jamfile.jam index b7b2170..aa6c195 100644 --- a/libdbpp/unittests/Jamfile.jam +++ b/libdbpp/unittests/Jamfile.jam @@ -23,6 +23,19 @@ run testConnection ; +run + testConnectionPool.cpp + : : : + ROOT=\"$(me)\" + BOOST_TEST_DYN_LINK + ..//dbppcore + ..//adhocutil + ../../libpqpp//dbpp-postgresql + boost_utf + : + testConnectionPool + ; + run testUtils.cpp : : : diff --git a/libdbpp/unittests/testConnectionPool.cpp b/libdbpp/unittests/testConnectionPool.cpp new file mode 100644 index 0000000..ebe22d1 --- /dev/null +++ b/libdbpp/unittests/testConnectionPool.cpp @@ -0,0 +1,41 @@ +#define BOOST_TEST_MODULE DbConnectionPool +#include + +#include +#include +#include + +class MockPool : public PQ::Mock, public DB::ConnectionPool { + public: + MockPool() : + PQ::Mock("user=postgres dbname=postgres", "pqmock", { }), + DB::ConnectionPool(4, 2, "postgresql", stringbf("user=postgres dbname=%s", databaseName())) + { + } +}; + +BOOST_AUTO_TEST_CASE( basic ) +{ + MockPool pool; + DB::Connection * cr; + { + auto c = pool.get(); + c->beginTx(); + c->commitTx(); + cr = c.get(); + } + { + auto c = pool.get(); + BOOST_REQUIRE_EQUAL(cr, c.get()); + } + { + auto c1 = pool.get(); + auto c2 = pool.get(); + auto c3 = pool.get(); + auto c4 = pool.get(); + BOOST_REQUIRE_EQUAL(4, pool.inUseCount()); + } + BOOST_REQUIRE_EQUAL(0, pool.inUseCount()); + BOOST_REQUIRE_EQUAL(2, pool.availableCount()); +} + -- cgit v1.2.3