#include "postgres_statement.hpp" #include "postgres_error.hpp" #include "postgres_parameter_binder.h" #include "postgres_result_reader.hpp" namespace matador::backends::postgres { postgres_statement::postgres_statement(PGconn *db, std::string name, const sql::query_context &query) : statement_impl(query, 0) , db_(db) , name_(std::move(name)) {} utils::result postgres_statement::execute(const sql::parameter_binder& bindings) { const auto* postgres_bindings = dynamic_cast(&bindings); if (!postgres_bindings) { return utils::failure(utils::error(sql::error_code::EXECUTE_FAILED, "Failed to cast bindings to postgres bindings")); } PGresult *res = PQexecPrepared(db_, name_.c_str(), static_cast(postgres_bindings->params().values.size()), postgres_bindings->params().values.data(), postgres_bindings->params().lengths.data(), postgres_bindings->params().formats.data(), 0); if (is_result_error(res)) { return utils::failure(make_error(sql::error_code::EXECUTE_FAILED, res, db_, "Failed to execute statement", query_.sql)); } const auto *tuples = PQcmdTuples(res); if (strlen(tuples) == 0) { return utils::ok(static_cast(0)); } return utils::ok(static_cast(std::stoul(tuples))); } utils::result, utils::error> postgres_statement::fetch(const sql::parameter_binder& bindings) { const auto* postgres_bindings = dynamic_cast(&bindings); if (!postgres_bindings) { return utils::failure(utils::error(sql::error_code::EXECUTE_FAILED, "Failed to cast bindings to postgres bindings")); } PGresult *res = PQexecPrepared(db_, name_.c_str(), static_cast(postgres_bindings->params().values.size()), postgres_bindings->params().values.data(), postgres_bindings->params().lengths.data(), postgres_bindings->params().formats.data(), 0); if (is_result_error(res)) { return utils::failure(make_error(sql::error_code::FETCH_FAILED, res, db_, "Failed to fetch statement", query_.sql)); } return utils::ok(std::make_unique(std::make_unique(res), query_.prototype)); } std::unique_ptr postgres_statement::create_binder() const { return std::make_unique(query_.bind_vars.size()); } }