collection_resolver progress

This commit is contained in:
Sascha Kühl
2026-01-28 16:09:54 +01:00
parent 6205ae81c9
commit 602b77e67b
31 changed files with 122 additions and 79 deletions
@@ -10,7 +10,7 @@ class abstract_type_resolver_factory {
public:
virtual ~abstract_type_resolver_factory() = default;
virtual std::shared_ptr<abstract_type_resolver> acquire_object_resolver(const std::type_index &type) = 0;
[[nodiscard]] virtual std::shared_ptr<abstract_type_resolver> acquire_object_resolver(const std::type_index &type) const = 0;
virtual void register_object_resolver(std::shared_ptr<abstract_type_resolver> &&resolver) = 0;
};
}
+1 -1
View File
@@ -45,7 +45,7 @@ public:
}
[[nodiscard]] bool empty() const {
return proxy_->items_.empty();
return proxy_->items().empty();
}
void reset(std::shared_ptr<collection_proxy<Type>> proxy) {
@@ -3,7 +3,6 @@
#include <atomic>
#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<typename Type>
// class collection_resolver : public abstract_collection_resolver {
// public:
// collection_resolver() : abstract_collection_resolver(typeid(Type)) {}
//
// virtual std::shared_ptr<Type> resolve(const utils::identifier& id) = 0;
// };
template<typename Type>
class collection_proxy final {
public:
@@ -8,14 +8,14 @@ class abstract_collection_resolver_factory {
public:
virtual ~abstract_collection_resolver_factory() = default;
virtual std::shared_ptr<abstract_collection_resolver> 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<abstract_collection_resolver> 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<abstract_collection_resolver> &&resolver) = 0;
};
class collection_resolver_factory : public abstract_collection_resolver_factory {
public:
template<class Type>
std::shared_ptr<collection_resolver<Type>> resolver(const std::type_index &root_type, const std::string &collection_name) {
[[nodiscard]] std::shared_ptr<collection_resolver<Type>> 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<collection_resolver<Type>>(res);
@@ -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<class Type>
std::shared_ptr<object_resolver<Type>> resolver() {
[[nodiscard]] std::shared_ptr<object_resolver<Type>> resolver() const {
const auto res = acquire_object_resolver(std::type_index(typeid(Type)));
if (!res) {
return std::dynamic_pointer_cast<object_resolver<Type>>(res);
+5 -4
View File
@@ -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<sql::producer_resolver_factory> resolver_factory = std::make_shared<sql::producer_resolver_factory>();
std::shared_ptr<sql::resolver_service> resolver_service = std::make_shared<sql::resolver_service>();
};
class prototype_builder final {
@@ -140,8 +141,8 @@ public:
[[nodiscard]] utils::result<sql::statement, utils::error> 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<sql::producer_resolver_factory> resolver_factory() const override;
[[nodiscard]] const class query::basic_schema &schema() const;
[[nodiscard]] std::shared_ptr<sql::resolver_service> 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<std::string, std::vector<object::attribute> > prototypes_;
std::shared_ptr<sql::producer_resolver_factory> resolver_factory_;
std::shared_ptr<sql::resolver_service> resolver_service_;
};
template<typename Type>
+7 -6
View File
@@ -1,16 +1,17 @@
#ifndef MATADOR_BASIC_SCHEMA_HPP
#define MATADOR_BASIC_SCHEMA_HPP
#include "matador/object/repository.hpp"
#include <memory>
#include <typeindex>
#include <unordered_map>
#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 <unordered_map>
#include <memory>
#include <typeindex>
#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 {
@@ -32,7 +32,7 @@ public:
}
const auto prototype = result.value()->prototype();
auto resolver = exec.resolver_factory()->resolver<Type>();
auto resolver = exec.resolver()->object_resolver<Type>();
return utils::ok(sql::query_result<Type>(result.release(), resolver, [prototype] {
return sql::detail::create_prototype<Type>(prototype);
}));
@@ -48,7 +48,7 @@ public:
}
const auto prototype = result.value()->prototype();
auto resolver = exec.resolver_factory()->resolver<Type>();
auto resolver = exec.resolver()->object_resolver<Type>();
auto objects = sql::query_result<Type>(result.release(), resolver, [prototype] {
return sql::detail::create_prototype<Type>(prototype);
});
-1
View File
@@ -193,7 +193,6 @@ public:
template<class CollectionType>
void on_has_many(const char * /*id*/, CollectionType &cont, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t<object::is_object_ptr<typename CollectionType::value_type>::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};
+6 -4
View File
@@ -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 <string>
@@ -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<producer_resolver_factory> resolver_factory, logger_ptr sql_logger = null_logger);
explicit connection(const connection_info& info,
const std::shared_ptr<resolver_service> &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<producer_resolver_factory> resolver_factory, const logger_ptr &sql_logger = null_logger);
explicit connection(const std::string &dns, const std::shared_ptr<resolver_service>& 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<producer_resolver_factory> resolver_factory() const override;
[[nodiscard]] std::shared_ptr<resolver_service> resolver() const override;
private:
[[nodiscard]] utils::result<std::unique_ptr<statement_impl>, utils::error> perform_prepare(const query_context &ctx) const;
@@ -152,7 +154,7 @@ private:
std::unique_ptr<connection_impl> connection_;
std::shared_ptr<abstract_sql_logger> logger_ = std::make_shared<null_sql_logger>();
std::shared_ptr<producer_resolver_factory> resolver_factory_ = std::make_shared<producer_resolver_factory>();
std::shared_ptr<resolver_service> resolver_service_ = std::make_shared<resolver_service>();
};
}
+2 -2
View File
@@ -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<std::unique_ptr<query_result_impl>, utils::error> fetch(const query_context &ctx) const = 0;
[[nodiscard]] virtual utils::result<statement, utils::error> prepare(const query_context &ctx) = 0;
[[nodiscard]] virtual std::string str(const query_context &ctx) const = 0;
[[nodiscard]] virtual std::shared_ptr<producer_resolver_factory> resolver_factory() const = 0;
[[nodiscard]] virtual std::shared_ptr<resolver_service> resolver() const = 0;
};
}
@@ -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 <memory>
#include <stack>
@@ -76,7 +77,7 @@ class query_result_impl {
public:
query_result_impl(std::unique_ptr<query_result_reader> &&reader,
std::vector<object::attribute> prototype,
const std::shared_ptr<object::object_resolver_factory>& resolver_factory,
const std::shared_ptr<resolver_service>& resolver,
size_t column_index = 0);
template<typename ValueType>
@@ -124,10 +125,12 @@ public:
}
template<class CollectionType>
void on_has_many(const char * /*id*/, CollectionType &cont, const char * /*join_column*/, const utils::foreign_attributes &attr, std::enable_if_t<object::is_object_ptr<typename CollectionType::value_type>::value> * = nullptr) {
void on_has_many(const char * /*id*/, CollectionType &cont, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t<object::is_object_ptr<typename CollectionType::value_type>::value> * = nullptr) {
using value_type = typename CollectionType::value_type::value_type;
auto resolver = resolver_factory_->resolver<value_type>();
auto resolver = resolver_->collection_resolver<value_type>(type_stack_.top(), join_column);
auto object_resolver = resolver_->object_resolver<value_type>();
std::vector<typename CollectionType::value_type> 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<object::object_proxy<value_type>>(resolver, obj));
auto ptr = typename CollectionType::value_type(std::make_shared<object::object_proxy<value_type>>(object_resolver, obj));
const auto pk = ptr.primary_key();
if (ptr.primary_key().is_valid()) {
cont.push_back(ptr);
}
}
// auto cp = std::make_shared<object::collection_proxy<typename CollectionType::value_type>>(resolver, objects);
// cont.reset();
}
template<class CollectionType>
@@ -203,7 +208,7 @@ private:
template<class Pointer>
void on_foreign_key(Pointer &x, const utils::foreign_attributes &attr) {
const auto resolver = resolver_factory_->resolver<typename Pointer::value_type>();
const auto resolver = resolver_->object_resolver<typename Pointer::value_type>();
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<object::attribute> prototype_;
std::unique_ptr<query_result_reader> reader_;
std::shared_ptr<object::object_resolver_factory> resolver_factory_;
std::shared_ptr<sql::resolver_service> resolver_;
internal::identifier_reader id_reader_;
detail::pk_reader pk_reader_;
std::stack<std::type_index> type_stack_;
@@ -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<object::abstract_type_resolver> acquire_object_resolver(const std::type_index &type) override;
[[nodiscard]] std::shared_ptr<object::abstract_type_resolver> acquire_object_resolver(const std::type_index &type) const override;
void register_object_resolver(std::shared_ptr<object::abstract_type_resolver> &&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<object::abstract_collection_resolver> 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<object::abstract_collection_resolver> 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<object::abstract_collection_resolver>&& resolver) override;
private:
+3 -2
View File
@@ -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<object::attribute> prototype{};
std::vector<std::string> bind_vars{};
std::vector<utils::database_type> bind_types{};
std::shared_ptr<object::object_resolver_factory> resolver_factory{};
std::shared_ptr<resolver_service> resolver{};
};
}
+27
View File
@@ -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<class Type>
std::shared_ptr<object::object_resolver<Type>> object_resolver() const {
return object_resolver_factory_.resolver<Type>();
}
template<class Type>
std::shared_ptr<object::collection_resolver<Type>> collection_resolver(const std::type_index &root_type, const std::string &collection_name) const {
return collection_resolver_factory_.resolver<Type>(root_type, collection_name);
}
void register_object_resolver(std::shared_ptr<object::abstract_type_resolver> &&resolver);
void register_collection_resolver(std::shared_ptr<object::abstract_collection_resolver>&& resolver);
private:
sql::producer_resolver_factory object_resolver_factory_;
sql::producer_collection_resolver_factory collection_resolver_factory_;
};
}
#endif // MATADOR_RESOLVER_SERVICE_HPP
+2 -2
View File
@@ -165,7 +165,7 @@ template<class Type>
utils::result<query_result<Type>, utils::error> statement::fetch() {
std::cout << statement_proxy_->sql() << std::endl;
return statement_proxy_->fetch(*bindings_).and_then([this](std::unique_ptr<query_result_impl> &&value) {
auto resolver = statement_proxy_->statement_->query_.resolver_factory->resolver<Type>();
auto resolver = statement_proxy_->statement_->query_.resolver->object_resolver<Type>();
const auto prototype = value->prototype();
return utils::ok(query_result<Type>(std::forward<decltype(value)>(value), resolver, [prototype] {
return detail::create_prototype<Type>(prototype);
@@ -180,7 +180,7 @@ utils::result<object::object_ptr<Type>, utils::error> statement::fetch_one() {
if (!result.is_ok()) {
return utils::failure(result.err());
}
auto resolver = statement_proxy_->statement_->query_.resolver_factory->resolver<Type>();
auto resolver = statement_proxy_->statement_->query_.resolver->object_resolver<Type>();
const auto prototype = result.value()->prototype();
auto records = query_result<Type>(result.release(), resolver, [prototype] {
return detail::create_prototype<Type>(prototype);