Fix connection invalidator.

This commit is contained in:
lganzzzo 2021-10-25 02:33:58 +03:00
parent 3071ed18bc
commit 725551950e
7 changed files with 60 additions and 17 deletions

View File

@ -26,6 +26,14 @@
namespace oatpp { namespace postgresql {
void Connection::setInvalidator(const std::shared_ptr<provider::Invalidator<Connection>>& invalidator) {
m_invalidator = invalidator;
}
std::shared_ptr<provider::Invalidator<Connection>> Connection::getInvalidator() {
return m_invalidator;
}
ConnectionImpl::ConnectionImpl(PGconn* connection)
: m_connection(connection)
{}

View File

@ -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<provider::Invalidator<Connection>> 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<provider::Invalidator<Connection>>& invalidator);
std::shared_ptr<provider::Invalidator<Connection>> getInvalidator();
};
class ConnectionImpl : public Connection {

View File

@ -26,7 +26,7 @@
namespace oatpp { namespace postgresql {
void ConnectionProvider::ConnectionInvalidator::invalidate(const std::shared_ptr<orm::Connection> &resource) {
void ConnectionProvider::ConnectionInvalidator::invalidate(const std::shared_ptr<Connection> &resource) {
(void) resource;
//Do nothing.
}
@ -36,7 +36,7 @@ ConnectionProvider::ConnectionProvider(const oatpp::String& connectionString)
, m_connectionString(connectionString)
{}
provider::ResourceHandle<orm::Connection> ConnectionProvider::get() {
provider::ResourceHandle<Connection> ConnectionProvider::get() {
auto handle = PQconnectdb(m_connectionString->c_str());
@ -47,11 +47,11 @@ provider::ResourceHandle<orm::Connection> ConnectionProvider::get() {
"Error. Can't connect. " + errMsg);
}
return provider::ResourceHandle<orm::Connection>(std::make_shared<ConnectionImpl>(handle), m_invalidator);
return provider::ResourceHandle<Connection>(std::make_shared<ConnectionImpl>(handle), m_invalidator);
}
async::CoroutineStarterForResult<const provider::ResourceHandle<orm::Connection>&> ConnectionProvider::getAsync() {
async::CoroutineStarterForResult<const provider::ResourceHandle<Connection>&> ConnectionProvider::getAsync() {
throw std::runtime_error("[oatpp::postgresql::ConnectionProvider::getAsync()]: Error. Not implemented!");
}

View File

@ -35,12 +35,12 @@ namespace oatpp { namespace postgresql {
/**
* Connection provider.
*/
class ConnectionProvider : public provider::Provider<orm::Connection> {
class ConnectionProvider : public provider::Provider<Connection> {
private:
class ConnectionInvalidator : public provider::Invalidator<orm::Connection> {
class ConnectionInvalidator : public provider::Invalidator<Connection> {
public:
void invalidate(const std::shared_ptr<orm::Connection>& resource) override;
void invalidate(const std::shared_ptr<Connection>& resource) override;
};
private:
@ -58,13 +58,13 @@ public:
* Get Connection.
* @return - resource.
*/
provider::ResourceHandle<orm::Connection> get() override;
provider::ResourceHandle<Connection> get() override;
/**
* Get Connection in Async manner.
* @return - &id:oatpp::async::CoroutineStarterForResult; of `Connection`.
*/
async::CoroutineStarterForResult<const provider::ResourceHandle<orm::Connection>&> getAsync() override;
async::CoroutineStarterForResult<const provider::ResourceHandle<Connection>&> getAsync() override;
/**
* Stop provider and free associated resources.
@ -79,7 +79,7 @@ public:
* - &id:oatpp::postgresql::ConnectionAcquisitionProxy;.
*/
typedef oatpp::provider::Pool<
provider::Provider<orm::Connection>,
provider::Provider<Connection>,
Connection,
ConnectionAcquisitionProxy
> ConnectionPool;

View File

@ -54,6 +54,16 @@ namespace {
}
void Executor::ConnectionInvalidator::invalidate(const std::shared_ptr<orm::Connection>& connection) {
auto c = std::static_pointer_cast<Connection>(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<oatpp::String, oatpp::Void>& params,
const mapping::Serializer& serializer,
@ -123,8 +133,9 @@ Executor::QueryParams::QueryParams(const StringTemplate& queryTemplate,
}
Executor::Executor(const std::shared_ptr<provider::Provider<orm::Connection>>& connectionProvider)
: m_connectionProvider(connectionProvider)
Executor::Executor(const std::shared_ptr<provider::Provider<Connection>>& connectionProvider)
: m_connectionInvalidator(std::make_shared<ConnectionInvalidator>())
, m_connectionProvider(connectionProvider)
, m_resultMapper(std::make_shared<mapping::ResultMapper>())
{
m_defaultTypeResolver->addKnownClasses({
@ -288,7 +299,12 @@ data::share::StringTemplate Executor::parseQueryTemplate(const oatpp::String& na
provider::ResourceHandle<orm::Connection> Executor::getConnection() {
auto connection = m_connectionProvider->get();
if(connection) {
return connection;
/* set correct invalidator before cast */
connection.object->setInvalidator(connection.invalidator);
return provider::ResourceHandle<orm::Connection>(
connection.object,
m_connectionInvalidator
);
}
throw std::runtime_error("[oatpp::postgresql::Executor::getConnection()]: Error. Can't connect.");
}

View File

@ -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<orm::Connection> {
public:
void invalidate(const std::shared_ptr<orm::Connection>& connection) override;
};
private:
struct QueryParameter {
@ -109,12 +119,13 @@ private:
const provider::ResourceHandle<orm::Connection>& connection);
private:
std::shared_ptr<provider::Provider<orm::Connection>> m_connectionProvider;
std::shared_ptr<ConnectionInvalidator> m_connectionInvalidator;
std::shared_ptr<provider::Provider<Connection>> m_connectionProvider;
std::shared_ptr<mapping::ResultMapper> m_resultMapper;
mapping::Serializer m_serializer;
public:
Executor(const std::shared_ptr<provider::Provider<orm::Connection>>& connectionProvider);
Executor(const std::shared_ptr<provider::Provider<Connection>>& connectionProvider);
std::shared_ptr<data::mapping::TypeResolver> createTypeResolver() override;

View File

@ -112,7 +112,10 @@ void ArrayTest::onRun() {
OATPP_LOGI(TAG, "DB-URL='%s'", TEST_DB_URL);
auto connectionProvider = std::make_shared<oatpp::postgresql::ConnectionProvider>(TEST_DB_URL);
auto executor = std::make_shared<oatpp::postgresql::Executor>(connectionProvider);
auto connectionPool = oatpp::postgresql::ConnectionPool::createShared(connectionProvider,
10,
std::chrono::seconds(3));
auto executor = std::make_shared<oatpp::postgresql::Executor>(connectionPool);
auto client = MyClient(executor);
@ -483,7 +486,7 @@ void ArrayTest::onRun() {
}
connectionPool->stop();
}