From b9f5819be52d8f415f7c46fa316026610139451b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Fri, 9 Jan 2026 18:10:23 +0100 Subject: [PATCH] use table metas where possible --- backends/postgres/test/CMakeLists.txt | 1 + test/backends/QueryBasicTest.cpp | 80 ++------ test/backends/QueryFixture.cpp | 27 ++- test/backends/QueryRecordTest.cpp | 3 +- test/backends/QueryStatementTests.cpp | 144 +++++--------- test/backends/QueryTest.cpp | 269 +++++++------------------- test/backends/StatementTest.cpp | 28 +-- test/backends/TypeTraitsTest.cpp | 10 +- test/models/model_metas.hpp | 15 ++ 9 files changed, 173 insertions(+), 404 deletions(-) create mode 100644 test/models/model_metas.hpp diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index e5cef92..b3bdd32 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -33,6 +33,7 @@ set(TEST_SOURCES ../../../test/backends/TypeTraitsTest.cpp ../../../test/utils/record_printer.hpp ../../../test/utils/record_printer.cpp + ../../../test/models/model_metas.hpp ) set(LIBRARY_TEST_TARGET PostgresTests) diff --git a/test/backends/QueryBasicTest.cpp b/test/backends/QueryBasicTest.cpp index fa2e1d0..9bdb73d 100644 --- a/test/backends/QueryBasicTest.cpp +++ b/test/backends/QueryBasicTest.cpp @@ -22,18 +22,12 @@ using namespace matador::test; using namespace matador::sql; using namespace matador::object; using namespace matador::query; +using namespace matador::utils; TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][datatypes]") { - REQUIRE(repo.attach("types")); - auto obj = object_generator::generate(repo.repo(), "types"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("types"); + REQUIRE(repo.attach("types") + .and_then([this] {return repo.create(db); })); + float float_value = 2.44557f; double double_value = 11111.23433345; int8_t cval = 'c'; @@ -74,16 +68,16 @@ TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][dat blob_val }; - res = query::insert() - .into("types", generator::columns(repo)) - .values(t) - .execute(db); + auto res = query::insert() + .into("types", generator::columns(repo)) + .values(t) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 1); auto result = query::select(repo) - .from("types") - .fetch_one(db); + .from("types") + .fetch_one(db); REQUIRE(result.is_ok()); REQUIRE(*result != nullptr); @@ -108,9 +102,6 @@ TEST_CASE_METHOD(QueryFixture, "Insert and select basic datatypes", "[query][dat } TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][identifier]" ) { - using namespace matador::sql; - using namespace matador::utils; - auto res = query::create() .table("quotes") .columns({ @@ -169,9 +160,6 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][ident } TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][column]" ) { - using namespace matador::sql; - using namespace matador::utils; - const auto start_quote = db.dialect().token_at(dialect_token::StartQuote); const auto end_quote = db.dialect().token_at(dialect_token::EndQuote); @@ -213,9 +201,6 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][col } TEST_CASE_METHOD(QueryFixture, "Test quoted literals", "[query][quotes][literals]") { - using namespace matador::sql; - using namespace matador::utils; - auto res = query::create() .table("escapes") .columns({ @@ -285,18 +270,8 @@ TEST_CASE_METHOD(QueryFixture, "Test quoted literals", "[query][quotes][literals } TEST_CASE_METHOD(QueryFixture, "Test describe table", "[query][describe][table]") { - using namespace matador::sql; - - REQUIRE(repo.attach("types")); - auto obj = object_generator::generate(repo.repo(), "types"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("types"); + REQUIRE(repo.attach("types") + .and_then([this] { return repo.create(db); })); const auto columns = db.describe("types"); REQUIRE(columns.is_ok()); @@ -365,20 +340,12 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key", "[query][primary key]") { using namespace matador::test::temporary; using namespace matador::sql; - REQUIRE(repo.attach("pk")); - auto obj = object_generator::generate(repo.repo(), "pk"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("pk"); + REQUIRE(repo.attach("pk") + .and_then([this] { return repo.create(db); })); pk pk1{ 7, "george" }; - res = query::insert() + auto res = query::insert() .into("pk", generator::columns(repo)) .values(pk1) .execute(db); @@ -395,18 +362,9 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key", "[query][primary key]") { TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key][prepared]") { using namespace matador::test::temporary; - using namespace matador::sql; - REQUIRE(repo.attach("pk")); - auto obj = object_generator::generate(repo.repo(), "pk"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("pk"); + REQUIRE(repo.attach("pk") + .and_then([this] { return repo.create(db); })); pk pk1{ 7, "george" }; @@ -414,9 +372,9 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key .into("pk", generator::columns(repo)) .values(generator::placeholders()) .prepare(db); -REQUIRE(stmt); + REQUIRE(stmt); - res = stmt->bind(pk1) + auto res = stmt->bind(pk1) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); diff --git a/test/backends/QueryFixture.cpp b/test/backends/QueryFixture.cpp index 39c37cd..56ded79 100644 --- a/test/backends/QueryFixture.cpp +++ b/test/backends/QueryFixture.cpp @@ -9,30 +9,28 @@ #include "catch2/catch_test_macros.hpp" namespace matador::test { - QueryFixture::QueryFixture() - : db(connection::dns) - , repo(db.dialect().default_schema_name()) -{ +: db(connection::dns) +, repo(db.dialect().default_schema_name()) { REQUIRE(db.open()); } QueryFixture::~QueryFixture() { - while (!tables_to_drop.empty()) { - drop_table_if_exists(tables_to_drop.top()); - tables_to_drop.pop(); - } + while (!tables_to_drop.empty()) { + drop_table_if_exists(tables_to_drop.top()); + tables_to_drop.pop(); + } + REQUIRE(repo.drop(db)); + REQUIRE(db.close()); } -void QueryFixture::check_table_exists(const std::string &table_name) const -{ +void QueryFixture::check_table_exists(const std::string &table_name) const { auto result = db.exists(table_name); REQUIRE(result.is_ok()); REQUIRE(*result); } -void QueryFixture::check_table_not_exists(const std::string &table_name) const -{ +void QueryFixture::check_table_not_exists(const std::string &table_name) const { auto result = db.exists(table_name); REQUIRE(result.is_ok()); REQUIRE(!*result); @@ -41,7 +39,7 @@ void QueryFixture::check_table_not_exists(const std::string &table_name) const void QueryFixture::drop_table_if_exists(const std::string &table_name) const { const auto result = db.exists(table_name).and_then([&table_name, this](const bool exists) { if (exists) { - auto res = query::query::drop() + auto res = query::query::drop() .table(table_name) .execute(db); REQUIRE(res); @@ -50,5 +48,4 @@ void QueryFixture::drop_table_if_exists(const std::string &table_name) const { return utils::ok(true); }); } - -} \ No newline at end of file +} diff --git a/test/backends/QueryRecordTest.cpp b/test/backends/QueryRecordTest.cpp index 357ed3b..a83e329 100644 --- a/test/backends/QueryRecordTest.cpp +++ b/test/backends/QueryRecordTest.cpp @@ -207,8 +207,7 @@ TEST_CASE_METHOD(QueryFixture, "Create and drop table statement with foreign key check_table_not_exists("airplane"); } -TEST_CASE_METHOD(QueryFixture, "Execute insert record statement", "[query][record]") -{ +TEST_CASE_METHOD(QueryFixture, "Execute insert record statement", "[query][record]") { auto res = query::create() .table("person") .columns({ diff --git a/test/backends/QueryStatementTests.cpp b/test/backends/QueryStatementTests.cpp index 6ebdf23..b0667b4 100644 --- a/test/backends/QueryStatementTests.cpp +++ b/test/backends/QueryStatementTests.cpp @@ -7,6 +7,7 @@ #include "matador/query/table_column.hpp" #include "models/person.hpp" +#include "models/model_metas.hpp" #include "QueryFixture.hpp" @@ -16,11 +17,12 @@ using namespace matador::sql; using namespace matador::object; using namespace matador::query; +using namespace matador::query::meta; +using namespace matador::utils; using namespace matador::test; TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][create]") { - REQUIRE(repo.attach("person")); - const auto obj = object_generator::generate(repo.repo(), "person"); + const auto obj = object_generator::generate(repo.repo(), "persons"); auto stmt = query::create() .table(obj->name()) .columns(obj->attributes()) @@ -31,11 +33,11 @@ TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][crea auto res = stmt->execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 0); - tables_to_drop.emplace("person"); + tables_to_drop.emplace("persons"); - check_table_exists("person"); + check_table_exists("persons"); const std::vector cols = {"id", "name", "age", "image"}; - const auto fields = db.describe("person"); + const auto fields = db.describe("persons"); REQUIRE(fields.is_ok()); for (const auto &fld : *fields) { @@ -44,39 +46,27 @@ TEST_CASE_METHOD(QueryFixture, "Test create statement", "[query][statement][crea } TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][insert]") { - using namespace matador::test; - REQUIRE(repo.attach("person")); - const auto obj = object_generator::generate(repo.repo(), "person"); - auto stmt = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .prepare(db); - REQUIRE(stmt); + REQUIRE(repo.attach("persons") + .and_then([this] { return repo.create(db);})); - auto res = stmt->execute(); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("person"); - - check_table_exists("person"); + check_table_exists(PERSON.table_name()); person george{1, "george", 45, {1,2,3,4}}; - stmt = query::insert() - .into("person", repo) + auto stmt = query::insert() + .into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image}) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); - res = stmt->bind(george) + auto res = stmt->bind(george) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); - auto row = query::select(repo) - .from("person") + auto row = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) .fetch_one(db); REQUIRE(row.is_ok()); @@ -88,40 +78,26 @@ TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][inse } TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][update]") { - using namespace matador::test; - using namespace matador::utils; + REQUIRE(repo.attach("persons") + .and_then([this] { return repo.create(db);})); - REQUIRE(repo.attach("person")); - const auto obj = object_generator::generate(repo.repo(), "person"); - auto stmt = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .prepare(db); - REQUIRE(stmt); - - auto res = stmt->execute(); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("person"); - - check_table_exists("person"); + check_table_exists(PERSON.table_name()); person george{1, "george", 45, {1,2,3,4}}; - stmt = query::insert() - .into("person", repo) + auto stmt = query::insert() + .into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image}) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); - res = stmt->bind(george) + auto res = stmt->bind(george) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); - auto row = query::select(repo) - .from("person") + auto row = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) .fetch_one(db); REQUIRE(row.is_ok()); @@ -133,9 +109,9 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda george.age = 36; george.image = {5,6,7,8}; - stmt = query::update("person") + stmt = query::update(PERSON) .set(generator::column_value_pairs()) - .where("id"_col == _) + .where(PERSON.id == _) .prepare(db); REQUIRE(stmt); @@ -145,8 +121,8 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda REQUIRE(res.is_ok()); REQUIRE(*res == 1); - row = query::select(repo) - .from("person") + row = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) .fetch_one(db); REQUIRE(row.is_ok()); @@ -158,26 +134,13 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda } TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][delete]") { - using namespace matador::test; + REQUIRE(repo.attach("persons") + .and_then([this] { return repo.create(db);})); - REQUIRE(repo.attach("person")); - const auto obj = object_generator::generate(repo.repo(), "person"); - auto stmt = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .prepare(db); - REQUIRE(stmt); + check_table_exists(PERSON.table_name()); - auto res = stmt->execute(); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("person"); - - check_table_exists("person"); - - stmt = query::insert() - .into("person", repo) + auto stmt = query::insert() + .into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image}) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); @@ -190,16 +153,16 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele }; for (const auto &p : peoples) { - res = stmt->bind(p) + auto res = stmt->bind(p) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); stmt->reset(); } - auto select_stmt = query::select(repo) - .from("person") - .where("name"_col == matador::utils::_) + auto select_stmt = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) + .where(PERSON.name ==_) .prepare(db); REQUIRE(select_stmt); @@ -216,12 +179,12 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele } stmt = query::remove() - .from("person") - .where("name"_col == matador::utils::_) + .from(PERSON) + .where(PERSON.name == _) .prepare(db); REQUIRE(stmt); - res = stmt->bind(0, "jane") + auto res = stmt->bind(0, "jane") .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); @@ -248,26 +211,13 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele } TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][statement][reuse]") { - using namespace matador::test; + REQUIRE(repo.attach("persons") + .and_then([this] { return repo.create(db);})); - REQUIRE(repo.attach("person")); - const auto obj = object_generator::generate(repo.repo(), "person"); - auto stmt = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .prepare(db); - REQUIRE(stmt); + check_table_exists(PERSON.table_name()); - auto res = stmt->execute(); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("person"); - - check_table_exists("person"); - - stmt = query::insert() - .into("person", repo) + auto stmt = query::insert() + .into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image}) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt); @@ -280,15 +230,15 @@ TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][stateme }; for (const auto &p : peoples) { - res = stmt->bind(p) + auto res = stmt->bind(p) .execute(); REQUIRE(res.is_ok()); REQUIRE(*res == 1); stmt->reset(); } - stmt = query::select(repo) - .from("person") + stmt = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) .prepare(db); REQUIRE(stmt); diff --git a/test/backends/QueryTest.cpp b/test/backends/QueryTest.cpp index 798f6b6..5bd0705 100644 --- a/test/backends/QueryTest.cpp +++ b/test/backends/QueryTest.cpp @@ -13,6 +13,7 @@ #include "models/person.hpp" #include "models/recipe.hpp" #include "models/shipment.hpp" +#include "models/model_metas.hpp" #include "../test/utils/record_printer.hpp" @@ -20,93 +21,59 @@ using namespace matador::object; using namespace matador::query; using namespace matador::sql; using namespace matador::test; - -META_TABLE(recipes, RECIPE, id, name); -META_TABLE(ingredients, INGREDIENT, id, name); -META_TABLE(recipe_ingredients, RECIPE_INGREDIENT, recipe_id, ingredient_id); -META_TABLE(airplanes, AIRPLANE, id, brand, model); -META_TABLE(flights, FLIGHT, id, airplane_id, pilot_name); -META_TABLE(shipments, SHIPMENT, id, tracking_number) -META_TABLE(packages, PACKAGE, id, weight, shipment_id) +using namespace matador::query::meta; TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query][foreign][relation]") { auto result = repo.attach("airplane") - .and_then( [this] { return repo.attach("flight");} ); + .and_then([this] { return repo.attach("flight");}) + .and_then([this] {return repo.create(db); }); REQUIRE(result.is_ok()); - auto obj = object_generator::generate(repo.repo(), "airplane"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - check_table_exists("airplane"); - tables_to_drop.emplace("airplane"); - - obj = object_generator::generate(repo.repo(), "flight"); - res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - check_table_exists("flight"); - tables_to_drop.emplace("flight"); } TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[query][where]") { - REQUIRE(repo.attach("person")); - const auto obj = object_generator::generate(repo.repo(), "person"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); + REQUIRE(repo.attach("persons")); + auto result = repo.create(db); + REQUIRE(result.is_ok()); - check_table_exists("person"); - tables_to_drop.emplace("person"); + check_table_exists(PERSON.table_name()); person george{7, "george", 45}; george.image.emplace_back(37); - res = query::insert() - .into("person", generator::columns(repo)) + auto res = query::insert() + .into(PERSON, {PERSON.id, PERSON.name, PERSON.age, PERSON.image}) .values(george) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 1); // fetch person as record - auto result_record = query::select(generator::columns(repo)) - .from("person") - .where("id"_col == 7) + auto result_record = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) + .where(PERSON.id == 7) .fetch_all(db); REQUIRE(result_record.is_ok()); for (const auto &i: *result_record) { REQUIRE(i.size() == 4); - REQUIRE(i.at(0).name() == "person.id"); + REQUIRE(i.at(0).name() == "persons.id"); REQUIRE(i.at(0).is_integer()); REQUIRE(i.at(0).as() == george.id); - REQUIRE(i.at(1).name() == "person.name"); + REQUIRE(i.at(1).name() == "persons.name"); REQUIRE(i.at(1).is_varchar()); REQUIRE(i.at(1).as() == george.name); - REQUIRE(i.at(2).name() == "person.age"); + REQUIRE(i.at(2).name() == "persons.age"); REQUIRE(i.at(2).is_integer()); REQUIRE(i.at(2).as() == george.age); } // fetch person as person - auto result_person = query::select(generator::columns(repo)) - .from("person") - .where("id"_col == 7) + auto result_person = query::select({PERSON.id, PERSON.name, PERSON.age, PERSON.image}) + .from(PERSON) + .where(PERSON.id == 7) .fetch_all(db); REQUIRE(result_person.is_ok()); @@ -164,33 +131,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert statement", "[query][insert]") { } TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][foreign]") { - auto result = repo.attach("airplane") - .and_then( [this] { return repo.attach("flight");} ); + auto result = repo.attach("airplanes") + .and_then( [this] { return repo.attach("flights");} ) + .and_then([this] {return repo.create(db); }); REQUIRE(result.is_ok()); - auto obj = object_generator::generate(repo.repo(), "airplane"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("airplane")); - tables_to_drop.emplace("airplane"); - - obj = object_generator::generate(repo.repo(), "flight"); - res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("flight")); - tables_to_drop.emplace("flight"); + REQUIRE(db.exists(AIRPLANE.table_name())); + REQUIRE(db.exists(FLIGHT.table_name())); std::vector planes{ object_ptr(new airplane{1, "Airbus", "A380"}), @@ -199,8 +146,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for }; for (const auto &plane: planes) { - res = query::insert() - .into("airplane", generator::columns(repo)) + auto res = query::insert() + .into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model}) .values(*plane) .execute(db); REQUIRE(res.is_ok()); @@ -208,22 +155,22 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for } auto count = query::select({count_all()}) - .from("airplane") + .from(AIRPLANE) .fetch_value(db); REQUIRE(count.is_ok()); REQUIRE(*count == 3); flight f4711{4, planes.at(1), "hans"}; - res = query::insert() - .into("flight", generator::columns(repo)) + auto res = query::insert() + .into(FLIGHT, {FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name}) .values(f4711) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 1); - auto f = query::select(generator::columns(repo)) - .from("flight") + auto f = query::select({FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name}) + .from(FLIGHT) .fetch_one(db); REQUIRE(f.is_ok()); @@ -234,32 +181,12 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left", "[query][foreign][join_left]") { auto result = repo.attach("airplanes") - .and_then( [this] { return repo.attach("flights");} ); + .and_then( [this] { return repo.attach("flights");} ) + .and_then([this] {return repo.create(db); }); REQUIRE(result.is_ok()); - auto obj = object_generator::generate(repo.repo(), "airplanes"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("airplanes")); - tables_to_drop.emplace("airplanes"); - - obj = object_generator::generate(repo.repo(), "flights"); - res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("flights")); - tables_to_drop.emplace("flights"); + REQUIRE(db.exists(AIRPLANE.table_name())); + REQUIRE(db.exists(FLIGHT.table_name())); std::vector planes{ object_ptr(new airplane{1, "Airbus", "A380"}), @@ -268,8 +195,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" }; for (const auto &plane: planes) { - res = query::insert() - .into("airplanes", generator::columns(repo)) + auto res = query::insert() + .into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model}) .values(*plane) .execute(db); REQUIRE(res.is_ok()); @@ -277,7 +204,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" } auto count = query::select({count_all()}) - .from("airplanes") + .from(AIRPLANE) .fetch_value(db).value(); REQUIRE(count == 3); @@ -289,16 +216,16 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" }; for (const auto &f: flights) { - res = query::insert() - .into("flights", {"id", "airplane_id", "pilot_name"}) + auto res = query::insert() + .into(FLIGHT, {FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name}) .values(*f) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 1); } - auto flight_result = query::select(generator::columns(repo)) - .from("flights") + auto flight_result = query::select({FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name}) + .from(FLIGHT) .fetch_one(db); REQUIRE(flight_result.is_ok()); REQUIRE(flight_result->has_value()); @@ -306,7 +233,6 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" REQUIRE(flight_result.value()->at(1).as() == 1); REQUIRE(flight_result.value()->at(2).as() == "hans"); - using namespace matador::query::meta; const auto f = FLIGHT.as("f"); const auto ap = AIRPLANE.as("ap"); @@ -334,32 +260,12 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single entity", "[query][join_left][find]") { auto result = repo.attach("airplanes") - .and_then( [this] { return repo.attach("flights");} ); + .and_then([this] { return repo.attach("flights");}) + .and_then([this] {return repo.create(db); }); REQUIRE(result.is_ok()); - auto obj = object_generator::generate(repo.repo(), "airplanes"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("airplanes")); - tables_to_drop.emplace("airplanes"); - - obj = object_generator::generate(repo.repo(), "flights"); - res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("flights")); - tables_to_drop.emplace("flights"); + REQUIRE(db.exists(AIRPLANE.table_name())); + REQUIRE(db.exists(FLIGHT.table_name())); std::vector planes{ object_ptr(new airplane{1, "Airbus", "A380"}), @@ -368,8 +274,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single }; for (const auto &plane: planes) { - res = query::insert() - .into("airplanes", generator::columns(repo)) + auto res = query::insert() + .into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model}) .values(*plane) .execute(db); REQUIRE(res.is_ok()); @@ -377,7 +283,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single } auto count = query::select({count_all()}) - .from("airplanes") + .from(AIRPLANE) .fetch_value(db); REQUIRE(count.is_ok()); REQUIRE(count->has_value()); @@ -391,16 +297,16 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single }; for (const auto &f: flights) { - res = query::insert() - .into("flights", generator::columns(repo)) + auto res = query::insert() + .into(FLIGHT, {FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name}) .values(*f) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 1); } - auto flight_result = query::select(generator::columns(repo)) - .from("flights") + auto flight_result = query::select({FLIGHT.id, FLIGHT.airplane_id, FLIGHT.pilot_name}) + .from(FLIGHT) .fetch_one(db); REQUIRE(flight_result.is_ok()); REQUIRE(flight_result->has_value()); @@ -408,7 +314,6 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single REQUIRE(flight_result.value()->at(1).as() == 1); REQUIRE(flight_result.value()->at(2).as() == "hans"); - using namespace matador::query::meta; const auto f = FLIGHT.as("f"); const auto ap = AIRPLANE.as("ap"); @@ -434,46 +339,12 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship", "[query][join][many_to_many]") { auto result = repo.attach("ingredients") - .and_then( [this] { return repo.attach("recipes"); } ); + .and_then( [this] { return repo.attach("recipes"); } ) + .and_then([this] {return repo.create(db); }); - auto obj = object_generator::generate(repo.repo(), "recipes"); - auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("recipes")); - tables_to_drop.emplace("recipes"); - - obj = object_generator::generate(repo.repo(), "ingredients"); - res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("ingredients")); - tables_to_drop.emplace("ingredients"); - - const auto it = repo.find("recipe_ingredients"); - REQUIRE(it != repo.end()); - obj = it->second.node().info().object(); - // obj = object_generator::generate(repo.repo(), "recipe_ingredients"); - res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - - REQUIRE(db.exists("recipe_ingredients")); - tables_to_drop.emplace("recipe_ingredients"); + REQUIRE(db.exists(RECIPE.table_name())); + REQUIRE(db.exists(INGREDIENT.table_name())); + REQUIRE(db.exists(RECIPE_INGREDIENT.table_name())); std::vector ingredients { {1, "Apple"}, @@ -486,8 +357,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship" }; for (const auto &i: ingredients) { - res = query::insert() - .into("ingredients", generator::columns(repo)) + auto res = query::insert() + .into(INGREDIENT, {INGREDIENT.id, INGREDIENT.name}) .values(i) .execute(db); REQUIRE(res.is_ok()); @@ -501,8 +372,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship" }; for (const auto &r: recipes) { - res = query::insert() - .into("recipes", generator::columns(repo)) + auto res = query::insert() + .into(RECIPE, {RECIPE.id, RECIPE.name}) .values(r) .execute(db); REQUIRE(res.is_ok()); @@ -520,11 +391,9 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship" { 9, 3 } }; - using namespace matador::query::meta; - for (const auto & [recipe_id, ingredient_id]: recipe_ingredients) { - res = query::insert() - .into("recipe_ingredients", RECIPE_INGREDIENT) + auto res = query::insert() + .into(RECIPE_INGREDIENT, {RECIPE_INGREDIENT.recipe_id, RECIPE_INGREDIENT.ingredient_id}) .values({recipe_id, ingredient_id}) .execute(db); REQUIRE(res.is_ok()); @@ -618,12 +487,8 @@ void print(std::ostream& out, const record& row) { TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation", "[query][has_many][eager]") { auto result = repo.attach("packages") - .and_then( [this] { return repo.attach("shipments"); } ); - REQUIRE(result.is_ok()); - tables_to_drop.emplace("shipments"); - tables_to_drop.emplace("packages"); - - result = repo.create(db); + .and_then([this] { return repo.attach("shipments"); }) + .and_then([this] {return repo.create(db); }); REQUIRE(result.is_ok()); const std::vector shipments { @@ -631,8 +496,6 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation", object_ptr{new shipment{2, "0815"}} }; - using namespace matador::query::meta; - for (const auto &sh: shipments) { auto res = query::insert() .into(SHIPMENT, SHIPMENT) diff --git a/test/backends/StatementTest.cpp b/test/backends/StatementTest.cpp index fa9aa34..a0c4fcc 100644 --- a/test/backends/StatementTest.cpp +++ b/test/backends/StatementTest.cpp @@ -1,6 +1,5 @@ #include -#include "matador/object/attribute.hpp" #include "matador/object/object_generator.hpp" #include "matador/sql/connection.hpp" @@ -14,12 +13,13 @@ #include "QueryFixture.hpp" #include "models/airplane.hpp" -#include "models/location.hpp" +#include "models/model_metas.hpp" using namespace matador::sql; using namespace matador::object; using namespace matador::query; using namespace matador::test; +using namespace matador::query::meta; namespace matador::test::detail { template @@ -31,14 +31,7 @@ template class StatementTestFixture : public QueryFixture { public: StatementTestFixture() { - const auto obj = object_generator::generate(repo.repo(), "airplane"); - const auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - REQUIRE(res.is_ok()); - tables_to_drop.emplace("airplane"); + REQUIRE(repo.attach("airplanes")); } protected: @@ -51,11 +44,10 @@ protected: TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]") { using namespace matador::utils; - REQUIRE(repo.attach("airplane")); - table ap{"airplane"}; + REQUIRE(repo.create(db)); SECTION("Insert with prepared statement and placeholder") { auto stmt = query::insert() - .into("airplane", generator::columns(repo)) + .into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model}) .values(generator::placeholders()) .prepare(db); REQUIRE(stmt.is_ok()); @@ -67,8 +59,8 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement] stmt->reset(); } - auto result = query::select(generator::columns(repo)) - .from(ap) + auto result = query::select({AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model}) + .from(AIRPLANE) .fetch_all(db); REQUIRE(result.is_ok()); @@ -83,7 +75,7 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement] SECTION("Select with prepared statement") { for (const auto &plane: planes) { auto res = query::insert() - .into("airplane", generator::columns(repo)) + .into(AIRPLANE, {AIRPLANE.id, AIRPLANE.brand, AIRPLANE.model}) .values(*plane) .execute(db); REQUIRE(res.is_ok()); @@ -91,8 +83,8 @@ TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement] } auto stmt = query::select(generator::columns(repo)) - .from(ap) - .where("brand"_col == _) + .from(AIRPLANE) + .where(AIRPLANE.brand == _) .prepare(db); REQUIRE(stmt.is_ok()); diff --git a/test/backends/TypeTraitsTest.cpp b/test/backends/TypeTraitsTest.cpp index c910655..bbecce8 100644 --- a/test/backends/TypeTraitsTest.cpp +++ b/test/backends/TypeTraitsTest.cpp @@ -22,18 +22,12 @@ class TypeTraitsTestFixture : public QueryFixture public: TypeTraitsTestFixture() { REQUIRE(db.open()); - const auto obj = matador::object::object_generator::generate(repo.repo(), "location"); - const auto res = query::create() - .table(obj->name()) - .columns(obj->attributes()) - .constraints(obj->constraints()) - .execute(db); - tables_to_drop.emplace("location"); + REQUIRE(repo.attach("location")); } }; TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]") { - REQUIRE(repo.attach("location")); + REQUIRE(repo.create(db)); SECTION("Insert and select with direct execution") { location loc{1, "center", {1, 2, 3}, Color::Black}; diff --git a/test/models/model_metas.hpp b/test/models/model_metas.hpp new file mode 100644 index 0000000..aa5e028 --- /dev/null +++ b/test/models/model_metas.hpp @@ -0,0 +1,15 @@ +#ifndef MATADOR_MODEL_METAS_HPP +#define MATADOR_MODEL_METAS_HPP + +#include "matador/query/meta_table_macro.hpp" + +META_TABLE(recipes, RECIPE, id, name); +META_TABLE(ingredients, INGREDIENT, id, name); +META_TABLE(recipe_ingredients, RECIPE_INGREDIENT, recipe_id, ingredient_id); +META_TABLE(airplanes, AIRPLANE, id, brand, model); +META_TABLE(flights, FLIGHT, id, airplane_id, pilot_name); +META_TABLE(shipments, SHIPMENT, id, tracking_number) +META_TABLE(packages, PACKAGE, id, weight, shipment_id) +META_TABLE(persons, PERSON, id, name, age, image) + +#endif //MATADOR_MODEL_METAS_HPP \ No newline at end of file