#include "pqConn.h" #include #include #include #include #include #include #include #include #include namespace MyGrate::Output::Pq { using ResPtr = std::unique_ptr; PqConn::PqConn(const char * const str) : conn {PQconnectdb(str)} { verify(PQstatus(conn) == CONNECTION_OK, "Connection failure"); PQsetNoticeProcessor(conn, notice_processor, this); } PqConn::~PqConn() { PQfinish(conn); } void PqConn::query(const char * const q) { ResPtr res {PQexec(conn, q), &PQclear}; verify(PQresultStatus(res.get()) == PGRES_COMMAND_OK, q); } struct Bindings { // NOLINTNEXTLINE(hicpp-explicit-conversions) explicit Bindings(const std::initializer_list & vs) { bufs.reserve(vs.size()); values.reserve(vs.size()); lengths.reserve(vs.size()); for (const auto & v : vs) { std::visit(*this, v); } } template void operator()(const T & v) { bufs.emplace_back(std::to_string(v)); const auto & vw {bufs.back()}; values.emplace_back(vw.data()); lengths.emplace_back(vw.length()); } template void operator()(const T & v) { values.emplace_back(v.data()); lengths.emplace_back(v.size()); } template void operator()(const T &) { throw std::runtime_error("Not implemented"); } void operator()(const std::nullptr_t &) { values.emplace_back(nullptr); lengths.emplace_back(0); } std::vector bufs; std::vector values; std::vector lengths; }; void PqConn::query(const char * const q, const std::initializer_list & vs) { Bindings b {vs}; ResPtr res {PQexecParams(conn, q, (int)vs.size(), nullptr, b.values.data(), b.lengths.data(), nullptr, 0), &PQclear}; verify(PQresultStatus(res.get()) == PGRES_COMMAND_OK, q); } void PqConn::notice_processor(void * p, const char * n) { return static_cast(p)->notice_processor(n); } void PqConn::notice_processor(const char *) const { } }