diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-05-31 13:18:17 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-05-31 13:18:17 +0100 |
commit | 63b2ca0dbdae190941d60a55c9cff99d4a75a0e1 (patch) | |
tree | d3766bcbc98fb5fb0fb2d8dddf2f194bedcb0325 /lib/output/pq/pqStmt.cpp | |
parent | Map std::size_t to a sensible header (diff) | |
download | mygrate-63b2ca0dbdae190941d60a55c9cff99d4a75a0e1.tar.bz2 mygrate-63b2ca0dbdae190941d60a55c9cff99d4a75a0e1.tar.xz mygrate-63b2ca0dbdae190941d60a55c9cff99d4a75a0e1.zip |
Initial commit of prepstmt, selects, record sets
This is full of holes, but all the basics are covered.
Diffstat (limited to 'lib/output/pq/pqStmt.cpp')
-rw-r--r-- | lib/output/pq/pqStmt.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/output/pq/pqStmt.cpp b/lib/output/pq/pqStmt.cpp new file mode 100644 index 0000000..04b48c6 --- /dev/null +++ b/lib/output/pq/pqStmt.cpp @@ -0,0 +1,54 @@ +#include "pqStmt.h" +#include "libpq-fe.h" +#include "pqBindings.h" +#include "pqConn.h" +#include "pqRecordSet.h" +#include <compileTimeFormatter.h> +#include <cstdlib> +#include <functional> +#include <helpers.h> +#include <map> +#include <stdexcept> +#include <utility> +#include <vector> + +namespace MyGrate::Output::Pq { + PqPrepStmt::PqPrepStmt(const char * const q, std::size_t n, PqConn * c) : + conn {c->conn.get()}, name {prepareAsNeeded(q, n, c)}, res {nullptr, nullptr} + { + } + + void + PqPrepStmt::execute(const std::initializer_list<DbValue> & vs) + { + Bindings b {vs}; + res = {PQexecPrepared(conn, name.c_str(), (int)vs.size(), b.values.data(), b.lengths.data(), nullptr, 0), + &PQclear}; + verify<std::runtime_error>( + PQresultStatus(res.get()) == PGRES_COMMAND_OK || PQresultStatus(res.get()) == PGRES_TUPLES_OK, name); + } + + std::size_t + PqPrepStmt::rows() const + { + return std::strtoul(PQcmdTuples(res.get()), nullptr, 10); + } + + RecordSetPtr + PqPrepStmt::recordSet() + { + return std::make_unique<PqRecordSet>(std::move(res)); + } + + std::string + PqPrepStmt::prepareAsNeeded(const char * const q, std::size_t n, PqConn * c) + { + if (const auto i = c->stmts.find(q); i != c->stmts.end()) { + return i->second; + } + auto nam {AdHoc::scprintf<"pst%0x">(c->stmts.size())}; + ResPtr res {PQprepare(c->conn.get(), nam.c_str(), q, (int)n, nullptr), PQclear}; + verify<std::runtime_error>(PQresultStatus(res.get()) == PGRES_COMMAND_OK, q); + return c->stmts.emplace(q, std::move(nam)).first->second; + } +} |