fixed has many and belongs to eager loading via sql join
This commit is contained in:
@@ -19,8 +19,7 @@ struct book {
|
||||
unsigned short published_in{};
|
||||
|
||||
template<typename Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "title", title, 511);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#include <iostream>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/sql/backend_provider.hpp"
|
||||
#include "matador/sql/connection.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include "matador/query/query.hpp"
|
||||
|
||||
@@ -20,6 +23,7 @@
|
||||
|
||||
using namespace matador::object;
|
||||
using namespace matador::orm;
|
||||
using namespace matador::query;
|
||||
using namespace matador::sql;
|
||||
using namespace matador::test;
|
||||
|
||||
@@ -36,7 +40,7 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity
|
||||
auto data = eqb.build<flight>(17U);
|
||||
|
||||
REQUIRE(data.is_ok());
|
||||
REQUIRE(data->root_table_name == "flights");
|
||||
REQUIRE(data->root_table->name == "flights");
|
||||
REQUIRE(data->joins.size() == 1);
|
||||
const std::vector<column> expected_columns {
|
||||
{ "flights", "id", "c01" },
|
||||
@@ -51,7 +55,7 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
||||
{ "airplanes", R"("flights"."airplane_id" = "airplanes"."id")"}
|
||||
{ "airplanes", R"("t01"."airplane_id" = "t02"."id")"}
|
||||
};
|
||||
|
||||
query_context qc;
|
||||
@@ -81,7 +85,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||
auto data = eqb.build<book>(17);
|
||||
|
||||
REQUIRE(data.is_ok());
|
||||
REQUIRE(data->root_table_name == "books");
|
||||
REQUIRE(data->root_table->name == "books");
|
||||
REQUIRE(data->joins.size() == 1);
|
||||
const std::vector<column> expected_columns {
|
||||
{ "books", "id", "c01" },
|
||||
@@ -100,7 +104,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
||||
{ "authors", R"("books"."author_id" = "authors"."id")"}
|
||||
{ "authors", R"("t01"."author_id" = "t02"."id")"}
|
||||
};
|
||||
|
||||
query_context qc;
|
||||
@@ -116,7 +120,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||
REQUIRE(cond == R"("books"."id" = 17)");
|
||||
|
||||
auto q = matador::query::query::select(data->columns)
|
||||
.from(data->root_table_name);
|
||||
.from(data->root_table->name);
|
||||
|
||||
for (auto &jd : data->joins) {
|
||||
q.join_left(*jd.join_table)
|
||||
@@ -143,7 +147,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
|
||||
auto data = eqb.build<order>(17);
|
||||
|
||||
REQUIRE(data.is_ok());
|
||||
REQUIRE(data->root_table_name == "orders");
|
||||
REQUIRE(data->root_table->name == "orders");
|
||||
REQUIRE(data->joins.size() == 1);
|
||||
const std::vector<column> expected_columns = {
|
||||
{ "orders", "order_id", "c01" },
|
||||
@@ -168,7 +172,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> expected_join_data {
|
||||
{ "order_details", R"("orders"."order_id" = "order_details"."order_id")"}
|
||||
{ "order_details", R"("t01"."order_id" = "t02"."order_id")"}
|
||||
};
|
||||
|
||||
query_context qc;
|
||||
@@ -197,7 +201,7 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
|
||||
auto data = eqb.build<ingredient>(17);
|
||||
|
||||
REQUIRE(data.is_ok());
|
||||
REQUIRE(data->root_table_name == "ingredients");
|
||||
REQUIRE(data->root_table->name == "ingredients");
|
||||
REQUIRE(data->joins.size() == 2);
|
||||
const std::vector<column> expected_columns {
|
||||
{ "ingredients", "id", "c01" },
|
||||
@@ -241,7 +245,7 @@ TEST_CASE("Create sql query data for entity with eager many to many (inverse par
|
||||
auto data = eqb.build<course>(17);
|
||||
|
||||
REQUIRE(data.is_ok());
|
||||
REQUIRE(data->root_table_name == "courses");
|
||||
REQUIRE(data->root_table->name == "courses");
|
||||
REQUIRE(data->joins.size() == 2);
|
||||
const std::vector<column> expected_columns {
|
||||
{ "courses", "id", "c01" },
|
||||
@@ -270,4 +274,64 @@ TEST_CASE("Create sql query data for entity with eager many to many (inverse par
|
||||
REQUIRE(data->where_clause);
|
||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||
REQUIRE(cond == R"("courses"."id" = 17)");
|
||||
}
|
||||
|
||||
namespace matador::test::orm {
|
||||
|
||||
struct employee;
|
||||
|
||||
struct department {
|
||||
unsigned int id{};
|
||||
std::string name;
|
||||
std::vector<object_ptr<employee>> employees;
|
||||
|
||||
template<typename Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "name", name, 63);
|
||||
field::has_many(op, "employees", employees, "dep_id", utils::fetch_type::EAGER);
|
||||
}
|
||||
};
|
||||
|
||||
struct employee {
|
||||
unsigned int id{};
|
||||
std::string first_name;
|
||||
std::string last_name;
|
||||
object_ptr<department> dep;
|
||||
|
||||
template<typename Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "first_name", first_name, 63);
|
||||
field::attribute(op, "last_name", last_name, 63);
|
||||
field::belongs_to(op, "dep_id", dep, utils::fetch_type::EAGER);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Test eager relationship", "[session][eager]") {
|
||||
using namespace matador::test;
|
||||
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
|
||||
connection db("noop://noop.db");
|
||||
schema scm("noop");
|
||||
auto result = scm.attach<orm::department>("departments")
|
||||
.and_then( [&scm] { return scm.attach<orm::employee>("employees"); } );
|
||||
|
||||
session_query_builder eqb(scm);
|
||||
|
||||
auto data = eqb.build<orm::department>();
|
||||
REQUIRE(data.is_ok());
|
||||
|
||||
auto ctx = query::select(data->columns)
|
||||
.from(*data->root_table)
|
||||
.join_left(data->joins)
|
||||
.where(std::move(data->where_clause))
|
||||
.order_by(column{data->root_table, data->pk_column_name})
|
||||
.asc()
|
||||
.str(db);
|
||||
|
||||
std::cout << ctx << std::endl;
|
||||
}
|
||||
Reference in New Issue
Block a user