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_LIBMYSQL_COMMAND_HPP
4#define BOAT_SQL_LIBMYSQL_COMMAND_HPP
5
6#include <boat/db/command.hpp>
7#include <boat/detail/config.hpp>
8#include <boat/sql/libmysql/detail/fetch.hpp>
9
11
12class command : public db::command {
13 unique_ptr<MYSQL, mysql_close> dbc_;
14 unique_ptr<MYSQL_STMT, mysql_stmt_close> stmt_;
15 std::string prepared_;
16
17public:
18 command(char const* user,
19 char const* password,
20 char const* host,
21 int port,
22 char const* database)
23 {
24 auto seconds =
25 static_cast<unsigned>(std::chrono::seconds{timeout}.count());
26 dbc_.reset(mysql_init(0));
27 check(!!dbc_, dbc_);
28 for (auto opt : {MYSQL_OPT_CONNECT_TIMEOUT,
29 MYSQL_OPT_READ_TIMEOUT,
30 MYSQL_OPT_WRITE_TIMEOUT})
31 check(!mysql_options(dbc_.get(), opt, &seconds), dbc_);
32 check(mysql_real_connect( //
33 dbc_.get(),
34 host,
35 user,
36 password,
37 database,
38 port,
39 0,
40 CLIENT_MULTI_STATEMENTS) == dbc_.get(),
41 dbc_);
42 check(!mysql_set_character_set(dbc_.get(), "utf8"), dbc_);
43 check(!mysql_query(dbc_.get(), "set time_zone = '+00:00'"), dbc_);
44 }
45
46 db::rowset exec(db::query const& qry, std::stop_token = {}) override
47 {
48 auto ret = db::rowset{};
49 auto txt = qry.text(id_quote(), param_mark());
50 auto ps = qry.params() | std::views::transform(to_bind) |
51 std::ranges::to<std::vector>();
52 if (ps.empty()) {
53 stmt_.reset();
54 prepared_.clear();
55 check(!mysql_query(dbc_.get(), txt.data()), dbc_);
56 for (int ec{}; ec >= 0; ec = mysql_next_result(dbc_.get())) {
57 check(!ec, dbc_);
58 ret = fetch(dbc_.get());
59 }
60 }
61 else {
62 if (prepared_ != txt) {
63 stmt_.reset(mysql_stmt_init(dbc_.get()));
64 check(!!stmt_, dbc_);
65 check(!mysql_stmt_prepare( //
66 stmt_.get(),
67 txt.data(),
68 static_cast<unsigned long>(txt.size())),
69 stmt_);
70 prepared_ = txt;
71 }
72 check(!mysql_stmt_bind_param(stmt_.get(), ps.data()), stmt_);
73 check(!mysql_stmt_execute(stmt_.get()), stmt_);
74 for (int ec{}; ec >= 0; ec = mysql_stmt_next_result(stmt_.get())) {
75 check(!ec, stmt_);
76 ret = fetch(stmt_.get());
77 }
78 }
79 return ret;
80 }
81
82 void set_autocommit(bool on) override
83 {
84 if (on)
85 check(!mysql_rollback(dbc_.get()), dbc_);
86 check(!mysql_autocommit(dbc_.get(), on), dbc_);
87 }
88
89 void commit() override { check(!mysql_commit(dbc_.get()), dbc_); }
90 char id_quote() override { return '`'; }
91 std::string param_mark() override { return "?"; }
92 std::string dbms() override { return "mysql"; }
93};
94
95} // namespace boat::sql::libmysql
96
97#endif // BOAT_SQL_LIBMYSQL_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
std::string param_mark() override
"{}" in the result is replaced with the parameter number.
Definition command.hpp:91
void commit() override
Definition command.hpp:89
std::string dbms() override
The result is lower-case.
Definition command.hpp:92
db::rowset exec(db::query const &qry, std::stop_token={}) override
Definition command.hpp:46
char id_quote() override
Definition command.hpp:90
void set_autocommit(bool on) override
Definition command.hpp:82
command(char const *user, char const *password, char const *host, int port, char const *database)
Definition command.hpp:18
Definition command.hpp:10
Definition command.hpp:12
Definition rowset.hpp:12