diff --git a/include/mysql.hpp b/include/mysql.hpp index 9680c013..a830842f 100644 --- a/include/mysql.hpp +++ b/include/mysql.hpp @@ -346,10 +346,10 @@ class mysql { template void set_param_bind(MYSQL_BIND ¶m_bind, T &&value, int i, - std::map> &mp) { + std::map> &mp, bool &is_null) { using U = std::remove_const_t>; if constexpr (is_optional_v::value) { - return set_param_bind(param_bind, *value, i, mp); + return set_param_bind(param_bind, *value, i, mp, is_null); } else if constexpr (std::is_arithmetic_v) { param_bind.buffer_type = @@ -377,6 +377,7 @@ class mysql { param_bind.buffer = &(mp.rbegin()->second[0]); param_bind.buffer_length = 65536; } + param_bind.is_null = &is_null; } template @@ -436,12 +437,13 @@ class mysql { std::array param_binds = {}; std::map> mp; + std::array nulls = {}; std::vector v; T t{}; int index = 0; - iguana::for_each(t, [&](auto item, auto i) { - set_param_bind(param_binds[index], t.*item, index, mp); + iguana::for_each(t, [&](auto item, auto /*i*/) { + set_param_bind(param_binds[index], t.*item, index, mp, nulls[index]); index++; }); @@ -471,13 +473,20 @@ class mysql { p.second.assign(p.second.size(), 0); } - v.push_back(std::move(t)); - iguana::for_each(t, [&mp, &t](auto item, auto /*i*/) { - using U = std::remove_reference_t().*item)>; - if constexpr (std::is_arithmetic_v) { - memset(&(t.*item), 0, sizeof(U)); + iguana::for_each(t, [&nulls, &t](auto item, auto i) { + constexpr auto Idx = decltype(i)::value; + if (nulls.at(Idx)) { + using U = std::remove_reference_t().*item)>; + if constexpr (is_optional_v::value) { + t.*item = {}; + } + else if constexpr (std::is_arithmetic_v) { + t.*item = {}; + } } }); + + v.push_back(std::move(t)); } return v; diff --git a/tests/test_ormpp.cpp b/tests/test_ormpp.cpp index 90e68742..0fcaf800 100644 --- a/tests/test_ormpp.cpp +++ b/tests/test_ormpp.cpp @@ -89,10 +89,11 @@ struct test_optional { int id; std::optional name; std::optional age; + std::optional empty; }; REFLECTION(test_optional, id, name, age); -TEST_CASE("test_optional") { +TEST_CASE("test optional") { #ifdef ORMPP_ENABLE_MYSQL dbng mysql; if (mysql.connect(ip, "root", password, db)) { @@ -104,9 +105,11 @@ TEST_CASE("test_optional") { REQUIRE(v1.size() > 0); CHECK(v1.front().age.value() == 200); CHECK(v1.front().name.value() == "purecpp"); + CHECK(v1.front().empty.has_value() == false); REQUIRE(v2.size() > 0); CHECK(v2.front().age.value() == 200); CHECK(v2.front().name.value() == "purecpp"); + CHECK(v2.front().empty.has_value() == false); } #endif #ifdef ORMPP_ENABLE_SQLITE3 @@ -120,9 +123,11 @@ TEST_CASE("test_optional") { REQUIRE(v1.size() > 0); CHECK(v1.front().age.value() == 200); CHECK(v1.front().name.value() == "purecpp"); + CHECK(v1.front().empty.has_value() == false); REQUIRE(v2.size() > 0); CHECK(v2.front().age.value() == 200); CHECK(v2.front().name.value() == "purecpp"); + CHECK(v2.front().empty.has_value() == false); } #endif }