schema progress (does not compile)

This commit is contained in:
2025-12-31 11:56:12 +01:00
parent d104222fdd
commit ab2d39407c
65 changed files with 1355 additions and 922 deletions
+87 -32
View File
@@ -12,6 +12,8 @@
#include "matador/query/table.hpp"
#include "matador/query/schema.hpp"
#include "matador/utils/macro_map.hpp"
#include "matador/orm/session_query_builder.hpp"
#include "../backend/test_connection.hpp"
@@ -33,26 +35,63 @@ using namespace matador::utils;
using namespace matador::sql;
using namespace matador::test;
// #define FIELD(FIELD_NAME) const matador::query::column& FIELD_NAME = create_column(*this, #FIELD_NAME);
//
// #define META_TABLE(TABLE_NAME, VARIABLE_NAME, ...) \
// namespace matador::query::meta { \
// namespace internal { \
// class TABLE_NAME##_table : public table { \
// public: \
// TABLE_NAME##_table() : table(#TABLE_NAME) {} \
// MAP(FIELD, __VA_ARGS__) \
// }; } \
// static const internal:: TABLE_NAME##_table VARIABLE_NAME; \
// }
//
// META_TABLE( books, BOOK, id, author_id, title, published_in )
class book_table : public table {
public:
book_table()
: table("books", {"id", "title", "author_id"})
, id(*column_by_name(*this, "id"))
, title(*column_by_name(*this, "id"))
, author_id(*column_by_name(*this, "author_id")) {
}
const column& id;
const column& title;
const column& author_id;
};
book_table BOOK;
using namespace matador::test;
TEST_CASE("Create sql query data for entity with eager has one", "[query][entity][builder]") {
using namespace matador::test;
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
connection db("noop://noop.db");
connection_pool pool("noop://noop.db", 4);
schema scm(pool);
schema scm;
auto result = scm.attach<airplane>("airplanes")
.and_then( [&scm] { return scm.attach<flight>("flights"); } );
REQUIRE(result);
session_query_builder eqb(scm, db);
auto data = eqb.build<flight>("flights.id"_col == _);
const auto it = scm.find(typeid(flight));
REQUIRE(it != scm.end());
const auto* col = it->second.table()["id"];
REQUIRE(col);
auto data = eqb.build<flight>(*col == _);
REQUIRE(data.is_ok());
REQUIRE(data->root_table->name() == "flights");
REQUIRE(data->root_table->table_name() == "flights");
REQUIRE(data->joins.size() == 1);
const auto flights = table("flights");
const auto airplanes = table("airplanes");
const auto flights = table("flights").as("t01");
const auto airplanes = table("airplanes").as("t02");
const std::vector<column> expected_columns {
{ &flights, "id", "c01" },
{ &airplanes, "id", "c02" },
@@ -73,7 +112,7 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity
size_t index{0};
criteria_evaluator evaluator(db.dialect(), qc);
for (const auto &[join_table, condition] : data->joins) {
REQUIRE(join_table->name() == expected_join_data[index].first);
REQUIRE(join_table->table_name() == expected_join_data[index].first);
REQUIRE(evaluator.evaluate(*condition) == expected_join_data[index].second);
++index;
}
@@ -89,20 +128,24 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
connection db("noop://noop.db");
connection_pool pool("noop://noop.db", 4);
schema scm(pool);
schema scm;
auto result = scm.attach<author>("authors")
.and_then( [&scm] { return scm.attach<book>("books"); } );
REQUIRE(result);
session_query_builder eqb(scm, db);
auto data = eqb.build<book>("books.id"_col == _);
const auto it = scm.find(typeid(book));
REQUIRE(it != scm.end());
const auto* col = it->second.table()["id"];
REQUIRE(col);
auto data = eqb.build<book>(*col == _);
REQUIRE(data.is_ok());
REQUIRE(data->root_table->name() == "books");
REQUIRE(data->root_table->table_name() == "books");
REQUIRE(data->joins.size() == 1);
const auto books = table("books");
const auto authors = table("authors");
const auto books = table("books").as("t01");
const auto authors = table("authors").as("t02");
const std::vector<column> expected_columns {
{ &books, "id", "c01" },
{ &books, "title", "c02" },
@@ -127,7 +170,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
size_t index{0};
criteria_evaluator evaluator(db.dialect(), qc);
for (const auto & [join_table, clause] : data->joins) {
REQUIRE(join_table->name() == expected_join_data[index].first);
REQUIRE(join_table->table_name() == expected_join_data[index].first);
REQUIRE(evaluator.evaluate(*clause) == expected_join_data[index].second);
++index;
}
@@ -154,7 +197,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
connection db("noop://noop.db");
connection_pool pool("noop://noop.db", 4);
schema scm(pool);
schema scm;
auto result = scm.attach<product>("products")
.and_then( [&scm] { return scm.attach<order_details>("order_details"); } )
.and_then( [&scm] { return scm.attach<supplier>("suppliers"); } )
@@ -164,13 +207,17 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
session_query_builder eqb(scm, db);
auto data = eqb.build<order>("orders.order_id"_col == _);
const auto it = scm.find(typeid(order));
REQUIRE(it != scm.end());
const auto* col = it->second.table()["order_id"];
REQUIRE(col);
auto data = eqb.build<order>(*col == _);
REQUIRE(data.is_ok());
REQUIRE(data->root_table->name() == "orders");
REQUIRE(data->root_table->table_name() == "orders");
REQUIRE(data->joins.size() == 1);
const auto orders = table("orders");
const auto order_details = table("order_details");
const auto orders = table("orders").as("t01");
const auto order_details = table("order_details").as("t02");
const std::vector<column> expected_columns = {
{ &orders, "order_id", "c01" },
{ &orders, "order_date", "c02" },
@@ -201,7 +248,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
size_t index{0};
criteria_evaluator evaluator(db.dialect(), qc);
for (const auto &jd : data->joins) {
REQUIRE(jd.join_table->name() == expected_join_data[index].first);
REQUIRE(jd.join_table->table_name() == expected_join_data[index].first);
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
++index;
}
@@ -217,20 +264,24 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
connection db("noop://noop.db");
connection_pool pool("noop://noop.db", 4);
schema scm(pool);
schema scm;
auto result = scm.attach<recipe>("recipes")
.and_then( [&scm] { return scm.attach<ingredient>("ingredients"); } );
REQUIRE(result);
session_query_builder eqb(scm, db);
auto data = eqb.build<ingredient>("ingredients.id"_col == _);
const auto it = scm.find(typeid(ingredient));
REQUIRE(it != scm.end());
const auto* col = it->second.table()["id"];
REQUIRE(col);
auto data = eqb.build<ingredient>(*col == _);
REQUIRE(data.is_ok());
REQUIRE(data->root_table->name() == "ingredients");
REQUIRE(data->root_table->table_name() == "ingredients");
REQUIRE(data->joins.size() == 2);
const auto ingredients = table("ingredients");
const auto recipes = table("recipes");
const auto ingredients = table("ingredients").as("t01");
const auto recipes = table("recipes").as("t03");
const std::vector<column> expected_columns {
{ &ingredients, "id", "c01" },
{ &ingredients, "name", "c02" },
@@ -251,7 +302,7 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
size_t index{0};
criteria_evaluator evaluator(db.dialect(), qc);
for (const auto &jd : data->joins) {
REQUIRE(jd.join_table->name() == expected_join_data[index].first);
REQUIRE(jd.join_table->table_name() == expected_join_data[index].first);
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
++index;
}
@@ -267,20 +318,24 @@ TEST_CASE("Create sql query data for entity with eager many to many (inverse par
connection db("noop://noop.db");
connection_pool pool("noop://noop.db", 4);
schema scm(pool);
schema scm;
auto result = scm.attach<student>("students")
.and_then( [&scm] { return scm.attach<course>("courses"); } );
REQUIRE(result);
session_query_builder eqb(scm, db);
auto data = eqb.build<course>("courses.id"_col == _);
const auto it = scm.find(typeid(course));
REQUIRE(it != scm.end());
const auto* col = it->second.table()["id"];
REQUIRE(col);
auto data = eqb.build<course>(*col == _);
REQUIRE(data.is_ok());
REQUIRE(data->root_table->name() == "courses");
REQUIRE(data->root_table->table_name() == "courses");
REQUIRE(data->joins.size() == 2);
const auto courses = table("courses");
const auto students = table("students");
const auto courses = table("courses").as("t01");
const auto students = table("students").as("t03");
const std::vector<column> expected_columns {
{ &courses, "id", "c01" },
{ &courses, "title", "c02" },
@@ -301,7 +356,7 @@ TEST_CASE("Create sql query data for entity with eager many to many (inverse par
size_t index{0};
criteria_evaluator evaluator(db.dialect(), qc);
for (const auto &jd : data->joins) {
REQUIRE(jd.join_table->name() == expected_join_data[index].first);
REQUIRE(jd.join_table->table_name() == expected_join_data[index].first);
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
++index;
}
@@ -317,7 +372,7 @@ TEST_CASE("Test eager relationship", "[session][eager]") {
connection db("noop://noop.db");
connection_pool pool("noop://noop.db", 4);
schema scm(pool);
schema scm;
auto result = scm.attach<department>("departments")
.and_then( [&scm] { return scm.attach<employee>("employees"); } );
REQUIRE(result);
@@ -331,7 +386,7 @@ TEST_CASE("Test eager relationship", "[session][eager]") {
.from(*data->root_table)
.join_left(data->joins)
.where(std::move(data->where_clause))
.order_by(column{data->root_table.get(), data->pk_column_name})
.order_by(column{data->root_table, data->pk_column_name})
.asc()
.str(db);
+15 -15
View File
@@ -32,18 +32,18 @@ TEST_CASE("Test column value generator", "[generator][column_value]") {
}
}
TEST_CASE("Test column generator", "[generator][column]") {
SECTION("Test column generator for simple table") {
const std::vector expected_columns {
column("id"),
column("brand"),
column("model"),
};
const auto result = generator::columns<airplane>();
REQUIRE(result.size() == expected_columns.size());
auto it = result.begin();
for (const auto& c : expected_columns) {
REQUIRE(c.equals( *it++));
}
}
}
// TEST_CASE("Test column generator", "[generator][column]") {
// SECTION("Test column generator for simple table") {
// const std::vector expected_columns {
// column("id"),
// column("brand"),
// column("model"),
// };
// const auto result = generator::columns<airplane>();
// REQUIRE(result.size() == expected_columns.size());
// auto it = result.begin();
// for (const auto& c : expected_columns) {
// REQUIRE(c.equals( *it++));
// }
// }
// }
+17 -13
View File
@@ -39,9 +39,9 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query
auto result = query::create()
.table({"person"})
.columns({
attribute("id", basic_type::UInt32),
attribute("name", basic_type::Varchar, 255),
attribute("age", basic_type::UInt16)
column("id", basic_type::UInt32),
column("name", basic_type::Varchar, 255),
column("age", basic_type::UInt16)
})
.constraints({
constraint("PK_person").primary_key({"id"})
@@ -53,10 +53,10 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query
auto ctx = query::create()
.table("person")
.columns({
attribute("id", basic_type::UInt32),
attribute("name", basic_type::Varchar, {255, constraints::Unique}),
attribute("age", basic_type::UInt16),
attribute("address", basic_type::UInt32)
column("id", basic_type::UInt32),
column("name", basic_type::Varchar, 255).unique(),
column("age", basic_type::UInt16),
column("address", basic_type::UInt32)
})
.constraints({
constraint("PK_person").primary_key({"id"}),
@@ -221,9 +221,9 @@ TEST_CASE_METHOD(QueryFixture, "Test create, insert and select a blob column", "
auto result = query::create()
.table("person")
.columns({
attribute("id", basic_type::UInt32),
attribute("name", basic_type::Varchar, 255),
attribute("data", basic_type::Blob)
column("id", basic_type::UInt32),
column("name", basic_type::Varchar, 255),
column("data", basic_type::Blob)
})
.constraints({
constraint("PK_person").primary_key({"id"})
@@ -247,10 +247,14 @@ TEST_CASE_METHOD(QueryFixture, "Test create, insert and select a blob column", "
}
TEST_CASE_METHOD(QueryFixture, "Test select statement with join_left", "[query][statement][join_left]") {
const auto ap = table("airplane").as("ap");
const auto f = table("flight").as("f");
const class matador::query::column col1 = {&f, "airplane_id"};
const class matador::query::column col2 = {&ap, "id"};
const auto result = query::select({"f.id", "ap.brand", "f.pilot_name"})
.from({"flight", "f"})
.join_left({"airplane", "ap"})
.on("f.airplane_id"_col == "ap.id"_col)
.from(table{"flight"}.as("f"))
.join_left(table{"airplane"}.as("ap"))
.on(col1 == col2)
.str(*db);
REQUIRE(result == R"(SELECT "f"."id", "ap"."brand", "f"."pilot_name" FROM "flight" "f" LEFT JOIN "airplane" "ap" ON "f"."airplane_id" = "ap"."id")");
+3 -3
View File
@@ -26,7 +26,7 @@ TEST_CASE("Generate columns from object", "[column][generator]") {
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
connection_pool pool("noop://noop.db", 4);
schema s(pool);
schema s;
auto result = s.attach<product>("product");
REQUIRE( result );
@@ -56,7 +56,7 @@ TEST_CASE("Generate columns for object with has many relation", "[column][genera
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
connection_pool pool("noop://noop.db", 4);
schema s(pool);
schema s;
auto result = s.attach<supplier>("supplier")
.and_then( [&s] { return s.attach<category>("categories"); } )
.and_then( [&s] { return s.attach<order_details>("order_details"); } )
@@ -99,7 +99,7 @@ TEST_CASE("Generate columns for object with eager foreign key relation", "[colum
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
connection_pool pool("noop://noop.db", 4);
schema s(pool);
schema s;
auto result = s.attach<book>("books")
.and_then( [&s] { return s.attach<author>("authors"); } );
REQUIRE(result);