From 63b2ca0dbdae190941d60a55c9cff99d4a75a0e1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 31 May 2021 13:18:17 +0100 Subject: Initial commit of prepstmt, selects, record sets This is full of holes, but all the basics are covered. --- lib/input/mysqlBindings.h | 178 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 lib/input/mysqlBindings.h (limited to 'lib/input/mysqlBindings.h') diff --git a/lib/input/mysqlBindings.h b/lib/input/mysqlBindings.h new file mode 100644 index 0000000..dcb3ebf --- /dev/null +++ b/lib/input/mysqlBindings.h @@ -0,0 +1,178 @@ +#ifndef MYGRATE_INPUT_MYSQLBINDINGS_H +#define MYGRATE_INPUT_MYSQLBINDINGS_H + +#include +#include +#include +#include +#include +#include +#include + +namespace MyGrate::Input { + struct BingingData { + explicit BingingData(unsigned long l, my_bool n = 0) : len {l}, null {n} { } + unsigned long len; + my_bool null; + }; + + struct Bindings { + // NOLINTNEXTLINE(hicpp-explicit-conversions) + explicit Bindings(const std::initializer_list & vs) + { + binds.reserve(vs.size()); + data.reserve(vs.size()); + for (const auto & v : vs) { + std::visit(*this, v); + } + } + template + void + operator()(const T & v) + { + auto & b = binds.emplace_back(); + b.buffer_type = MySQL::CType::type; + b.buffer = const_cast(&v); + b.is_unsigned = std::unsigned_integral; + } + template + void + operator()(const T & v) + { + auto & b = binds.emplace_back(); + b.buffer_type = MySQL::CType::type; + b.buffer = const_cast(&v); + } + template + void + operator()(const T & v) + { + auto & b = binds.emplace_back(); + b.buffer_type = MySQL::CType::type; + b.buffer = const_cast(v.data()); + b.length = &data.emplace_back(v.size(), 0).len; + } + void + operator()(const std::nullptr_t &) + { + auto & b = binds.emplace_back(); + b.buffer = nullptr; + b.is_null = &data.emplace_back(0, 1).null; + } + template + void + operator()(const T &) + { + throw std::runtime_error("Not implemented"); + } + std::vector binds; + std::vector data; + }; + + class ResultData : public BingingData { + public: + ResultData() : BingingData {0} { } + virtual ~ResultData() = default; + + [[nodiscard]] virtual DbValue getValue() const = 0; + }; + + template class ResultDataT : public ResultData { + public: + ResultDataT(MYSQL_BIND & b, const MYSQL_FIELD & f) + { + b.buffer = &buf; + b.buffer_length = sizeof(T); + b.is_null = &this->null; + b.length = &this->len; + b.is_unsigned = std::is_unsigned_v; + b.buffer_type = f.type; + } + + [[nodiscard]] DbValue + getValue() const override + { + return buf; + } + + private: + T buf {}; + }; + + template<> class ResultDataT : public ResultData { + public: + ResultDataT(MYSQL_BIND & b, const MYSQL_FIELD & f) : buf(f.length) + { + b.buffer_length = buf.size(); + b.buffer = buf.data(); + b.is_null = &this->null; + b.length = &this->len; + b.buffer_type = f.type; + } + + [[nodiscard]] DbValue + getValue() const override + { + return std::string_view {buf.data(), this->len}; + } + + private: + std::vector buf; + }; + + template<> class ResultDataT : public ResultData { + public: + ResultDataT(MYSQL_BIND & b, const MYSQL_FIELD & f) : buf(f.length) + { + b.buffer_length = buf.size(); + b.buffer = buf.data(); + b.is_null = &this->null; + b.length = &this->len; + b.buffer_type = f.type; + } + + [[nodiscard]] DbValue + getValue() const override + { + return Blob {buf.data(), this->len}; + } + + private: + std::vector buf; + }; + + template class ResultDataTime : public ResultData { + public: + ResultDataTime(MYSQL_BIND & b, const MYSQL_FIELD & f) + { + b.buffer_length = sizeof(MYSQL_TIME); + b.buffer = &buf; + b.is_null = &this->null; + b.length = &this->len; + b.buffer_type = f.type; + } + + [[nodiscard]] DbValue + getValue() const override + { + return Out {*this}; + } + + private: + operator Date() const + { + return Date(buf.year, buf.month, buf.day); + } + operator Time() const + { + return Time(buf.hour, buf.minute, buf.second); + } + operator DateTime() const + { + return DateTime(*this, *this); + } + MYSQL_TIME buf; + }; +} + +#endif -- cgit v1.2.3