From 19eb54df8d3f59c6bf8b04203f1954a5a75c1227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Wed, 3 Dec 2025 16:18:03 +0100 Subject: [PATCH] query builder progress --- backends/postgres/src/postgres_connection.cpp | 2 +- include/matador/orm/session.hpp | 6 +- include/matador/query/builder.hpp | 12 +- source/orm/query/query_compiler.cpp | 18 +- test/backends/QueryBasicTest.cpp | 96 +++--- test/backends/QueryRecordTest.cpp | 285 +++++++++++------- test/backends/QueryStatementTests.cpp | 41 ++- test/backends/QueryTest.cpp | 72 ++++- test/backends/StatementTest.cpp | 7 +- test/backends/TypeTraitsTest.cpp | 7 +- test/orm/query/QueryBuilderTest.cpp | 6 +- 11 files changed, 360 insertions(+), 192 deletions(-) diff --git a/backends/postgres/src/postgres_connection.cpp b/backends/postgres/src/postgres_connection.cpp index d782b96..fbccc92 100644 --- a/backends/postgres/src/postgres_connection.cpp +++ b/backends/postgres/src/postgres_connection.cpp @@ -245,7 +245,7 @@ utils::result, utils::error> postgres_connection: null_opt = object::null_option_type::NotNull; } // f.default_value(res->column(4)); - prototype.emplace_back(name, type, utils::null_attributes, null_opt, index); + prototype.emplace_back(name, type, utils::null_attributes, null_opt); } return utils::ok(prototype); diff --git a/include/matador/orm/session.hpp b/include/matador/orm/session.hpp index b8e4f90..6007c1c 100644 --- a/include/matador/orm/session.hpp +++ b/include/matador/orm/session.hpp @@ -245,7 +245,7 @@ utils::result, utils::error> session::update( const obj using namespace matador::utils; using namespace matador::query; - const auto col = column(info.value().get().reference_column()->name()); + const auto col = column(info.value().get().primary_key_attribute()->name()); auto res = matador::query::query::update(info->get().name()) .set(generator::column_value_pairs()) .where(col == _) @@ -271,7 +271,7 @@ utils::result session::remove( const object::object_ptrname()); + const auto col = column(info.value().get().primary_key_attribute()->name()); auto res = matador::query::query::remove() .from( info->get().name() ) .where(col == _) @@ -300,7 +300,7 @@ utils::result, utils::error> session::find(const Primar const auto& type_info = info.value().get(); session_query_builder eqb(*schema_, *this); - const query::column col(query::table{type_info.reference_column()->table_name()}, type_info.reference_column()->name()); + const query::column col(query::table{type_info.name()}, type_info.primary_key_attribute()->name()); using namespace matador::query; auto data = eqb.build(col == utils::_); if (!data.is_ok()) { diff --git a/include/matador/query/builder.hpp b/include/matador/query/builder.hpp index ad906d1..3b9ccda 100644 --- a/include/matador/query/builder.hpp +++ b/include/matador/query/builder.hpp @@ -51,14 +51,18 @@ public: : data_type(utils::data_type_traits::type(size), size) {} }; +using TinyInt = typed_data_type; +using SmallInt = typed_data_type; +using Integer = typed_data_type; using BigInt = typed_data_type; -using Integer = typed_data_type; + using Real = typed_data_type; -using Double_ = typed_data_type; -using String = typed_data_type; +using Double = typed_data_type; + +using Text = typed_data_type; using Boolean = typed_data_type; using Varchar = sized_typed_data_type; - +using Blob = sized_typed_data_type>; class constraint { public: diff --git a/source/orm/query/query_compiler.cpp b/source/orm/query/query_compiler.cpp index 7f576b2..cd2d42e 100644 --- a/source/orm/query/query_compiler.cpp +++ b/source/orm/query/query_compiler.cpp @@ -315,7 +315,7 @@ void query_compiler::visit(internal::query_create_table_part &part) } void query_compiler::visit(internal::query_create_table_columns_part& part) { - std::string result = "("; + std::string result; if (part.columns().size() < 2) { for (const auto &col: part.columns()) { @@ -407,16 +407,24 @@ std::string build_create_column(const object::attribute &col, const sql::dialect std::string build_constraint(const class object::constraint& cons, const sql::dialect& d) { std::string result; if (!cons.name().empty()) { - result.append(d.constraint()).append(" ").append(d.prepare_identifier_string(cons.name())).append(" "); + result.append(d.constraint()).append(" ").append(cons.name()).append(" "); } if (cons.is_primary_key_constraint()) { - result.append(d.primary_key()); + result.append(d.primary_key()).append(" (").append(cons.column_name()).append(")"); } else if (cons.is_foreign_key_constraint()) { - result.append(d.foreign_key()); + result + .append(d.foreign_key()) + .append(" (") + .append(cons.column_name()) + .append(") ") + .append(d.references()).append(" ") + .append(cons.ref_table_name()) + .append(" (") + .append(cons.ref_column_name()) + .append(")"); } else { // handle error } - result.append("(").append(cons.attribute()->full_name()).append(")"); return result; } diff --git a/test/backends/QueryBasicTest.cpp b/test/backends/QueryBasicTest.cpp index 9b050c5..562667d 100644 --- a/test/backends/QueryBasicTest.cpp +++ b/test/backends/QueryBasicTest.cpp @@ -26,28 +26,30 @@ using namespace matador::object; using namespace matador::query; TEST_CASE_METHOD( QueryFixture, "Insert and select basic datatypes", "[query][datatypes]" ) { - REQUIRE(repo.attach("types")); - auto res = query::create() - .table("types", repo) - .execute(db); - REQUIRE(res.is_ok()); - REQUIRE(*res == 0); - tables_to_drop.emplace("types"); - - float float_value = 2.44557f; - double double_value = 11111.23433345; - int8_t cval = 'c'; - short sval = (std::numeric_limits::min)(); - int ival = (std::numeric_limits::min)(); - int64_t llval = (std::numeric_limits::max)(); - unsigned char ucval = (std::numeric_limits::max)(); - unsigned short usval = (std::numeric_limits::max)(); - unsigned int uival = (std::numeric_limits::max)(); - uint64_t ullval = (std::numeric_limits::max)(); - if (db.type() == "sqlite" || db.type() == "postgres") { - ullval = (std::numeric_limits::max)(); - } - bool bval = true; + REQUIRE(repo.attach("types")); + auto obj = object_generator::generate(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"); + float float_value = 2.44557f; + double double_value = 11111.23433345; + int8_t cval = 'c'; + short sval = (std::numeric_limits::min)(); + int ival = (std::numeric_limits::min)(); + int64_t llval = (std::numeric_limits::max)(); + unsigned char ucval = (std::numeric_limits::max)(); + unsigned short usval = (std::numeric_limits::max)(); + unsigned int uival = (std::numeric_limits::max)(); + uint64_t ullval = (std::numeric_limits::max)(); + if (db.type() == "sqlite" || db.type() == "postgres") { + ullval = (std::numeric_limits::max)(); + } + bool bval = true; const char *cstr("Armer schwarzer Kater"); std::string varcharval("hallo welt"); std::string strval = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " @@ -111,9 +113,10 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][ident using namespace matador::sql; auto res = query::create() - .table("quotes", { - make_column("from", 255), - make_column("to", 255) + .table("quotes") + .columns({ + attribute("from", matador::utils::basic_type::type_varchar, 255), + attribute("to", matador::utils::basic_type::type_varchar, 255) }) .execute(db); REQUIRE(res.is_ok()); @@ -126,9 +129,11 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][ident const auto columns = db.describe("quotes"); REQUIRE(columns.is_ok()); + size_t i = 0; for (const auto &col : *columns) { - REQUIRE(col.name() == column_names[col.index()]); - REQUIRE(col.type() == types[col.index()]); + REQUIRE(col.name() == column_names[i]); + REQUIRE(col.type() == types[i]); + ++i; } res = query::insert() @@ -183,8 +188,9 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][col for (const auto &name : column_names) { auto res = query::create() - .table("quotes", { - make_column(name, 255), + .table("quotes") + .columns({ + attribute(name, matador::utils::basic_type::type_varchar, 255) }) .execute(db); REQUIRE(res.is_ok()); @@ -210,8 +216,9 @@ TEST_CASE_METHOD(QueryFixture, "Test quoted literals", "[query][quotes][literals using namespace matador::sql; auto res = query::create() - .table("escapes", { - make_column("name", 255), + .table("escapes") + .columns({ + attribute("name", matador::utils::basic_type::type_varchar, 255) }) .execute(db); REQUIRE(res.is_ok()); @@ -280,8 +287,11 @@ TEST_CASE_METHOD(QueryFixture, "Test describe table", "[query][describe][table]" using namespace matador::sql; REQUIRE(repo.attach("types")); - const auto res = query::create() - .table("types", repo) + auto obj = object_generator::generate(repo, "types"); + auto res = query::create() + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -321,9 +331,11 @@ TEST_CASE_METHOD(QueryFixture, "Test describe table", "[query][describe][table]" }; const auto &cols = columns.value(); + size_t i = 0; for (const auto &col : cols) { - REQUIRE(col.name() == column_names[col.index()]); - REQUIRE(type_check[col.index()](col)); + REQUIRE(col.name() == column_names[i]); + REQUIRE(type_check[i](col)); + ++i; } } @@ -339,8 +351,8 @@ namespace matador::test::temporary { struct pk { template void process(Operator &op) { - matador::access::primary_key(op, "id", id); - matador::access::attribute(op, "name", name, 255); + access::primary_key(op, "id", id); + access::attribute(op, "name", name, 255); } uint32_t id{}; @@ -353,8 +365,11 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key", "[query][primary key]") { using namespace matador::sql; REQUIRE(repo.attach("pk")); + auto obj = object_generator::generate(repo, "pk"); auto res = query::create() - .table("pk", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -382,8 +397,11 @@ TEST_CASE_METHOD(QueryFixture, "Test primary key prepared", "[query][primary key using namespace matador::sql; REQUIRE(repo.attach("pk")); + auto obj = object_generator::generate(repo, "pk"); auto res = query::create() - .table("pk", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); diff --git a/test/backends/QueryRecordTest.cpp b/test/backends/QueryRecordTest.cpp index d4d2d03..71de519 100644 --- a/test/backends/QueryRecordTest.cpp +++ b/test/backends/QueryRecordTest.cpp @@ -18,29 +18,34 @@ using namespace matador::object; using namespace matador::query; using namespace matador::sql; using namespace matador::test; +using namespace matador::utils; TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record][data types]") { check_table_not_exists("types"); auto res = query::create() - .table("types", { - make_pk_column("id"), - make_column("val_char"), - make_column("val_short"), - make_column("val_int"), - make_column("val_long_long"), - make_column("val_uchar"), - make_column("val_ushort"), - make_column("val_uint"), - make_column("val_ulong_long"), - make_column("val_bool"), - make_column("val_float"), - make_column("val_double"), - make_column("val_string"), - make_column("val_varchar", 63), - // make_column("val_date"), - // make_column("val_time"), - make_column("val_blob"), + .table("types") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("val_char", basic_type::type_int8), + attribute("val_short", basic_type::type_int16), + attribute("val_int", basic_type::type_int32), + attribute("val_long_long", basic_type::type_int64), + attribute("val_uchar", basic_type::type_uint8), + attribute("val_ushort", basic_type::type_uint16), + attribute("val_uint", basic_type::type_uint32), + attribute("val_ulong_long", basic_type::type_uint64), + attribute("val_bool", basic_type::type_bool), + attribute("val_float", basic_type::type_float), + attribute("val_double", basic_type::type_double), + attribute("val_string", basic_type::type_text), + attribute("val_varchar", basic_type::type_varchar, 63), + // attribute("val_date", basic_type::type_date), + // attribute("val_time", basic_type::type_time), + attribute("val_blob", basic_type::type_blob), + }) + .constraints({ + constraint("PK_types").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -80,7 +85,7 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record std::string varchar{"good day"}; // auto md{matador::date()}; // auto mt{matador::time::now()}; - matador::utils::blob bin{0x01,0x02,0x03,0x04}; + blob bin{0x01,0x02,0x03,0x04}; res = query::insert() .into("types", cols) @@ -112,17 +117,21 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record REQUIRE(varchar == (*row)->at("val_varchar")); // REQUIRE(md == (*row)->at("val_date")); // REQUIRE(mt == (*row)->at("val_time")); - REQUIRE(bin == (*row)->at("val_blob")); + REQUIRE(bin == (*row)->at("val_blob")); } TEST_CASE_METHOD(QueryFixture, "Create and drop table statement", "[query][record]") { check_table_not_exists("person"); auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -143,12 +152,16 @@ TEST_CASE_METHOD(QueryFixture, "Create and drop table statement", "[query][recor TEST_CASE_METHOD(QueryFixture, "Create and drop table statement with foreign key", "[query][record]") { auto res = query::create() - .table("airplane", { - make_pk_column("id"), - make_column("brand", 255), - make_column("model", 255), - }) - .execute(db); + .table("airplane") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("brand", basic_type::type_varchar, 255), + attribute("model", basic_type::type_varchar, 255), + }) + .constraints({ + constraint("PK_airplane").primary_key("id"), + }) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(res.value() == 0); @@ -156,11 +169,16 @@ TEST_CASE_METHOD(QueryFixture, "Create and drop table statement with foreign key tables_to_drop.emplace("airplane"); res = query::create() - .table("flight", { - make_pk_column("id"), - make_fk_column("airplane_id", "airplane", "id"), - make_column("pilot_name", 255), - }) + .table("flight") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("airplane_id", basic_type::type_uint32), + attribute("pilot_name", basic_type::type_varchar, 255) + }) + .constraints({ + constraint("PK_flight").primary_key("id"), + constraint( "FK_flight_airplane_id").foreign_key("airplane_id").references("airplane", "id") + }) .execute(db); REQUIRE(res.is_ok()); REQUIRE(res.value() == 0); @@ -188,12 +206,16 @@ TEST_CASE_METHOD(QueryFixture, "Create and drop table statement with foreign key TEST_CASE_METHOD(QueryFixture, "Execute insert record statement", "[query][record]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) }) - .execute(db); + .constraints({ + constraint("PK_person").primary_key("id") + }) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(res.value() == 0); tables_to_drop.emplace("person"); @@ -227,10 +249,14 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert record statement", "[query][recor TEST_CASE_METHOD(QueryFixture, "Execute insert record statement with foreign key", "[query][record]") { auto res = query::create() - .table("airplane", { - make_pk_column("id"), - make_column("brand", 255), - make_column("model", 255), + .table("airplane") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("brand", basic_type::type_varchar, 255), + attribute("model", basic_type::type_varchar, 255), + }) + .constraints({ + constraint("PK_airplane").primary_key("id"), }) .execute(db); REQUIRE(res.is_ok()); @@ -238,17 +264,22 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert record statement with foreign key tables_to_drop.emplace("airplane"); res = query::create() - .table("flight", { - make_pk_column("id"), - make_fk_column("airplane_id", "airplane", "id"), - make_column("pilot_name", 255), - }) - .execute(db); + .table("flight") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("airplane_id", basic_type::type_uint32), + attribute("pilot_name", basic_type::type_varchar, 255) + }) + .constraints({ + constraint("PK_flight").primary_key("id"), + constraint( "FK_flight_airplane_id").foreign_key("airplane_id").references("airplane", "id") + }) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(res.value() == 0); tables_to_drop.emplace("flight"); - std::vector> values_list{ + std::vector> values_list{ {1, "Airbus", "A380"}, {2, "Boeing", "707"}, {3, "Boeing", "747"} @@ -281,10 +312,14 @@ TEST_CASE_METHOD(QueryFixture, "Execute insert record statement with foreign key TEST_CASE_METHOD(QueryFixture, "Execute update record statement", "[query][record]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -330,17 +365,21 @@ TEST_CASE_METHOD(QueryFixture, "Execute update record statement", "[query][recor TEST_CASE_METHOD(QueryFixture, "Execute select statement", "[query][record]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(db); + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") + }) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(res.value() == 0); tables_to_drop.emplace("person"); - std::vector> values_list{ + std::vector> values_list{ {1, "george", 45}, {2, "jane", 32}, {3, "michael", 67}, @@ -386,17 +425,21 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement", "[query][record]") TEST_CASE_METHOD(QueryFixture, "Execute select statement with order by", "[query][record]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); REQUIRE(res.value() == 0); tables_to_drop.emplace("person"); - std::vector> values_list{ + std::vector> values_list{ {1, "george", 45}, {2, "jane", 32}, {3, "michael", 67}, @@ -428,17 +471,21 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with order by", "[query TEST_CASE_METHOD(QueryFixture, "Execute select statement with group by and order by", "[query][record]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(db); + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") + }) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); - std::vector> values_list{ + std::vector> values_list{ {1, "george", 45}, {2, "jane", 45}, {3, "joe", 45}, @@ -477,11 +524,16 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with group by and order TEST_CASE_METHOD(QueryFixture, "Execute delete statement", "[query][record]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }).execute(db); + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") + }) + .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); tables_to_drop.emplace("person"); @@ -522,9 +574,10 @@ TEST_CASE_METHOD(QueryFixture, "Execute delete statement", "[query][record]") { TEST_CASE_METHOD(QueryFixture, "Test quoted identifier record", "[query][record]") { auto res = query::create() - .table("quotes", { - make_column("from", 255), - make_column("to", 255) + .table("quotes") + .columns({ + attribute("from", basic_type::type_varchar, 255), + attribute("to", basic_type::type_varchar, 255) }) .execute(db); REQUIRE(res.is_ok()); @@ -533,16 +586,18 @@ TEST_CASE_METHOD(QueryFixture, "Test quoted identifier record", "[query][record] // check table description std::vector columns = { "from", "to"}; - std::vector types = { - matador::utils::basic_type::type_varchar, - matador::utils::basic_type::type_varchar + std::vector types = { + basic_type::type_varchar, + basic_type::type_varchar }; auto fields = db.describe("quotes"); REQUIRE(fields.is_ok()); + size_t i = 0; for (const auto &field : *fields) { - REQUIRE(field.name() == columns[field.index()]); - REQUIRE(field.type() == types[field.index()]); + REQUIRE(field.name() == columns[i]); + REQUIRE(field.type() == types[i]); + ++i; } res = query::insert() @@ -580,10 +635,14 @@ TEST_CASE_METHOD(QueryFixture, "Test quoted identifier record", "[query][record] TEST_CASE_METHOD(QueryFixture, "Test create record", "[query][record][create]") { check_table_not_exists("person"); auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -603,10 +662,14 @@ TEST_CASE_METHOD(QueryFixture, "Test create record", "[query][record][create]") TEST_CASE_METHOD(QueryFixture, "Test insert record", "[query][record][insert]") { check_table_not_exists("person"); auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -636,10 +699,14 @@ TEST_CASE_METHOD(QueryFixture, "Test insert record", "[query][record][insert]") TEST_CASE_METHOD(QueryFixture, "Test update record", "[query][record][update]") { check_table_not_exists("person"); auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -686,10 +753,14 @@ TEST_CASE_METHOD(QueryFixture, "Test update record", "[query][record][update]") TEST_CASE_METHOD(QueryFixture, "Test prepared record statement", "[query][record][prepared]") { check_table_not_exists("person"); auto stmt = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") + .table("person") + .columns({ + attribute("id", basic_type::type_uint32), + attribute("name", basic_type::type_varchar, 255), + attribute("age", basic_type::type_uint16) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .prepare(db); REQUIRE(stmt.is_ok()); @@ -712,8 +783,12 @@ TEST_CASE_METHOD(QueryFixture, "Test prepared record statement", "[query][record TEST_CASE_METHOD(QueryFixture, "Test scalar result", "[query][record][scalar][result]") { check_table_not_exists("person"); auto res = query::create() - .table("person", { - make_pk_column("id"), + .table("person") + .columns({ + attribute("id", basic_type::type_uint32) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); diff --git a/test/backends/QueryStatementTests.cpp b/test/backends/QueryStatementTests.cpp index dc175ad..1d1177c 100644 --- a/test/backends/QueryStatementTests.cpp +++ b/test/backends/QueryStatementTests.cpp @@ -20,8 +20,11 @@ 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, "person"); auto stmt = query::create() - .table("person", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .prepare(db); REQUIRE(stmt); @@ -44,9 +47,12 @@ TEST_CASE_METHOD(QueryFixture, "Test insert statement", "[query][statement][inse using namespace matador::test; REQUIRE(repo.attach("person")); - auto stmt = query::create() - .table("person", repo) - .prepare(db); + const auto obj = object_generator::generate(repo, "person"); + auto stmt = query::create() + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) + .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); @@ -86,9 +92,12 @@ TEST_CASE_METHOD(QueryFixture, "Test update statement", "[query][statement][upda using namespace matador::utils; REQUIRE(repo.attach("person")); - auto stmt = query::create() - .table("person", repo) - .prepare(db); + const auto obj = object_generator::generate(repo, "person"); + auto stmt = query::create() + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) + .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); @@ -152,9 +161,12 @@ TEST_CASE_METHOD(QueryFixture, "Test delete statement", "[query][statement][dele using namespace matador::test; REQUIRE(repo.attach("person")); - auto stmt = query::create() - .table("person", repo) - .prepare(db); + const auto obj = object_generator::generate(repo, "person"); + auto stmt = query::create() + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) + .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); @@ -239,9 +251,12 @@ TEST_CASE_METHOD(QueryFixture, "Test reuse prepared statement", "[query][stateme using namespace matador::test; REQUIRE(repo.attach("person")); - auto stmt = query::create() - .table("person", repo) - .prepare(db); + const auto obj = object_generator::generate(repo, "person"); + auto stmt = query::create() + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) + .prepare(db); REQUIRE(stmt); auto res = stmt->execute(); diff --git a/test/backends/QueryTest.cpp b/test/backends/QueryTest.cpp index d1e2a20..2fdbb91 100644 --- a/test/backends/QueryTest.cpp +++ b/test/backends/QueryTest.cpp @@ -23,8 +23,11 @@ TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query .and_then( [this] { return repo.attach("flight");} ); REQUIRE(result.is_ok()); + auto obj = object_generator::generate(repo, "airplane"); auto res = query::create() - .table("airplane", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -32,8 +35,11 @@ TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query check_table_exists("airplane"); tables_to_drop.emplace("airplane"); + obj = object_generator::generate(repo, "flight"); res = query::create() - .table("flight", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -44,8 +50,11 @@ TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[query][where]") { REQUIRE(repo.attach("person")); + const auto obj = object_generator::generate(repo, "person"); auto res = query::create() - .table("person", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -99,10 +108,14 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[q TEST_CASE_METHOD(QueryFixture, "Execute insert statement", "[query][insert]") { auto res = query::create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("color", 63) + .table("person") + .columns({ + attribute("id", matador::utils::basic_type::type_uint32), + attribute("name", matador::utils::basic_type::type_varchar, 255), + attribute("color", matador::utils::basic_type::type_varchar, 63) + }) + .constraints({ + constraint("PK_person").primary_key("id") }) .execute(db); REQUIRE(res.is_ok()); @@ -144,8 +157,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for .and_then( [this] { return repo.attach("flight");} ); REQUIRE(result.is_ok()); + auto obj = object_generator::generate(repo, "airplane"); auto res = query::create() - .table("airplane", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -153,8 +169,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for REQUIRE(db.exists("airplane")); tables_to_drop.emplace("airplane"); + obj = object_generator::generate(repo, "flight"); res = query::create() - .table("flight", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -207,8 +226,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" .and_then( [this] { return repo.attach("flight");} ); REQUIRE(result.is_ok()); + auto obj = object_generator::generate(repo, "airplane"); auto res = query::create() - .table("airplane", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -216,8 +238,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left" REQUIRE(db.exists("airplane")); tables_to_drop.emplace("airplane"); + obj = object_generator::generate(repo, "flight"); res = query::create() - .table("flight", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -297,8 +322,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single .and_then( [this] { return repo.attach("flight");} ); REQUIRE(result.is_ok()); + auto obj = object_generator::generate(repo, "airplane"); auto res = query::create() - .table("airplane", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -306,8 +334,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single REQUIRE(db.exists("airplane")); tables_to_drop.emplace("airplane"); + obj = object_generator::generate(repo, "flight"); res = query::create() - .table("flight", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -386,8 +417,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship" auto result = repo.attach("recipes") .and_then( [this] { return repo.attach("ingredients"); } ); + auto obj = object_generator::generate(repo, "recipes"); auto res = query::create() - .table("recipes", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -395,8 +429,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship" REQUIRE(db.exists("recipes")); tables_to_drop.emplace("recipes"); + obj = object_generator::generate(repo, "ingredients"); res = query::create() - .table("ingredients", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); @@ -404,8 +441,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship" REQUIRE(db.exists("ingredients")); tables_to_drop.emplace("ingredients"); + obj = object_generator::generate(repo, "recipe_ingredients"); res = query::create() - .table("recipe_ingredients", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); REQUIRE(*res == 0); diff --git a/test/backends/StatementTest.cpp b/test/backends/StatementTest.cpp index 87b2da4..a296cfa 100644 --- a/test/backends/StatementTest.cpp +++ b/test/backends/StatementTest.cpp @@ -1,6 +1,7 @@ #include #include "matador/object/attribute.hpp" +#include "matador/object/object_generator.hpp" #include "matador/sql/connection.hpp" @@ -13,6 +14,7 @@ #include "QueryFixture.hpp" #include "models/airplane.hpp" +#include "models/location.hpp" using namespace matador::sql; using namespace matador::object; @@ -32,8 +34,11 @@ class StatementTestFixture : public QueryFixture public: StatementTestFixture() { + const auto obj = object_generator::generate(repo, "airplane"); const auto res = query::create() - .table("airplane", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); REQUIRE(res.is_ok()); tables_to_drop.emplace("airplane"); diff --git a/test/backends/TypeTraitsTest.cpp b/test/backends/TypeTraitsTest.cpp index e9ab25e..1a973e8 100644 --- a/test/backends/TypeTraitsTest.cpp +++ b/test/backends/TypeTraitsTest.cpp @@ -2,6 +2,8 @@ #include "ColorEnumTraits.hpp" +#include "matador/object/object_generator.hpp" + #include "matador/sql/connection.hpp" #include "matador/query/generator.hpp" @@ -20,8 +22,11 @@ class TypeTraitsTestFixture : public QueryFixture public: TypeTraitsTestFixture() { REQUIRE(db.open()); + const auto obj = matador::object::object_generator::generate(repo, "location"); const auto res = query::create() - .table("location", repo) + .table(obj->name()) + .columns(obj->attributes()) + .constraints(obj->constraints()) .execute(db); tables_to_drop.emplace("location"); } diff --git a/test/orm/query/QueryBuilderTest.cpp b/test/orm/query/QueryBuilderTest.cpp index 2034e50..0656510 100644 --- a/test/orm/query/QueryBuilderTest.cpp +++ b/test/orm/query/QueryBuilderTest.cpp @@ -52,7 +52,7 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query .table("person") .columns({ attribute("id", basic_type::type_uint32), - attribute("name", basic_type::type_varchar, 255), + attribute("name", basic_type::type_varchar, {255, constraints::Unique}), attribute("age", basic_type::type_uint16), attribute("address", basic_type::type_uint32) }) @@ -62,9 +62,7 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query }) .compile(*db); - REQUIRE(ctx.sql == R"##(CREATE TABLE "person" ("id" BIGINT NOT NULL, "name" VARCHAR(255) NOT NULL UNIQUE, "age" INTEGER NOT NULL, "address" BIGINT NOT NULL, CONSTRAINT PK_person PRIMARY KEY (id)))##"); - REQUIRE(ctx.additional_commands.size() == 1); - REQUIRE(ctx.additional_commands[0].sql == R"##(ALTER TABLE "person" ADD CONSTRAINT FK_person_address FOREIGN KEY ("address") REFERENCES address(id))##"); + REQUIRE(ctx.sql == R"##(CREATE TABLE "person" ("id" BIGINT NOT NULL, "name" VARCHAR(255) NOT NULL UNIQUE, "age" INTEGER NOT NULL, "address" BIGINT NOT NULL, CONSTRAINT PK_person PRIMARY KEY (id), CONSTRAINT FK_person_address FOREIGN KEY (address)))##"); } TEST_CASE_METHOD(QueryFixture, "Test drop table sql statement string", "[query]") {