query/backends/tests/TypeTraitsTest.cpp

131 lines
3.6 KiB
C++

#include <catch2/catch_test_macros.hpp>
#include "matador/sql/connection.hpp"
#include "matador/sql/column_generator.hpp"
#include "matador/utils/enum_mapper.hpp"
#include "connection.hpp"
#include "models/location.hpp"
using namespace matador::sql;
using namespace matador::test;
class TypeTraitsTestFixture
{
public:
TypeTraitsTestFixture()
: db(matador::test::connection::dns)
, 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;
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"}
});
template<>
struct matador::sql::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);
if (const auto enum_opt = color_enum.to_enum(enum_string)) {
value = enum_opt.value();
}
}
static any_type create_value(const 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]")
{
schema.attach<location>("location");
SECTION("Insert and select with direct execution") {
location loc{1, "center", {1, 2, 3}, Color::Black};
auto res = db
.query(schema)
.insert()
.into("location", column_generator::generate<location>(schema, true))
.values(loc)
.execute();
REQUIRE(res == 1);
auto result = db
.query(schema)
.select(column_generator::generate<location>(schema, true))
.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", column_generator::generate<location>(schema, true))
.values<location>()
.prepare();
auto res = stmt
.bind(loc)
.execute();
REQUIRE(res == 1);
auto result = db
.query(schema)
.select(column_generator::generate<location>(schema, true))
.from("location")
.fetch_all<location>();
for (const auto &l: result) {
REQUIRE(l.name == "center");
}
}
}