collection has-many-to-many resolve progress

This commit is contained in:
Sascha Kühl
2026-02-03 15:36:58 +01:00
parent 73abd61eba
commit 4d886f0343
7 changed files with 135 additions and 45 deletions
+36 -16
View File
@@ -821,6 +821,10 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many to many rel
.and_then( [this] { return repo.attach<recipe>("recipes"); } )
.and_then([this] {return repo.create(db); });
REQUIRE(result.is_ok());
repo.initialize_executor(db);
REQUIRE(db.exists(RECIPE.table_name()));
REQUIRE(db.exists(INGREDIENT.table_name()));
REQUIRE(db.exists(RECIPE_INGREDIENT.table_name()));
@@ -845,9 +849,9 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many to many rel
}
std::vector<recipe> recipes{
{7, "Apple Crumble"},
{8, "Beans Chili"},
{9, "Fruit Salad"}
{8, "Apple Crumble"},
{9, "Beans Chili"},
{10, "Fruit Salad"}
};
for (const auto &r: recipes) {
@@ -860,14 +864,14 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many to many rel
}
std::vector<std::pair<int, int>> recipe_ingredients {
{ 7, 1 },
{ 7, 4 },
{ 7, 5 },
{ 8, 6 },
{ 8, 7 },
{ 9, 1 },
{ 9, 2 },
{ 9, 3 }
{ 8, 1 },
{ 8, 4 },
{ 8, 5 },
{ 9, 6 },
{ 9, 7 },
{ 10, 1 },
{ 10, 2 },
{ 10, 3 }
};
for (const auto & [recipe_id, ingredient_id]: recipe_ingredients) {
@@ -883,15 +887,31 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many to many rel
const auto ri= RECIPE_INGREDIENT.as("ri");
const auto i = INGREDIENT.as("i");
auto ingredients_result = query::select({r.id, r.name, ri.ingredient_id, i.name})
auto recipes_result = query::select({r.id, r.name })
.from(r)
.join_left(ri).on(r.id == ri.recipe_id)
.join_left(i).on(ri.ingredient_id == i.id)
.order_by({r.id}).asc()
.fetch_all<recipe>(db);
REQUIRE(recipes_result.is_ok());
for (const auto &reps : *recipes_result) {
REQUIRE(!reps->ingredients.empty());
for (const auto &ingr : reps->ingredients) {
std::cout << ingr->name << " (" << reps->name << ")" << std::endl;
}
}
auto ingredients_result = query::select({i.id, i.name, ri.recipe_id, r.name})
.from(i)
.join_left(ri).on(i.id == ri.ingredient_id)
.join_left(r).on(ri.recipe_id == r.id)
.order_by({i.id, r.id}).asc()
.fetch_all<ingredient>(db);
REQUIRE(ingredients_result.is_ok());
for (const auto &ing : *ingredients_result) {
REQUIRE(!ing->recipes.empty());
for (const auto &ingr : *ingredients_result) {
REQUIRE(!ingr->recipes.empty());
for (const auto &recipe : ingr->recipes) {
std::cout << recipe->name << " (" << ingr->name << ")" << std::endl;
}
}
}
+3 -2
View File
@@ -5,6 +5,7 @@
#include "matador/utils/foreign_attributes.hpp"
#include "matador/object/object_ptr.hpp"
#include "matador/object/collection.hpp"
#include "matador/object/many_to_many_relation.hpp"
#include <string>
@@ -15,7 +16,7 @@ struct recipe;
struct ingredient {
unsigned int id{};
std::string name;
std::vector<object::object_ptr<recipe> > recipes{};
object::collection<object::object_ptr<recipe> > recipes{};
ingredient() = default;
@@ -35,7 +36,7 @@ struct ingredient {
struct recipe {
unsigned int id{};
std::string name;
std::vector<object::object_ptr<ingredient> > ingredients{};
object::collection<object::object_ptr<ingredient> > ingredients{};
recipe() = default;