70 lines
2.5 KiB
C++
70 lines
2.5 KiB
C++
#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, PGresult *res, std::string name, const sql::query_context &query)
|
|
: statement_impl(query, 0)
|
|
, db_(db)
|
|
, res_(res)
|
|
, name_(std::move(name))
|
|
{}
|
|
|
|
postgres_statement::~postgres_statement() {
|
|
PQclear(res_);
|
|
}
|
|
|
|
utils::result<size_t, utils::error> postgres_statement::execute(const sql::parameter_binder& bindings) {
|
|
const auto* postgres_bindings = dynamic_cast<const postgres_parameter_binder*>(&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<int>(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));
|
|
}
|
|
|
|
size_t value{0};
|
|
if (const auto *tuples = PQcmdTuples(res); strlen(tuples) != 0) {
|
|
value = std::stoul(tuples);
|
|
}
|
|
|
|
PQclear(res);
|
|
|
|
return utils::ok(value);
|
|
}
|
|
|
|
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_statement::fetch(const sql::parameter_binder& bindings) {
|
|
const auto* postgres_bindings = dynamic_cast<const postgres_parameter_binder*>(&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<int>(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<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), query_.prototype));
|
|
}
|
|
|
|
std::unique_ptr<utils::attribute_writer> postgres_statement::create_binder() const {
|
|
return std::make_unique<postgres_parameter_binder>(query_.bind_vars.size());
|
|
}
|
|
}
|