From 602b77e67b3a642e73a3273b01d546ae4894a27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Wed, 28 Jan 2026 16:09:54 +0100 Subject: [PATCH] collection_resolver progress --- backends/postgres/src/postgres_connection.cpp | 2 +- backends/postgres/src/postgres_statement.cpp | 2 +- .../object/abstract_type_resolver_factory.hpp | 2 +- include/matador/object/collection.hpp | 2 +- include/matador/object/collection_proxy.hpp | 9 ------- .../object/collection_resolver_factory.hpp | 4 +-- .../object/object_resolver_factory.hpp | 3 +-- include/matador/orm/session.hpp | 9 ++++--- include/matador/query/basic_schema.hpp | 13 ++++----- .../query/intermediates/fetchable_query.hpp | 4 +-- include/matador/query/schema.hpp | 1 - include/matador/sql/connection.hpp | 10 ++++--- include/matador/sql/executor.hpp | 4 +-- .../sql/internal/query_result_impl.hpp | 19 ++++++++----- .../matador/sql/producer_resolver_factory.hpp | 10 +++---- include/matador/sql/query_context.hpp | 5 ++-- include/matador/sql/resolver_service.hpp | 27 +++++++++++++++++++ include/matador/sql/statement.hpp | 4 +-- source/orm/CMakeLists.txt | 2 ++ source/orm/orm/session.cpp | 8 +++--- source/orm/query/basic_schema.cpp | 4 +-- .../query/intermediates/fetchable_query.cpp | 6 ++--- .../orm/query/internal/query_result_impl.cpp | 4 +-- source/orm/sql/connection.cpp | 16 +++++------ source/orm/sql/producer_resolver_factory.cpp | 4 +-- source/orm/sql/resolver_service.cpp | 10 +++++++ test/backends/QueryTest.cpp | 7 +++-- test/models/author.hpp | 3 ++- test/models/department.hpp | 3 ++- test/orm/backend/test_connection.cpp | 2 +- test/orm/backend/test_statement.cpp | 2 +- 31 files changed, 122 insertions(+), 79 deletions(-) create mode 100644 include/matador/sql/resolver_service.hpp create mode 100644 source/orm/sql/resolver_service.cpp diff --git a/backends/postgres/src/postgres_connection.cpp b/backends/postgres/src/postgres_connection.cpp index 9b02188..b8c00e8 100644 --- a/backends/postgres/src/postgres_connection.cpp +++ b/backends/postgres/src/postgres_connection.cpp @@ -111,7 +111,7 @@ utils::result, utils::error> postgres_co return utils::ok(std::make_unique(std::make_unique(res), std::move(prototype), - context.resolver_factory)); + context.resolver)); } std::string postgres_connection::generate_statement_name(const sql::query_context &query) { diff --git a/backends/postgres/src/postgres_statement.cpp b/backends/postgres/src/postgres_statement.cpp index b104a5e..38b84b4 100644 --- a/backends/postgres/src/postgres_statement.cpp +++ b/backends/postgres/src/postgres_statement.cpp @@ -60,7 +60,7 @@ utils::result, utils::error> postgres_st return utils::failure(make_error(sql::error_code::FETCH_FAILED, res, db_, "Failed to fetch statement", query_.sql)); } - return utils::ok(std::make_unique(std::make_unique(res), query_.prototype, query_.resolver_factory)); + return utils::ok(std::make_unique(std::make_unique(res), query_.prototype, query_.resolver)); } std::unique_ptr postgres_statement::create_binder() const { diff --git a/include/matador/object/abstract_type_resolver_factory.hpp b/include/matador/object/abstract_type_resolver_factory.hpp index 6f36fc4..4dc995e 100644 --- a/include/matador/object/abstract_type_resolver_factory.hpp +++ b/include/matador/object/abstract_type_resolver_factory.hpp @@ -10,7 +10,7 @@ class abstract_type_resolver_factory { public: virtual ~abstract_type_resolver_factory() = default; - virtual std::shared_ptr acquire_object_resolver(const std::type_index &type) = 0; + [[nodiscard]] virtual std::shared_ptr acquire_object_resolver(const std::type_index &type) const = 0; virtual void register_object_resolver(std::shared_ptr &&resolver) = 0; }; } diff --git a/include/matador/object/collection.hpp b/include/matador/object/collection.hpp index 49a6c10..dcd730a 100644 --- a/include/matador/object/collection.hpp +++ b/include/matador/object/collection.hpp @@ -45,7 +45,7 @@ public: } [[nodiscard]] bool empty() const { - return proxy_->items_.empty(); + return proxy_->items().empty(); } void reset(std::shared_ptr> proxy) { diff --git a/include/matador/object/collection_proxy.hpp b/include/matador/object/collection_proxy.hpp index 38e1a38..16f2f97 100644 --- a/include/matador/object/collection_proxy.hpp +++ b/include/matador/object/collection_proxy.hpp @@ -3,7 +3,6 @@ #include -#include "matador/object/object_ptr.hpp" #include "matador/object/collection_resolver.hpp" #include "matador/utils/identifier.hpp" @@ -13,14 +12,6 @@ namespace matador::object { -// template -// class collection_resolver : public abstract_collection_resolver { -// public: -// collection_resolver() : abstract_collection_resolver(typeid(Type)) {} -// -// virtual std::shared_ptr resolve(const utils::identifier& id) = 0; -// }; - template class collection_proxy final { public: diff --git a/include/matador/object/collection_resolver_factory.hpp b/include/matador/object/collection_resolver_factory.hpp index 3548579..b01d06a 100644 --- a/include/matador/object/collection_resolver_factory.hpp +++ b/include/matador/object/collection_resolver_factory.hpp @@ -8,14 +8,14 @@ class abstract_collection_resolver_factory { public: virtual ~abstract_collection_resolver_factory() = default; - virtual std::shared_ptr acquire_collection_resolver(const std::type_index &root_type, const std::type_index &element_type, const std::string &collection_name) = 0; + [[nodiscard]] virtual std::shared_ptr acquire_collection_resolver(const std::type_index &root_type, const std::type_index &element_type, const std::string &collection_name) const = 0; virtual void register_collection_resolver(std::shared_ptr &&resolver) = 0; }; class collection_resolver_factory : public abstract_collection_resolver_factory { public: template - std::shared_ptr> resolver(const std::type_index &root_type, const std::string &collection_name) { + [[nodiscard]] std::shared_ptr> resolver(const std::type_index &root_type, const std::string &collection_name) const { const auto res = acquire_collection_resolver(typeid(Type), root_type, collection_name); if (!res) { return std::dynamic_pointer_cast>(res); diff --git a/include/matador/object/object_resolver_factory.hpp b/include/matador/object/object_resolver_factory.hpp index 4609696..2ad37fe 100644 --- a/include/matador/object/object_resolver_factory.hpp +++ b/include/matador/object/object_resolver_factory.hpp @@ -3,13 +3,12 @@ #include "matador/object/abstract_type_resolver_factory.hpp" #include "matador/object/object_resolver.hpp" -#include "matador/object/collection_resolver_factory.hpp" namespace matador::object { class object_resolver_factory : public abstract_type_resolver_factory { public: template - std::shared_ptr> resolver() { + [[nodiscard]] std::shared_ptr> resolver() const { const auto res = acquire_object_resolver(std::type_index(typeid(Type))); if (!res) { return std::dynamic_pointer_cast>(res); diff --git a/include/matador/orm/session.hpp b/include/matador/orm/session.hpp index 67e44e4..73835ce 100644 --- a/include/matador/orm/session.hpp +++ b/include/matador/orm/session.hpp @@ -12,6 +12,7 @@ #include "matador/sql/connection.hpp" #include "matador/sql/connection_pool.hpp" #include "matador/sql/executor.hpp" +#include "matador/sql/resolver_service.hpp" #include "matador/sql/statement.hpp" #include "matador/sql/statement_cache.hpp" @@ -34,7 +35,7 @@ struct session_context { std::string dns; size_t connection_count{}; size_t cache_size{500}; - std::shared_ptr resolver_factory = std::make_shared(); + std::shared_ptr resolver_service = std::make_shared(); }; class prototype_builder final { @@ -140,8 +141,8 @@ public: [[nodiscard]] utils::result prepare(const sql::query_context &ctx) override; [[nodiscard]] std::string str(const sql::query_context &ctx) const override; [[nodiscard]] const sql::dialect &dialect() const override; - [[nodiscard]] std::shared_ptr resolver_factory() const override; - [[nodiscard]] const class query::basic_schema &schema() const; + [[nodiscard]] std::shared_ptr resolver() const override; + [[nodiscard]] const query::basic_schema &schema() const; private: friend class query_select; @@ -155,7 +156,7 @@ private: const query::basic_schema &schema_; mutable std::unordered_map > prototypes_; - std::shared_ptr resolver_factory_; + std::shared_ptr resolver_service_; }; template diff --git a/include/matador/query/basic_schema.hpp b/include/matador/query/basic_schema.hpp index e7057b1..968a907 100644 --- a/include/matador/query/basic_schema.hpp +++ b/include/matador/query/basic_schema.hpp @@ -1,16 +1,17 @@ #ifndef MATADOR_BASIC_SCHEMA_HPP #define MATADOR_BASIC_SCHEMA_HPP -#include "matador/object/repository.hpp" +#include +#include +#include -#include "matador/sql/internal/collection_resolver_producer.hpp" -#include "matador/sql/producer_resolver_factory.hpp" +#include "matador/object/repository.hpp" #include "matador/query/table.hpp" -#include -#include -#include +#include "matador/sql/internal/collection_resolver_producer.hpp" +#include "matador/sql/internal/object_resolver_producer.hpp" +#include "matador/sql/producer_resolver_factory.hpp" namespace matador::query { class schema_node final { diff --git a/include/matador/query/intermediates/fetchable_query.hpp b/include/matador/query/intermediates/fetchable_query.hpp index 0055b5c..6c8a144 100644 --- a/include/matador/query/intermediates/fetchable_query.hpp +++ b/include/matador/query/intermediates/fetchable_query.hpp @@ -32,7 +32,7 @@ public: } const auto prototype = result.value()->prototype(); - auto resolver = exec.resolver_factory()->resolver(); + auto resolver = exec.resolver()->object_resolver(); return utils::ok(sql::query_result(result.release(), resolver, [prototype] { return sql::detail::create_prototype(prototype); })); @@ -48,7 +48,7 @@ public: } const auto prototype = result.value()->prototype(); - auto resolver = exec.resolver_factory()->resolver(); + auto resolver = exec.resolver()->object_resolver(); auto objects = sql::query_result(result.release(), resolver, [prototype] { return sql::detail::create_prototype(prototype); }); diff --git a/include/matador/query/schema.hpp b/include/matador/query/schema.hpp index e1f2427..2493bfd 100644 --- a/include/matador/query/schema.hpp +++ b/include/matador/query/schema.hpp @@ -193,7 +193,6 @@ public: template void on_has_many(const char * /*id*/, CollectionType &cont, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t::value> * = nullptr) { - // SELECT id FROM books where author_id = ?; const auto it = schema_.find(typeid(typename CollectionType::value_type::value_type)); if (it == schema_.end()) { throw query_builder_exception{query_build_error::UnknownType}; diff --git a/include/matador/sql/connection.hpp b/include/matador/sql/connection.hpp index 20e3cec..ff5f2d6 100644 --- a/include/matador/sql/connection.hpp +++ b/include/matador/sql/connection.hpp @@ -6,6 +6,7 @@ #include "matador/sql/abstract_sql_logger.hpp" #include "matador/sql/connection_info.hpp" #include "matador/sql/executor.hpp" +#include "matador/sql/resolver_service.hpp" #include "matador/sql/statement.hpp" #include @@ -26,7 +27,8 @@ public: * @param sql_logger The logging handler */ explicit connection(const connection_info& info, logger_ptr sql_logger = null_logger); - explicit connection(const connection_info& info, std::shared_ptr resolver_factory, logger_ptr sql_logger = null_logger); + explicit connection(const connection_info& info, + const std::shared_ptr &resolver, logger_ptr sql_logger = null_logger); /** * @brief Creates a database connection from a connection string. * @@ -34,7 +36,7 @@ public: * @param sql_logger The logging handler */ explicit connection(const std::string &dns, const logger_ptr &sql_logger = null_logger); - explicit connection(const std::string &dns, std::shared_ptr resolver_factory, const logger_ptr &sql_logger = null_logger); + explicit connection(const std::string &dns, const std::shared_ptr& resolver, const logger_ptr &sql_logger = null_logger); /** * Copies a given connection * @@ -140,7 +142,7 @@ public: [[nodiscard]] std::string str( const query_context& ctx ) const override; [[nodiscard]] const class dialect &dialect() const override; - [[nodiscard]] std::shared_ptr resolver_factory() const override; + [[nodiscard]] std::shared_ptr resolver() const override; private: [[nodiscard]] utils::result, utils::error> perform_prepare(const query_context &ctx) const; @@ -152,7 +154,7 @@ private: std::unique_ptr connection_; std::shared_ptr logger_ = std::make_shared(); - std::shared_ptr resolver_factory_ = std::make_shared(); + std::shared_ptr resolver_service_ = std::make_shared(); }; } diff --git a/include/matador/sql/executor.hpp b/include/matador/sql/executor.hpp index 9c10fae..3967609 100644 --- a/include/matador/sql/executor.hpp +++ b/include/matador/sql/executor.hpp @@ -1,7 +1,7 @@ #ifndef EXECUTOR_HPP #define EXECUTOR_HPP -#include "matador/sql/producer_resolver_factory.hpp" +#include "matador/sql/resolver_service.hpp" #include "matador/utils/error.hpp" #include "matador/utils/result.hpp" @@ -22,7 +22,7 @@ public: [[nodiscard]] virtual utils::result, utils::error> fetch(const query_context &ctx) const = 0; [[nodiscard]] virtual utils::result prepare(const query_context &ctx) = 0; [[nodiscard]] virtual std::string str(const query_context &ctx) const = 0; - [[nodiscard]] virtual std::shared_ptr resolver_factory() const = 0; + [[nodiscard]] virtual std::shared_ptr resolver() const = 0; }; } diff --git a/include/matador/sql/internal/query_result_impl.hpp b/include/matador/sql/internal/query_result_impl.hpp index 5c98d35..0fdcc6f 100644 --- a/include/matador/sql/internal/query_result_impl.hpp +++ b/include/matador/sql/internal/query_result_impl.hpp @@ -11,12 +11,13 @@ #include "matador/sql/interface/query_result_reader.hpp" #include "matador/sql/internal/query_result_pk_resolver.hpp" #include "matador/sql/internal/identifier_reader.hpp" +#include "matador/sql/resolver_service.hpp" #include "matador/sql/record.hpp" #include "matador/object/attribute.hpp" #include "matador/object/object_proxy.hpp" #include "matador/object/object_ptr.hpp" -#include "matador/object/object_resolver_factory.hpp" +#include "matador/object/collection_proxy.hpp" #include #include @@ -76,7 +77,7 @@ class query_result_impl { public: query_result_impl(std::unique_ptr &&reader, std::vector prototype, - const std::shared_ptr& resolver_factory, + const std::shared_ptr& resolver, size_t column_index = 0); template @@ -124,10 +125,12 @@ public: } template - void on_has_many(const char * /*id*/, CollectionType &cont, const char * /*join_column*/, const utils::foreign_attributes &attr, std::enable_if_t::value> * = nullptr) { + void on_has_many(const char * /*id*/, CollectionType &cont, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t::value> * = nullptr) { using value_type = typename CollectionType::value_type::value_type; - auto resolver = resolver_factory_->resolver(); + auto resolver = resolver_->collection_resolver(type_stack_.top(), join_column); + auto object_resolver = resolver_->object_resolver(); + std::vector objects; if (attr.fetch() == utils::fetch_type::Lazy) { // pk_reader_.read(*id, column_index_++); @@ -137,12 +140,14 @@ public: type_stack_.push(ti); access::process(*this, *obj); type_stack_.pop(); - auto ptr = typename CollectionType::value_type(std::make_shared>(resolver, obj)); + auto ptr = typename CollectionType::value_type(std::make_shared>(object_resolver, obj)); const auto pk = ptr.primary_key(); if (ptr.primary_key().is_valid()) { cont.push_back(ptr); } } + // auto cp = std::make_shared>(resolver, objects); + // cont.reset(); } template @@ -203,7 +208,7 @@ private: template void on_foreign_key(Pointer &x, const utils::foreign_attributes &attr) { - const auto resolver = resolver_factory_->resolver(); + const auto resolver = resolver_->object_resolver(); if (attr.fetch() == utils::fetch_type::Lazy) { typename Pointer::value_type obj; auto pk = id_reader_.read(obj, column_index_++); @@ -222,7 +227,7 @@ protected: size_t column_index_ = 0; std::vector prototype_; std::unique_ptr reader_; - std::shared_ptr resolver_factory_; + std::shared_ptr resolver_; internal::identifier_reader id_reader_; detail::pk_reader pk_reader_; std::stack type_stack_; diff --git a/include/matador/sql/producer_resolver_factory.hpp b/include/matador/sql/producer_resolver_factory.hpp index 9fa0d98..4889dba 100644 --- a/include/matador/sql/producer_resolver_factory.hpp +++ b/include/matador/sql/producer_resolver_factory.hpp @@ -5,14 +5,14 @@ #include "matador/object/abstract_collection_resolver.hpp" #include "matador/object/object_resolver_factory.hpp" -#include "matador/sql/internal/object_resolver_producer.hpp" +#include "matador/object/collection_resolver_factory.hpp" namespace matador::sql { class executor; class producer_resolver_factory : public object::object_resolver_factory { public: - std::shared_ptr acquire_object_resolver(const std::type_index &type) override; + [[nodiscard]] std::shared_ptr acquire_object_resolver(const std::type_index &type) const override; void register_object_resolver(std::shared_ptr &&resolver) override; private: @@ -48,9 +48,9 @@ struct composite_key_hash { class producer_collection_resolver_factory : public object::collection_resolver_factory { public: - std::shared_ptr acquire_collection_resolver(const std::type_index& root_type, - const std::type_index& element_type, - const std::string& collection_name) override; + [[nodiscard]] std::shared_ptr acquire_collection_resolver(const std::type_index& root_type, + const std::type_index& element_type, + const std::string& collection_name) const override; void register_collection_resolver(std::shared_ptr&& resolver) override; private: diff --git a/include/matador/sql/query_context.hpp b/include/matador/sql/query_context.hpp index 1a9b6ab..55a1c17 100644 --- a/include/matador/sql/query_context.hpp +++ b/include/matador/sql/query_context.hpp @@ -2,7 +2,8 @@ #define QUERY_QUERY_DATA_HPP #include "matador/object/attribute.hpp" -#include "matador/object/object_resolver_factory.hpp" + +#include "matador/sql/resolver_service.hpp" #include "matador/utils/types.hpp" @@ -40,7 +41,7 @@ struct query_context { std::vector prototype{}; std::vector bind_vars{}; std::vector bind_types{}; - std::shared_ptr resolver_factory{}; + std::shared_ptr resolver{}; }; } diff --git a/include/matador/sql/resolver_service.hpp b/include/matador/sql/resolver_service.hpp new file mode 100644 index 0000000..d38872d --- /dev/null +++ b/include/matador/sql/resolver_service.hpp @@ -0,0 +1,27 @@ +#ifndef MATADOR_RESOLVER_SERVICE_HPP +#define MATADOR_RESOLVER_SERVICE_HPP + +#include "matador/sql/producer_resolver_factory.hpp" + +namespace matador::sql { +class resolver_service { +public: + template + std::shared_ptr> object_resolver() const { + return object_resolver_factory_.resolver(); + } + + template + std::shared_ptr> collection_resolver(const std::type_index &root_type, const std::string &collection_name) const { + return collection_resolver_factory_.resolver(root_type, collection_name); + } + + void register_object_resolver(std::shared_ptr &&resolver); + void register_collection_resolver(std::shared_ptr&& resolver); + +private: + sql::producer_resolver_factory object_resolver_factory_; + sql::producer_collection_resolver_factory collection_resolver_factory_; +}; +} +#endif // MATADOR_RESOLVER_SERVICE_HPP diff --git a/include/matador/sql/statement.hpp b/include/matador/sql/statement.hpp index b641f89..cc71ab5 100644 --- a/include/matador/sql/statement.hpp +++ b/include/matador/sql/statement.hpp @@ -165,7 +165,7 @@ template utils::result, utils::error> statement::fetch() { std::cout << statement_proxy_->sql() << std::endl; return statement_proxy_->fetch(*bindings_).and_then([this](std::unique_ptr &&value) { - auto resolver = statement_proxy_->statement_->query_.resolver_factory->resolver(); + auto resolver = statement_proxy_->statement_->query_.resolver->object_resolver(); const auto prototype = value->prototype(); return utils::ok(query_result(std::forward(value), resolver, [prototype] { return detail::create_prototype(prototype); @@ -180,7 +180,7 @@ utils::result, utils::error> statement::fetch_one() { if (!result.is_ok()) { return utils::failure(result.err()); } - auto resolver = statement_proxy_->statement_->query_.resolver_factory->resolver(); + auto resolver = statement_proxy_->statement_->query_.resolver->object_resolver(); const auto prototype = result.value()->prototype(); auto records = query_result(result.release(), resolver, [prototype] { return detail::create_prototype(prototype); diff --git a/source/orm/CMakeLists.txt b/source/orm/CMakeLists.txt index 8bbb749..b067148 100644 --- a/source/orm/CMakeLists.txt +++ b/source/orm/CMakeLists.txt @@ -95,6 +95,7 @@ add_library(matador-orm STATIC ../../include/matador/sql/query_record_result.hpp ../../include/matador/sql/query_result.hpp ../../include/matador/sql/record.hpp + ../../include/matador/sql/resolver_service.hpp ../../include/matador/sql/sql_functions.hpp ../../include/matador/sql/statement.hpp ../../include/matador/sql/statement_cache.hpp @@ -182,6 +183,7 @@ add_library(matador-orm STATIC sql/producer_resolver_factory.cpp sql/query_result.cpp sql/record.cpp + sql/resolver_service.cpp sql/statement.cpp sql/statement_cache.cpp ) diff --git a/source/orm/orm/session.cpp b/source/orm/orm/session.cpp index b931d3e..3f5a62c 100644 --- a/source/orm/orm/session.cpp +++ b/source/orm/orm/session.cpp @@ -14,11 +14,11 @@ utils::error make_error(const error_code ec, const std::string &msg) { } session::session(session_context&& ctx, const query::schema &scm) -: pool_(ctx.dns, ctx.connection_count, [ctx](const sql::connection_info& info) { return sql::connection(info, ctx.resolver_factory); }) +: pool_(ctx.dns, ctx.connection_count, [ctx](const sql::connection_info& info) { return sql::connection(info, ctx.resolver_service); }) , cache_(ctx.bus, pool_, ctx.cache_size) , dialect_(sql::backend_provider::instance().connection_dialect(pool_.info().type)) , schema_(scm) -, resolver_factory_(ctx.resolver_factory) { +, resolver_service_(ctx.resolver_service) { } utils::result session::drop_table(const std::string &table_name) const { @@ -85,8 +85,8 @@ const class sql::dialect &session::dialect() const { return dialect_; } -std::shared_ptr session::resolver_factory() const { - return resolver_factory_; +std::shared_ptr session::resolver() const { + return resolver_service_; } const query::basic_schema & session::schema() const { diff --git a/source/orm/query/basic_schema.cpp b/source/orm/query/basic_schema.cpp index e801ed2..9d43b04 100644 --- a/source/orm/query/basic_schema.cpp +++ b/source/orm/query/basic_schema.cpp @@ -85,13 +85,13 @@ void basic_schema::initialize_executor(sql::executor &exec) const { auto factory = std::make_shared(); for (const auto &[key, producer] : resolver_producers_) { auto resolver = producer->produce(exec); - exec.resolver_factory()->register_object_resolver(std::move(resolver)); + exec.resolver()->register_object_resolver(std::move(resolver)); } auto collection_factory = std::make_shared(); for (const auto &[key, producer] : collection_resolver_producers_) { auto resolver = producer->produce(exec); - // exec.resolver_factory()->register_collection_resolver(std::move(resolver)); + exec.resolver()->register_collection_resolver(std::move(resolver)); } } diff --git a/source/orm/query/intermediates/fetchable_query.cpp b/source/orm/query/intermediates/fetchable_query.cpp index 8d26fad..04e1e1f 100644 --- a/source/orm/query/intermediates/fetchable_query.cpp +++ b/source/orm/query/intermediates/fetchable_query.cpp @@ -39,7 +39,7 @@ utils::result, utils::error> fetchable_query::fet utils::result, utils::error> fetchable_query::fetch_one(const sql::executor &exec) const { query_builder compiler; auto ctx = compiler.compile(*context_, exec.dialect(), std::nullopt); - ctx.resolver_factory = exec.resolver_factory(); + ctx.resolver = exec.resolver(); auto result = exec.fetch(ctx); if (!result.is_ok()) { return utils::failure(result.err()); @@ -69,13 +69,13 @@ sql::query_context fetchable_query::compile(const sql::dialect &d) const { utils::result, utils::error> fetchable_query::fetch(const sql::executor &exec) const { auto ctx = compile(exec.dialect()); - ctx.resolver_factory = exec.resolver_factory(); + ctx.resolver = exec.resolver(); return exec.fetch(ctx); } utils::result fetchable_query::prepare(sql::executor &exec) const { auto ctx = compile(exec.dialect()); - ctx.resolver_factory = exec.resolver_factory(); + ctx.resolver = exec.resolver(); return exec.prepare(ctx); } diff --git a/source/orm/query/internal/query_result_impl.cpp b/source/orm/query/internal/query_result_impl.cpp index e5c436b..8d4e290 100644 --- a/source/orm/query/internal/query_result_impl.cpp +++ b/source/orm/query/internal/query_result_impl.cpp @@ -9,12 +9,12 @@ detail::pk_reader::pk_reader(query_result_reader &reader) query_result_impl::query_result_impl(std::unique_ptr &&reader, std::vector prototype, - const std::shared_ptr& resolver_factory, + const std::shared_ptr& resolver, const size_t column_index) : column_index_(column_index) , prototype_(std::move(prototype)) , reader_(std::move(reader)) -, resolver_factory_(resolver_factory) +, resolver_(resolver) , id_reader_(*reader_) , pk_reader_(*reader_) { } diff --git a/source/orm/sql/connection.cpp b/source/orm/sql/connection.cpp index 620c6c4..c8b94d8 100644 --- a/source/orm/sql/connection.cpp +++ b/source/orm/sql/connection.cpp @@ -33,10 +33,10 @@ connection::connection(const connection_info& info, logger_ptr sql_logger) } connection::connection(const connection_info &info, - std::shared_ptr resolver_factory, + const std::shared_ptr& resolver, logger_ptr sql_logger) : logger_(std::move(sql_logger)) -, resolver_factory_(std::move(resolver_factory)) { +, resolver_service_(resolver) { connection_.reset(backend_provider::instance().create_connection(info.type, info)); } @@ -45,9 +45,9 @@ connection::connection(const std::string& dns, const logger_ptr &sql_logger) {} connection::connection(const std::string &dns, - std::shared_ptr resolver_factory, + const std::shared_ptr &resolver, const logger_ptr &sql_logger) -: connection(connection_info::parse(dns), std::move(resolver_factory), sql_logger) +: connection(connection_info::parse(dns), std::move(resolver), sql_logger) {} connection::connection(const connection &x) { @@ -70,13 +70,13 @@ connection &connection::operator=(const connection &x) { connection::connection( connection&& x ) noexcept : connection_(std::move(x.connection_)) , logger_(std::move(x.logger_)) -, resolver_factory_(std::move(x.resolver_factory_)) +, resolver_service_(std::move(x.resolver_service_)) {} connection & connection::operator=(connection &&x) noexcept { connection_ = std::move(x.connection_); logger_ = std::move(x.logger_); - resolver_factory_ = std::move(x.resolver_factory_); + resolver_service_ = std::move(x.resolver_service_); return *this; } @@ -233,8 +233,8 @@ const class dialect &connection::dialect() const return connection_->dialect(); } -std::shared_ptr connection::resolver_factory() const { - return resolver_factory_; +std::shared_ptr connection::resolver() const { + return resolver_service_; } utils::result, utils::error> connection::perform_prepare(const query_context& ctx) const { diff --git a/source/orm/sql/producer_resolver_factory.cpp b/source/orm/sql/producer_resolver_factory.cpp index 18f2732..92f3323 100644 --- a/source/orm/sql/producer_resolver_factory.cpp +++ b/source/orm/sql/producer_resolver_factory.cpp @@ -1,7 +1,7 @@ #include "matador/sql/producer_resolver_factory.hpp" namespace matador::sql { -std::shared_ptr producer_resolver_factory::acquire_object_resolver(const std::type_index &type) { +std::shared_ptr producer_resolver_factory::acquire_object_resolver(const std::type_index &type) const { if (const auto it = resolvers_.find(type); it != resolvers_.end()) { return it->second; } @@ -14,7 +14,7 @@ void producer_resolver_factory::register_object_resolver(std::shared_ptr producer_collection_resolver_factory::acquire_collection_resolver(const std::type_index& root_type, const std::type_index& element_type, - const std::string& collection_name) { + const std::string& collection_name) const { const composite_key key{root_type, element_type, collection_name}; if (const auto it = resolvers_.find(key); it != resolvers_.end()) { return it->second; diff --git a/source/orm/sql/resolver_service.cpp b/source/orm/sql/resolver_service.cpp new file mode 100644 index 0000000..1681201 --- /dev/null +++ b/source/orm/sql/resolver_service.cpp @@ -0,0 +1,10 @@ +#include "matador/sql/resolver_service.hpp" + +namespace matador::sql { +void resolver_service::register_object_resolver(std::shared_ptr&& resolver) { + object_resolver_factory_.register_object_resolver(std::move(resolver)); +} +void resolver_service::register_collection_resolver(std::shared_ptr&& resolver) { + collection_resolver_factory_.register_collection_resolver(std::move(resolver)); +} +} // namespace matador::query \ No newline at end of file diff --git a/test/backends/QueryTest.cpp b/test/backends/QueryTest.cpp index faa151c..9c9472b 100644 --- a/test/backends/QueryTest.cpp +++ b/test/backends/QueryTest.cpp @@ -588,11 +588,14 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation", } TEST_CASE_METHOD(QueryFixture, "Test load entity with lazy has many relation", "[query][has_many][lazy]") { - auto result = repo.attach("authors") - .and_then( [this] { return repo.attach("books"); } ) + // auto result = repo.attach("authors") + // .and_then( [this] { return repo.attach("books"); } ) + auto result = repo.attach("books") + .and_then( [this] { return repo.attach("authors"); } ) .and_then([this] { return repo.create(db); } ); + REQUIRE(result.is_ok()); repo.initialize_executor(db); diff --git a/test/models/author.hpp b/test/models/author.hpp index c6a4b54..7b7e01b 100644 --- a/test/models/author.hpp +++ b/test/models/author.hpp @@ -4,6 +4,7 @@ #include "matador/utils/access.hpp" #include "matador/object/object_ptr.hpp" +#include "matador/object/collection.hpp" #include #include @@ -25,7 +26,7 @@ struct author { std::string date_of_birth; unsigned short year_of_birth{}; bool distinguished{false}; - std::vector > books; + object::collection > books; template void process(Operator &op) { diff --git a/test/models/department.hpp b/test/models/department.hpp index e3aa821..41d699b 100644 --- a/test/models/department.hpp +++ b/test/models/department.hpp @@ -2,6 +2,7 @@ #define DEPARTMENT_EMPLOYEE_HPP #include "matador/object/object_ptr.hpp" +#include "matador/object/collection.hpp" #include #include @@ -16,7 +17,7 @@ struct department { : id(id), name(std::move(name)) {} unsigned int id{}; std::string name; - std::vector> employees{}; + object::collection> employees{}; // object::object_ptr manager; template diff --git a/test/orm/backend/test_connection.cpp b/test/orm/backend/test_connection.cpp index db07042..109683b 100644 --- a/test/orm/backend/test_connection.cpp +++ b/test/orm/backend/test_connection.cpp @@ -51,7 +51,7 @@ utils::result test_connection::execute(const std::string & utils::result, utils::error> test_connection::fetch(const sql::query_context &context) { return utils::ok(std::make_unique(std::make_unique(), context.prototype, - context.resolver_factory, + context.resolver, context.prototype.size())); } diff --git a/test/orm/backend/test_statement.cpp b/test/orm/backend/test_statement.cpp index c664f0e..49a04b7 100644 --- a/test/orm/backend/test_statement.cpp +++ b/test/orm/backend/test_statement.cpp @@ -21,7 +21,7 @@ utils::result test_statement::execute(const sql::parameter utils::result, utils::error> test_statement::fetch(const sql::parameter_binder &/*bindings*/) { return utils::ok(std::make_unique(std::make_unique(), query_.prototype, - query_.resolver_factory, + query_.resolver, query_.prototype.size())); }