query/backends/tests/TypeTraitsTest.cpp

114 lines
3.2 KiB
C++

#include <catch2/catch_test_macros.hpp>
#include "matador/sql/connection.hpp"
#include "matador/utils/enum_mapper.hpp"
#include "connection.hpp"
#include "models/location.hpp"
using namespace matador::test;
class TypeTraitsTestFixture
{
public:
TypeTraitsTestFixture()
: db(matador::test::connection::dns)
, schema(std::make_shared<matador::sql::schema>(db.dialect().default_schema_name()))
{
db.open();
db.query(schema).create()
.table<location>("location")
.execute();
}
~TypeTraitsTestFixture()
{
db.query(schema).drop().table("location").execute();
}
protected:
matador::sql::connection db;
std::shared_ptr<matador::sql::schema> schema;
private:
void drop_table_if_exists(const std::string &table_name) {
if (db.exists(table_name)) {
db.query(schema).drop().table(table_name).execute();
}
}
};
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));
}
};
}
TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]")
{
SECTION("Insert and select with direct execution") {
location loc{1, "center", {1, 2, 3}, Color::Black};
auto res = db.query(schema).insert().into<location>("location").values(loc).execute();
REQUIRE(res == 1);
auto result = db.query(schema).select<location>().from("location").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 = db.query(schema).insert().into<location>("location").values<location>().prepare();
auto res = stmt.bind(loc).execute();
REQUIRE(res == 1);
auto result = db.query(schema).select<location>().from("location").
template fetch_all<location>();
for (const auto &l: result) {
REQUIRE(l.name == "center");
}
}
}