boat
C++23 geospatial library
Loading...
Searching...
No Matches
command.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef BOAT_SQL_LIBPQ_COMMAND_HPP
4#define BOAT_SQL_LIBPQ_COMMAND_HPP
5
6#include <boat/db/command.hpp>
7#include <boat/sql/libpq/detail/fetch.hpp>
8#include <boat/sql/libpq/detail/params.hpp>
9
11
12class command : public db::command {
13 unique_ptr<PGconn, PQfinish> dbc_;
14
15public:
16 explicit command(char const* connection) : dbc_(PQconnectdb(connection))
17 {
18 check(dbc_ && PQstatus(dbc_.get()) == CONNECTION_OK, dbc_.get());
19 }
20
21 db::rowset exec(db::query const& qry, std::stop_token tok = {}) override
22 {
23 auto cxl = unique_ptr<PGcancel, PQfreeCancel>{PQgetCancel(dbc_.get())};
24 check(!!cxl, dbc_.get());
25 char err[256]{};
26 auto stop = std::stop_callback{
27 tok, [&] { PQcancel(cxl.get(), err, sizeof(err)); }};
28 auto txt = qry.text(id_quote(), param_mark());
29 auto ps = qry.params() | std::views::transform(params::make) |
30 std::ranges::to<std::vector>();
31 if (ps.empty()) {
32 auto res =
33 unique_ptr<PGresult, PQclear>{PQexec(dbc_.get(), txt.data())};
34 return fetch(res.get());
35 }
36 auto types = std::vector<Oid>(ps.size());
37 auto values = std::vector<char const*>(ps.size());
38 auto lengths = std::vector<int>(ps.size());
39 auto formats = std::vector<int>(ps.size());
40 for (size_t i{}; i < ps.size(); ++i) {
41 auto& p = ps[i];
42 types[i] = params::type(p);
43 values[i] = params::value(p);
44 lengths[i] = params::length(p);
45 formats[i] = params::format(p);
46 }
47 auto res = unique_ptr<PGresult, PQclear>{PQexecParams( //
48 dbc_.get(),
49 txt.data(),
50 int(ps.size()),
51 types.data(),
52 values.data(),
53 lengths.data(),
54 formats.data(),
55 text_fmt)};
56 return fetch(res.get());
57 }
58
59 void set_autocommit(bool on) override { exec(on ? "rollback;" : "begin;"); }
60 void commit() override { exec("commit;begin;"); }
61 char id_quote() override { return '"'; }
62 std::string param_mark() override { return "${}"; }
63 std::string dbms() override { return "postgres"; }
64};
65
66} // namespace boat::sql::libpq
67
68#endif // BOAT_SQL_LIBPQ_COMMAND_HPP
Definition query.hpp:20
std::string text(char id_quote, std::string_view param_mark) const
Definition query.hpp:47
std::generator< std::reference_wrapper< variant const > > params() const
Definition query.hpp:73
char id_quote() override
Definition command.hpp:61
command(char const *connection)
Definition command.hpp:16
db::rowset exec(db::query const &qry, std::stop_token tok={}) override
Definition command.hpp:21
void set_autocommit(bool on) override
Definition command.hpp:59
std::string param_mark() override
"{}" in the result is replaced with the parameter number.
Definition command.hpp:62
std::string dbms() override
The result is lower-case.
Definition command.hpp:63
void commit() override
Definition command.hpp:60
Definition command.hpp:10
Definition command.hpp:12
Definition rowset.hpp:12