From f4e984a2885cc544b2483c9f72e6c01ea882675f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Fri, 3 Apr 2026 19:15:15 +0200 Subject: [PATCH] insert_query_builder has_many progress --- .../matador/query/insert_query_builder.hpp | 15 +++++++-- test/orm/query/InsertQueryBuilderTest.cpp | 33 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/include/matador/query/insert_query_builder.hpp b/include/matador/query/insert_query_builder.hpp index 5a10075..9287b27 100644 --- a/include/matador/query/insert_query_builder.hpp +++ b/include/matador/query/insert_query_builder.hpp @@ -138,8 +138,19 @@ public: void on_has_one(const char * /*id*/, Pointer &obj, const utils::foreign_attributes &attr) { on_foreign_object(obj, attr); } - template - static void on_has_many(const char * /*id*/, Collection &/*con*/, const char * /*join_column*/, const utils::foreign_attributes & ) {} + template + void on_has_many(const char * /*id*/, CollectionType &con, const char *, const utils::foreign_attributes &attr, std::enable_if_t::value> * = nullptr) { + if (!utils::is_cascade_type_set(attr.cascade(), utils::cascade_type::Insert)) { + return; + } + for (auto &obj : con) { + obj.is_persistent() ? build_for(obj) : on_foreign_object(obj, attr); + + } + + } + template + void on_has_many(const char * /*id*/, CollectionType &/*con*/, const char *, const utils::foreign_attributes &/*attr*/, std::enable_if_t::value> * = nullptr) {} template void on_has_many_to_many(const char *id, Collection &container, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes & ) { if (id == nullptr || join_column == nullptr || inverse_join_column == nullptr) { diff --git a/test/orm/query/InsertQueryBuilderTest.cpp b/test/orm/query/InsertQueryBuilderTest.cpp index a749e7b..1c53c94 100644 --- a/test/orm/query/InsertQueryBuilderTest.cpp +++ b/test/orm/query/InsertQueryBuilderTest.cpp @@ -12,6 +12,8 @@ #include "../backend/test_backend_service.hpp" +#include "../../models/author.hpp" +#include "../../models/book.hpp" #include "../../models/airplane.hpp" #include "../../models/flight.hpp" @@ -32,8 +34,8 @@ TEST_CASE("insert query builder test", "[query][insert_query_builder]") { insert_query_builder iqb(scm); - const auto a380 = object_ptr(std::make_shared(1, "Boeing", "A380" )); - auto build_result = iqb.build(a380); + const auto a380 = make_object(1, "Boeing", "A380" ); + auto build_result = iqb.build(a380); REQUIRE(build_result.is_ok()); const auto& stmts = *build_result; @@ -45,3 +47,30 @@ TEST_CASE("insert query builder test", "[query][insert_query_builder]") { const auto sql = std::get(step.query).str(db); REQUIRE(sql == R"(INSERT INTO "airplanes" ("id", "brand", "model") VALUES (1, 'Boeing', 'A380'))"); } + +TEST_CASE("Test insert builder has many", "[query][insert_query_builder][has_many]") { + using namespace matador::test; + backend_provider::instance().register_backend("noop", std::make_unique()); + connection db("noop://noop.db"); + + schema scm; + const auto result = scm.attach("books") + .and_then( [&scm] { return scm.attach("authors"); } ); + REQUIRE(result.is_ok()); + + auto s_king = make_object(1, "Steven", "King", "21.9.1947", 1956, false); + + s_king->books.push_back(make_object(2, "Carrie", object_ptr{}, 1974)); + s_king->books.push_back(make_object(3, "The Shining", object_ptr{}, 1977)); + s_king->books.push_back(make_object(4, "It", object_ptr{}, 1986)); + s_king->books.push_back(make_object(5, "Misery", object_ptr{}, 1987)); + s_king->books.push_back(make_object(6, "The Dark Tower: The Gunslinger", object_ptr{}, 1982)); + + insert_query_builder iqb(scm); + + auto build_result = iqb.build(s_king); + REQUIRE(build_result.is_ok()); + + const auto& stmts = *build_result; + REQUIRE(stmts.size() == 1); +} \ No newline at end of file