From 725551950ed6b6541ace880203bc53e21c4b3021 Mon Sep 17 00:00:00 2001 From: lganzzzo Date: Mon, 25 Oct 2021 02:33:58 +0300 Subject: [PATCH] Fix connection invalidator. --- src/oatpp-postgresql/Connection.cpp | 8 ++++++++ src/oatpp-postgresql/Connection.hpp | 5 +++++ src/oatpp-postgresql/ConnectionProvider.cpp | 8 ++++---- src/oatpp-postgresql/ConnectionProvider.hpp | 12 +++++------ src/oatpp-postgresql/Executor.cpp | 22 ++++++++++++++++++--- src/oatpp-postgresql/Executor.hpp | 15 ++++++++++++-- test/oatpp-postgresql/types/ArrayTest.cpp | 7 +++++-- 7 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/oatpp-postgresql/Connection.cpp b/src/oatpp-postgresql/Connection.cpp index abd51b8..ee92f7d 100644 --- a/src/oatpp-postgresql/Connection.cpp +++ b/src/oatpp-postgresql/Connection.cpp @@ -26,6 +26,14 @@ namespace oatpp { namespace postgresql { +void Connection::setInvalidator(const std::shared_ptr>& invalidator) { + m_invalidator = invalidator; +} + +std::shared_ptr> Connection::getInvalidator() { + return m_invalidator; +} + ConnectionImpl::ConnectionImpl(PGconn* connection) : m_connection(connection) {} diff --git a/src/oatpp-postgresql/Connection.hpp b/src/oatpp-postgresql/Connection.hpp index bfce242..85372de 100644 --- a/src/oatpp-postgresql/Connection.hpp +++ b/src/oatpp-postgresql/Connection.hpp @@ -37,6 +37,8 @@ namespace oatpp { namespace postgresql { * Implementation of &id:oatpp::orm::Connection; for PostgreSQL. */ class Connection : public orm::Connection { +private: + std::shared_ptr> m_invalidator; public: /** @@ -48,6 +50,9 @@ public: virtual void setPrepared(const oatpp::String& statementName) = 0; virtual bool isPrepared(const oatpp::String& statementName) = 0; + void setInvalidator(const std::shared_ptr>& invalidator); + std::shared_ptr> getInvalidator(); + }; class ConnectionImpl : public Connection { diff --git a/src/oatpp-postgresql/ConnectionProvider.cpp b/src/oatpp-postgresql/ConnectionProvider.cpp index 9599a28..a26f4cc 100644 --- a/src/oatpp-postgresql/ConnectionProvider.cpp +++ b/src/oatpp-postgresql/ConnectionProvider.cpp @@ -26,7 +26,7 @@ namespace oatpp { namespace postgresql { -void ConnectionProvider::ConnectionInvalidator::invalidate(const std::shared_ptr &resource) { +void ConnectionProvider::ConnectionInvalidator::invalidate(const std::shared_ptr &resource) { (void) resource; //Do nothing. } @@ -36,7 +36,7 @@ ConnectionProvider::ConnectionProvider(const oatpp::String& connectionString) , m_connectionString(connectionString) {} -provider::ResourceHandle ConnectionProvider::get() { +provider::ResourceHandle ConnectionProvider::get() { auto handle = PQconnectdb(m_connectionString->c_str()); @@ -47,11 +47,11 @@ provider::ResourceHandle ConnectionProvider::get() { "Error. Can't connect. " + errMsg); } - return provider::ResourceHandle(std::make_shared(handle), m_invalidator); + return provider::ResourceHandle(std::make_shared(handle), m_invalidator); } -async::CoroutineStarterForResult&> ConnectionProvider::getAsync() { +async::CoroutineStarterForResult&> ConnectionProvider::getAsync() { throw std::runtime_error("[oatpp::postgresql::ConnectionProvider::getAsync()]: Error. Not implemented!"); } diff --git a/src/oatpp-postgresql/ConnectionProvider.hpp b/src/oatpp-postgresql/ConnectionProvider.hpp index d8b25f5..5cf9371 100644 --- a/src/oatpp-postgresql/ConnectionProvider.hpp +++ b/src/oatpp-postgresql/ConnectionProvider.hpp @@ -35,12 +35,12 @@ namespace oatpp { namespace postgresql { /** * Connection provider. */ -class ConnectionProvider : public provider::Provider { +class ConnectionProvider : public provider::Provider { private: - class ConnectionInvalidator : public provider::Invalidator { + class ConnectionInvalidator : public provider::Invalidator { public: - void invalidate(const std::shared_ptr& resource) override; + void invalidate(const std::shared_ptr& resource) override; }; private: @@ -58,13 +58,13 @@ public: * Get Connection. * @return - resource. */ - provider::ResourceHandle get() override; + provider::ResourceHandle get() override; /** * Get Connection in Async manner. * @return - &id:oatpp::async::CoroutineStarterForResult; of `Connection`. */ - async::CoroutineStarterForResult&> getAsync() override; + async::CoroutineStarterForResult&> getAsync() override; /** * Stop provider and free associated resources. @@ -79,7 +79,7 @@ public: * - &id:oatpp::postgresql::ConnectionAcquisitionProxy;. */ typedef oatpp::provider::Pool< - provider::Provider, + provider::Provider, Connection, ConnectionAcquisitionProxy > ConnectionPool; diff --git a/src/oatpp-postgresql/Executor.cpp b/src/oatpp-postgresql/Executor.cpp index 70a7706..642f09a 100644 --- a/src/oatpp-postgresql/Executor.cpp +++ b/src/oatpp-postgresql/Executor.cpp @@ -54,6 +54,16 @@ namespace { } +void Executor::ConnectionInvalidator::invalidate(const std::shared_ptr& connection) { + auto c = std::static_pointer_cast(connection); + auto invalidator = c->getInvalidator(); + if(!invalidator) { + throw std::runtime_error("[oatpp::postgresql::Executor::ConnectionInvalidator::invalidate()]: Error. " + "Connection invalidator was NOT set."); + } + invalidator->invalidate(c); +} + Executor::QueryParams::QueryParams(const StringTemplate& queryTemplate, const std::unordered_map& params, const mapping::Serializer& serializer, @@ -123,8 +133,9 @@ Executor::QueryParams::QueryParams(const StringTemplate& queryTemplate, } -Executor::Executor(const std::shared_ptr>& connectionProvider) - : m_connectionProvider(connectionProvider) +Executor::Executor(const std::shared_ptr>& connectionProvider) + : m_connectionInvalidator(std::make_shared()) + , m_connectionProvider(connectionProvider) , m_resultMapper(std::make_shared()) { m_defaultTypeResolver->addKnownClasses({ @@ -288,7 +299,12 @@ data::share::StringTemplate Executor::parseQueryTemplate(const oatpp::String& na provider::ResourceHandle Executor::getConnection() { auto connection = m_connectionProvider->get(); if(connection) { - return connection; + /* set correct invalidator before cast */ + connection.object->setInvalidator(connection.invalidator); + return provider::ResourceHandle( + connection.object, + m_connectionInvalidator + ); } throw std::runtime_error("[oatpp::postgresql::Executor::getConnection()]: Error. Can't connect."); } diff --git a/src/oatpp-postgresql/Executor.hpp b/src/oatpp-postgresql/Executor.hpp index 7ae567c..b650d75 100644 --- a/src/oatpp-postgresql/Executor.hpp +++ b/src/oatpp-postgresql/Executor.hpp @@ -43,6 +43,16 @@ namespace oatpp { namespace postgresql { * Implementation of &id:oatpp::orm::Executor;. for PostgreSQL. */ class Executor : public orm::Executor { +private: + + /* + * We need this invalidator to correlate abstract orm::Connection to its correct invalidator. + */ + class ConnectionInvalidator : public provider::Invalidator { + public: + void invalidate(const std::shared_ptr& connection) override; + }; + private: struct QueryParameter { @@ -109,12 +119,13 @@ private: const provider::ResourceHandle& connection); private: - std::shared_ptr> m_connectionProvider; + std::shared_ptr m_connectionInvalidator; + std::shared_ptr> m_connectionProvider; std::shared_ptr m_resultMapper; mapping::Serializer m_serializer; public: - Executor(const std::shared_ptr>& connectionProvider); + Executor(const std::shared_ptr>& connectionProvider); std::shared_ptr createTypeResolver() override; diff --git a/test/oatpp-postgresql/types/ArrayTest.cpp b/test/oatpp-postgresql/types/ArrayTest.cpp index 48d4987..d95ee6b 100644 --- a/test/oatpp-postgresql/types/ArrayTest.cpp +++ b/test/oatpp-postgresql/types/ArrayTest.cpp @@ -112,7 +112,10 @@ void ArrayTest::onRun() { OATPP_LOGI(TAG, "DB-URL='%s'", TEST_DB_URL); auto connectionProvider = std::make_shared(TEST_DB_URL); - auto executor = std::make_shared(connectionProvider); + auto connectionPool = oatpp::postgresql::ConnectionPool::createShared(connectionProvider, + 10, + std::chrono::seconds(3)); + auto executor = std::make_shared(connectionPool); auto client = MyClient(executor); @@ -483,7 +486,7 @@ void ArrayTest::onRun() { } - + connectionPool->stop(); }