Connection. Track prepared statements.

This commit is contained in:
lganzzzo 2020-07-14 01:57:14 +03:00
parent 02ddb50b2c
commit 58f43f8af8
4 changed files with 33 additions and 17 deletions

View File

@ -36,8 +36,17 @@ Connection::~Connection() {
} }
} }
void* Connection::getHandle() { PGconn* Connection::getHandle() {
return m_connection; return m_connection;
} }
void Connection::setPrepared(const oatpp::String& statementName) {
m_prepared.insert(statementName);
}
bool Connection::isPrepared(const oatpp::String& statementName) {
auto it = m_prepared.find(statementName);
return it != m_prepared.end();
}
}} }}

View File

@ -26,6 +26,7 @@
#define oatpp_postgresql_Connection_hpp #define oatpp_postgresql_Connection_hpp
#include "oatpp/database/Connection.hpp" #include "oatpp/database/Connection.hpp"
#include "oatpp/core/Types.hpp"
#include <libpq-fe.h> #include <libpq-fe.h>
@ -34,12 +35,16 @@ namespace oatpp { namespace postgresql {
class Connection : public database::Connection { class Connection : public database::Connection {
private: private:
PGconn* m_connection; PGconn* m_connection;
std::unordered_set<oatpp::String> m_prepared;
public: public:
Connection(PGconn* connection); Connection(PGconn* connection);
~Connection(); ~Connection();
void* getHandle() override; PGconn* getHandle();
void setPrepared(const oatpp::String& statementName);
bool isPrepared(const oatpp::String& statementName);
}; };

View File

@ -51,13 +51,12 @@ std::unique_ptr<Oid[]> Executor::getParamTypes(const StringTemplate& queryTempla
} }
void Executor::prepareQuery(const StringTemplate& queryTemplate, void Executor::prepareQuery(const StringTemplate& queryTemplate,
const std::shared_ptr<database::Connection>& connection) const std::shared_ptr<postgresql::Connection>& connection)
{ {
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData()); auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData());
auto pgConnection = static_cast<PGconn *>(connection->getHandle()); PGresult *qres = PQprepare(connection->getHandle(),
PGresult *qres = PQprepare(pgConnection,
extra->templateName->c_str(), extra->templateName->c_str(),
extra->preparedTemplate->c_str(), extra->preparedTemplate->c_str(),
queryTemplate.getTemplateVariables().size(), queryTemplate.getTemplateVariables().size(),
@ -65,7 +64,7 @@ void Executor::prepareQuery(const StringTemplate& queryTemplate,
auto status = PQresultStatus(qres); auto status = PQresultStatus(qres);
if (status != PGRES_COMMAND_OK) { if (status != PGRES_COMMAND_OK) {
OATPP_LOGD("Executor::prepareQuery", "execute prepare failed: %s", PQerrorMessage(pgConnection)); OATPP_LOGD("Executor::prepareQuery", "execute prepare failed: %s", PQerrorMessage(connection->getHandle()));
} else { } else {
OATPP_LOGD("Executor::prepareQuery", "OK"); OATPP_LOGD("Executor::prepareQuery", "OK");
} }
@ -74,13 +73,11 @@ void Executor::prepareQuery(const StringTemplate& queryTemplate,
void Executor::executeQuery(const StringTemplate& queryTemplate, void Executor::executeQuery(const StringTemplate& queryTemplate,
const std::unordered_map<oatpp::String, oatpp::Void>& params, const std::unordered_map<oatpp::String, oatpp::Void>& params,
const std::shared_ptr<database::Connection>& connection) const std::shared_ptr<postgresql::Connection>& connection)
{ {
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData()); auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData());
auto pgConnection = static_cast<PGconn *>(connection->getHandle());
v_uint32 paramsNumber = queryTemplate.getTemplateVariables().size(); v_uint32 paramsNumber = queryTemplate.getTemplateVariables().size();
std::vector<mapping::Serializer::OutputData> outData(paramsNumber); std::vector<mapping::Serializer::OutputData> outData(paramsNumber);
@ -104,7 +101,7 @@ void Executor::executeQuery(const StringTemplate& queryTemplate,
paramFormats[i] = data.dataFormat; paramFormats[i] = data.dataFormat;
} }
PGresult *qres = PQexecPrepared(pgConnection, PGresult *qres = PQexecPrepared(connection->getHandle(),
extra->templateName->c_str(), extra->templateName->c_str(),
paramsNumber, paramsNumber,
paramValues.get(), paramValues.get(),
@ -114,7 +111,7 @@ void Executor::executeQuery(const StringTemplate& queryTemplate,
auto status = PQresultStatus(qres); auto status = PQresultStatus(qres);
if (status != PGRES_TUPLES_OK) { if (status != PGRES_TUPLES_OK) {
OATPP_LOGD("Database", "execute query failed: %s", PQerrorMessage(pgConnection)); OATPP_LOGD("Database", "execute query failed: %s", PQerrorMessage(connection->getHandle()));
} else { } else {
OATPP_LOGD("Database", "OK_2"); OATPP_LOGD("Database", "OK_2");
} }
@ -170,6 +167,7 @@ database::QueryResult Executor::execute(const StringTemplate& queryTemplate,
const std::shared_ptr<database::Connection>& connection) const std::shared_ptr<database::Connection>& connection)
{ {
auto pgConnection = std::static_pointer_cast<postgresql::Connection>(connection);
auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData()); auto extra = std::static_pointer_cast<ql_template::Parser::TemplateExtra>(queryTemplate.getExtraData());
std::unordered_map<oatpp::String, oatpp::String> map; std::unordered_map<oatpp::String, oatpp::String> map;
@ -178,13 +176,17 @@ database::QueryResult Executor::execute(const StringTemplate& queryTemplate,
} }
auto res = queryTemplate.format(map); auto res = queryTemplate.format(map);
OATPP_LOGD("AAA", "prepared[%s]={%s}", extra->templateName->c_str(), extra->preparedTemplate->c_str()); if(!pgConnection->isPrepared(extra->templateName)) {
OATPP_LOGD("AAA", "query={%s}", res->c_str()); OATPP_LOGD("AAA", "prepared[%s]={%s}", extra->templateName->c_str(), extra->preparedTemplate->c_str());
prepareQuery(queryTemplate, pgConnection);
pgConnection->setPrepared(extra->templateName);
}
prepareQuery(queryTemplate, connection); OATPP_LOGD("AAA", "query={%s}", res->c_str());
executeQuery(queryTemplate, params, connection); executeQuery(queryTemplate, params, pgConnection);
return database::QueryResult(); return database::QueryResult();
} }
}} }}

View File

@ -38,10 +38,10 @@ namespace oatpp { namespace postgresql {
class Executor : public database::Executor { class Executor : public database::Executor {
private: private:
std::unique_ptr<Oid[]> getParamTypes(const StringTemplate& queryTemplate, const ParamsTypeMap& paramsTypeMap); std::unique_ptr<Oid[]> getParamTypes(const StringTemplate& queryTemplate, const ParamsTypeMap& paramsTypeMap);
void prepareQuery(const StringTemplate& queryTemplate, const std::shared_ptr<database::Connection>& connection); void prepareQuery(const StringTemplate& queryTemplate, const std::shared_ptr<postgresql::Connection>& connection);
void executeQuery(const StringTemplate& queryTemplate, void executeQuery(const StringTemplate& queryTemplate,
const std::unordered_map<oatpp::String, oatpp::Void>& params, const std::unordered_map<oatpp::String, oatpp::Void>& params,
const std::shared_ptr<database::Connection>& connection); const std::shared_ptr<postgresql::Connection>& connection);
private: private:
mapping::TypeMapper m_typeMapper; mapping::TypeMapper m_typeMapper;
mapping::Serializer m_serializer; mapping::Serializer m_serializer;