query/test/TypeTraitsTest.cpp

118 lines
3.3 KiB
C++

#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_template_test_macros.hpp>
#include "matador/sql/connection_pool.hpp"
#include "matador/sql/session.hpp"
#include "matador/utils/enum_mapper.hpp"
#include "Databases.hpp"
#include "models/location.hpp"
using namespace matador::sql;
using namespace matador::test;
using namespace matador::sql;
using namespace matador::test;
template<class Type>
class TypeTraitsTestFixture
{
public:
TypeTraitsTestFixture()
: pool_(Type::dns, 4), session_(pool_)
{
session_.create()
.table<location>("location")
.execute();
}
~TypeTraitsTestFixture()
{
session_.drop().table("location").execute();
}
matador::sql::session &session()
{ return session_; }
private:
matador::sql::connection_pool<matador::sql::connection> pool_;
matador::sql::session session_;
};
static const matador::utils::enum_mapper<Color> color_enum({
{Color::Green, "green"},
{Color::Red, "red"},
{Color::Blue, "blue"},
{Color::Yellow, "yellow"},
{Color::Black, "black"},
{Color::White, "white"},
{Color::Brown, "brown"}
});
namespace matador::sql {
template<>
struct data_type_traits<Color, void>
{
inline static data_type_t builtin_type(std::size_t size)
{ return data_type_traits<std::string>::builtin_type(size); }
static void read_value(query_result_reader &reader, const char *id, size_t index, Color &value)
{
std::string enum_string;
reader.read_value(id, index, enum_string, 64);
auto enum_opt = color_enum.to_enum(enum_string);
if (enum_opt) {
value = enum_opt.value();
}
}
static any_type create_value(Color &value)
{
return color_enum.to_string(value);
}
static void bind_value(parameter_binder &binder, size_t index, Color &value)
{
binder.bind(index, color_enum.to_string(value));
}
};
}
TEMPLATE_TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]", Sqlite, Postgres, MySql)
{
auto &s = TypeTraitsTestFixture<TestType>::session();
SECTION("Insert and select with direct execution") {
location loc{1, "center", {1, 2, 3}, Color::Black};
auto res = s.insert().template into<location>("location").values(loc).execute();
REQUIRE(res == 1);
auto result = s.template select<location>().from("location").
template fetch_all<location>();
for (const auto &l: result) {
REQUIRE(l.name == "center");
}
}
SECTION("Insert and select with prepared statement") {
location loc{1, "center", {1, 2, 3}, Color::Black};
auto stmt = s.insert().template into<location>("location").template values<location>().prepare();
auto res = stmt.bind(loc).execute();
REQUIRE(res == 1);
auto result = s.template select<location>().from("location").
template fetch_all<location>();
for (const auto &l: result) {
REQUIRE(l.name == "center");
}
}
}