#include #include #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 TypeTraitsTestFixture { public: TypeTraitsTestFixture() : pool_(Type::dns, 4), session_(pool_) { auto res = session_.create() .table("location") .execute(); REQUIRE(res.first == 0); REQUIRE(res.second == R"(CREATE TABLE "location" ("id" BIGINT, "name" VARCHAR(255), "coordinate_x" INTEGER, "coordinate_y" INTEGER, "coordinate_z" INTEGER, "color" TEXT, CONSTRAINT PK_location PRIMARY KEY (id)))"); } ~TypeTraitsTestFixture() { session_.drop().table("location").execute(); } matador::sql::session &session() { return session_; } private: matador::sql::connection_pool pool_; matador::sql::session session_; }; static const matador::utils::enum_mapper 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 { inline static data_type_t builtin_type(std::size_t size) { return data_type_traits::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) { auto &s = TypeTraitsTestFixture::session(); SECTION("Insert and select with direct execution") { location loc{1, "center", {1, 2, 3}, Color::Black}; auto res = s.insert().template into("location").values(loc).execute(); REQUIRE(res.first == 1); auto result = s.template select().from("location"). template fetch_all(); 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").template values().prepare(); auto res = stmt.bind(loc).execute(); REQUIRE(res == 1); auto result = s.template select().from("location"). template fetch_all(); for (const auto &l: result) { REQUIRE(l.name == "center"); } } }