From 0168b96b79db2627fdba77a8712956408aa081d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 4 Oct 2017 21:28:18 +0200 Subject: Add postgresql support --- src/database/postgresql_statement.hpp | 128 ++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/database/postgresql_statement.hpp (limited to 'src/database/postgresql_statement.hpp') diff --git a/src/database/postgresql_statement.hpp b/src/database/postgresql_statement.hpp new file mode 100644 index 0000000..5016350 --- /dev/null +++ b/src/database/postgresql_statement.hpp @@ -0,0 +1,128 @@ +#pragma once + +#include + +#include + +#include + +class PostgresqlStatement: public Statement +{ + public: + PostgresqlStatement(std::string body, PGconn*const conn): + body(std::move(body)), + conn(conn) + {} + ~PostgresqlStatement() + {} + PostgresqlStatement(const PostgresqlStatement&) = delete; + PostgresqlStatement& operator=(const PostgresqlStatement&) = delete; + PostgresqlStatement(PostgresqlStatement&& other) = delete; + PostgresqlStatement& operator=(PostgresqlStatement&& other) = delete; + + StepResult step() override final + { + if (!this->executed) + { + this->current_tuple = 0; + this->executed = true; + if (!this->execute()) + return StepResult::Error; + } + else + { + this->current_tuple++; + } + if (this->current_tuple < PQntuples(this->result)) + return StepResult::Row; + return StepResult::Done; + } + + int64_t get_column_int64(const int col) override + { + const char* result = PQgetvalue(this->result, this->current_tuple, col); + std::istringstream iss; + iss.str(result); + int64_t res; + iss >> res; + return res; + } + std::string get_column_text(const int col) override + { + const char* result = PQgetvalue(this->result, this->current_tuple, col); + return result; + } + int get_column_int(const int col) override + { + const char* result = PQgetvalue(this->result, this->current_tuple, col); + std::istringstream iss; + iss.str(result); + int res; + iss >> res; + return res; + } + + void bind(std::vector params) override + { + + this->params = std::move(params); + } + + bool bind_text(const int, const std::string& data) override + { + this->params.push_back(data); + return true; + } + bool bind_int64(const int pos, const std::int64_t value) override + { + this->params.push_back(std::to_string(value)); + return true; + } + bool bind_null(const int pos) override + { + this->params.push_back("NULL"); + return true; + } + + private: + +private: + bool execute() + { + std::vector params; + params.reserve(this->params.size()); + + for (const auto& param: this->params) + { + log_debug("param:", param); + params.push_back(param.data()); + } + + log_debug("body: ", body); + this->result = PQexecParams(this->conn, this->body.data(), + this->params.size(), + nullptr, + params.data(), + nullptr, + nullptr, + 0); + const auto status = PQresultStatus(this->result); + if (status == PGRES_TUPLES_OK) + { + log_debug("PGRES_TUPLES_OK"); + } + else if (status != PGRES_COMMAND_OK) + { + log_error("Failed to execute command: ", PQresultErrorMessage(this->result)); + return false; + } + return true; + } + + bool executed{false}; + std::string body; + PGconn*const conn; + std::vector params; + PGresult* result{nullptr}; + int current_tuple{0}; +}; -- cgit v1.2.3 From 6dc49f32844b846bd9675ed6a9d669e266122276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 1 Dec 2017 15:06:23 +0100 Subject: Fix a few warnings --- src/database/postgresql_statement.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/database/postgresql_statement.hpp') diff --git a/src/database/postgresql_statement.hpp b/src/database/postgresql_statement.hpp index 5016350..6e5dec8 100644 --- a/src/database/postgresql_statement.hpp +++ b/src/database/postgresql_statement.hpp @@ -73,12 +73,12 @@ class PostgresqlStatement: public Statement this->params.push_back(data); return true; } - bool bind_int64(const int pos, const std::int64_t value) override + bool bind_int64(const int, const std::int64_t value) override { this->params.push_back(std::to_string(value)); return true; } - bool bind_null(const int pos) override + bool bind_null(const int) override { this->params.push_back("NULL"); return true; @@ -99,8 +99,9 @@ private: } log_debug("body: ", body); + const int param_size = static_cast(this->params.size()); this->result = PQexecParams(this->conn, this->body.data(), - this->params.size(), + param_size, nullptr, params.data(), nullptr, -- cgit v1.2.3 From c3313d0d418cb2aaaf2226eb0a7729ef567b6afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 5 Dec 2017 01:05:45 +0100 Subject: Always free the PGresult pointer returned by PQexec Fix a somewhat big memory leak --- src/database/postgresql_statement.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/database/postgresql_statement.hpp') diff --git a/src/database/postgresql_statement.hpp b/src/database/postgresql_statement.hpp index 6e5dec8..30c3ec2 100644 --- a/src/database/postgresql_statement.hpp +++ b/src/database/postgresql_statement.hpp @@ -14,7 +14,10 @@ class PostgresqlStatement: public Statement conn(conn) {} ~PostgresqlStatement() - {} + { + PQclear(this->result); + this->result = nullptr; + } PostgresqlStatement(const PostgresqlStatement&) = delete; PostgresqlStatement& operator=(const PostgresqlStatement&) = delete; PostgresqlStatement(PostgresqlStatement&& other) = delete; -- cgit v1.2.3