diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-08-27 19:23:39 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-08-27 19:23:39 +0100 |
commit | 53ad8ff1422266a89e667dddc0c73b2d0f91a373 (patch) | |
tree | 3b7e2415cd6d815758580cf54b0ae0d653d47d4e | |
parent | Mark some empty base implementations not tested (diff) | |
download | mygrate-53ad8ff1422266a89e667dddc0c73b2d0f91a373.tar.bz2 mygrate-53ad8ff1422266a89e667dddc0c73b2d0f91a373.tar.xz mygrate-53ad8ff1422266a89e667dddc0c73b2d0f91a373.zip |
Support binding date/time values to MySQL
-rw-r--r-- | lib/input/mysqlBindings.cpp | 28 | ||||
-rw-r--r-- | lib/input/mysqlBindings.h | 46 | ||||
-rw-r--r-- | lib/mysql_types.h | 3 | ||||
-rw-r--r-- | test/test-mysql.cpp | 1 |
4 files changed, 77 insertions, 1 deletions
diff --git a/lib/input/mysqlBindings.cpp b/lib/input/mysqlBindings.cpp new file mode 100644 index 0000000..3895821 --- /dev/null +++ b/lib/input/mysqlBindings.cpp @@ -0,0 +1,28 @@ +#include "mysqlBindings.h" + +namespace MyGrate::Input { + MYSQL_TIME & + operator<<(MYSQL_TIME & t, const Date & dt) + { + t.year = dt.year; + t.month = dt.month; + t.day = dt.day; + return t; + } + + MYSQL_TIME & + operator<<(MYSQL_TIME & t, const Time & dt) + { + t.hour = dt.hour; + t.minute = dt.minute; + t.second = dt.second; + return t; + } + + MYSQL_TIME & + operator<<(MYSQL_TIME & t, const DateTime & dt) + { + return t << (Date)dt << (Time)dt; + } + +} diff --git a/lib/input/mysqlBindings.h b/lib/input/mysqlBindings.h index 36ef2bf..449c465 100644 --- a/lib/input/mysqlBindings.h +++ b/lib/input/mysqlBindings.h @@ -4,6 +4,7 @@ #include <dbTypes.h> #include <helpers.h> #include <initializer_list> +#include <memory> #include <mysql.h> #include <mysql_types.h> #include <variant> @@ -16,7 +17,21 @@ namespace MyGrate::Input { my_bool null; }; + MYSQL_TIME & operator<<(MYSQL_TIME & t, const Date &); + MYSQL_TIME & operator<<(MYSQL_TIME & t, const Time &); + MYSQL_TIME & operator<<(MYSQL_TIME & t, const DateTime & dt); + struct Bindings { + struct Buffer { + virtual ~Buffer() = default; + }; + template<typename T> struct BufferOf : public Buffer { + template<typename S> BufferOf(const S & src) : val {} + { + val << src; + } + T val; + }; explicit Bindings(const std::span<const DbValue> vs) { binds.reserve(vs.size()); @@ -59,12 +74,43 @@ namespace MyGrate::Input { b.is_null = &data.emplace_back(0, 1).null; } void + operator()(const DateTime & dt) + { + auto & b = binds.emplace_back(); + auto t = std::make_unique<BufferOf<MYSQL_TIME>>(dt); + b.buffer_type = MySQL::CType<DateTime>::type; + b.buffer = &t->val; + b.buffer_length = sizeof(t->val); + buffers.push_back(std::move(t)); + } + void + operator()(const Time & dt) + { + auto & b = binds.emplace_back(); + auto t = std::make_unique<BufferOf<MYSQL_TIME>>(dt); + b.buffer_type = MySQL::CType<Time>::type; + b.buffer = &t->val; + b.buffer_length = sizeof(t->val); + buffers.push_back(std::move(t)); + } + void + operator()(const Date & dt) + { + auto & b = binds.emplace_back(); + auto t = std::make_unique<BufferOf<MYSQL_TIME>>(dt); + b.buffer_type = MySQL::CType<Date>::type; + b.buffer = &t->val; + b.buffer_length = sizeof(t->val); + buffers.push_back(std::move(t)); + } + void operator()(const auto &) { throw std::logic_error("Not implemented"); } std::vector<MYSQL_BIND> binds; std::vector<BingingData> data; + std::vector<std::unique_ptr<Buffer>> buffers; }; class ResultData : public BingingData { diff --git a/lib/mysql_types.h b/lib/mysql_types.h index b3a1a85..d32f6a8 100644 --- a/lib/mysql_types.h +++ b/lib/mysql_types.h @@ -76,6 +76,9 @@ namespace MyGrate { DEFINE_CTYPE(MYSQL_TYPE_TINY, uint8_t); DEFINE_CTYPE(MYSQL_TYPE_STRING, std::string_view); DEFINE_CTYPE(MYSQL_TYPE_BLOB, Blob); + DEFINE_CTYPE(MYSQL_TYPE_DATETIME, DateTime); + DEFINE_CTYPE(MYSQL_TYPE_DATE, Date); + DEFINE_CTYPE(MYSQL_TYPE_TIME, Time); #undef DEFINE_ITYPE #undef DEFINE_USTYPE diff --git a/test/test-mysql.cpp b/test/test-mysql.cpp index 4ad9bb5..91999e9 100644 --- a/test/test-mysql.cpp +++ b/test/test-mysql.cpp @@ -34,7 +34,6 @@ BOOST_AUTO_TEST_CASE(simple) BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {"string_view"})); BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {nullptr})); BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {1.2})); - BOOST_CHECK_THROW(c.query("SET @var = ?", {MyGrate::Time {}}), std::logic_error); } using SomeSelect = MyGrate::DbStmt<"SELECT * FROM foo">; |