has one progress

This commit is contained in:
2026-05-15 15:22:59 +02:00
parent 22f6f71412
commit 57703dfb67
44 changed files with 288 additions and 121 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ public:
on_foreign_key(id, x, attr);
}
template<class Pointer>
void on_has_one(const char *id, Pointer &x, const utils::foreign_attributes &attr) {
void on_has_one(const char *id, Pointer &x, const char * /*join_column*/, const utils::foreign_attributes &attr) {
on_foreign_key(id, x, attr);
}
@@ -1,7 +1,7 @@
#ifndef MATADOR_COLLECTION_RESOLVER_PRODUCER_HPP
#define MATADOR_COLLECTION_RESOLVER_PRODUCER_HPP
#include "matador/object/abstract_collection_resolver.hpp"
#include "matador/object/abstract_joined_resolver.hpp"
#include "matador/sql/query_context.hpp"
@@ -18,7 +18,7 @@ class collection_resolver_producer {
public:
virtual ~collection_resolver_producer() = default;
virtual utils::result<query_context, utils::error> build_query(const dialect& d) = 0;
virtual std::shared_ptr<object::abstract_collection_resolver> produce(statement&& stmt, const resolver_service& rs) = 0;
virtual std::shared_ptr<object::abstract_joined_resolver> produce(statement&& stmt, const resolver_service& rs) = 0;
[[nodiscard]] const std::type_index& root_type() const;
[[nodiscard]] const std::type_index& type() const;
@@ -36,7 +36,7 @@ public:
template < class Pointer >
static void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template < class Pointer >
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
@@ -27,5 +27,24 @@ protected:
private:
std::type_index type_;
};
class joined_object_resolver_producer {
public:
virtual ~joined_object_resolver_producer() = default;
virtual utils::result<query_context, utils::error> build_query(const dialect& d) = 0;
virtual std::shared_ptr<object::abstract_joined_resolver> produce(statement&& stmt) = 0;
[[nodiscard]] const std::type_index& root_type() const;
[[nodiscard]] const std::type_index& type() const;
[[nodiscard]] const std::string& collection_name() const;
protected:
explicit joined_object_resolver_producer(const std::type_index &root_type, const std::type_index &type, std::string collection_name);
private:
std::type_index root_type_;
std::type_index type_;
std::string collection_name_;
};
}
#endif //MATADOR_RESOLVER_PRODUCER_HPP
@@ -38,7 +38,7 @@ public:
template < class Pointer >
static void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template < class Pointer >
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many(const char * /*id*/,
@@ -96,7 +96,7 @@ public:
fk_result_binder_.bind(*x, id, index_++, *binder_);
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
void on_has_one(const char *id, Pointer<Type> &x, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {
fk_result_binder_.bind(*x, id, index_++, *binder_);
}
template<class ContainerType>
+1 -1
View File
@@ -32,7 +32,7 @@ public:
++column_index_;
}
template<class Pointer>
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many(const char * /*id*/, ContainerType &, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
@@ -63,15 +63,9 @@ public:
void on_attribute(const char *id, utils::value &val, const utils::field_attributes &attr);
template<class Pointer>
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr) {
on_foreign_key(x, attr);
}
template<class Pointer>
void on_has_one(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr) {
on_foreign_key(x, attr);
}
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr);
template<class PointerType>
void on_has_one(const char * /*id*/, object::object_ptr<PointerType> &x, const char * /*join_column*/, const utils::foreign_attributes &attr);
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);
template<class CollectionType>
@@ -103,23 +97,6 @@ private:
return resolver.discover(obj);
}
template<class Pointer>
void on_foreign_key(Pointer &x, const utils::foreign_attributes &attr) {
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_++);
x = Pointer(std::make_shared<object::object_proxy<typename Pointer::value_type>>(resolver, pk));
} else {
auto obj = std::make_shared<typename Pointer::value_type>();
const auto ti = std::type_index(typeid(*x));
type_stack_.push(ti);
access::process(*this, *obj);
type_stack_.pop();
x = Pointer(std::make_shared<object::object_proxy<typename Pointer::value_type>>(resolver, obj));
}
}
protected:
size_t column_index_ = 0;
std::vector<object::attribute> prototype_;
@@ -134,6 +111,38 @@ protected:
std::unordered_set<object::collection_composite_key, object::collection_composite_key_hash> initialized_collections_;
};
template <class Pointer>
void query_result_impl::on_belongs_to(const char*, Pointer& x, const utils::foreign_attributes& attr) {
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_++);
x = Pointer(std::make_shared<object::object_proxy<typename Pointer::value_type>>(resolver, pk));
} else {
auto obj = std::make_shared<typename Pointer::value_type>();
const auto ti = std::type_index(typeid(*x));
type_stack_.push(ti);
access::process(*this, *obj);
type_stack_.pop();
x = Pointer(std::make_shared<object::object_proxy<typename Pointer::value_type>>(resolver, obj));
}
}
template <class PointerType>
void query_result_impl::on_has_one(const char*, object::object_ptr<PointerType>& x, const char *join_column, const utils::foreign_attributes& attr) {
const auto resolver = resolver_->collection_resolver<PointerType>(result_type_, join_column);
if (attr.fetch() == utils::fetch_type::Lazy) {
x = object::object_ptr<PointerType>(std::make_shared<object::object_proxy<PointerType>>(resolver, id_reader_.read(x, column_index_++)));
} else {
auto obj = std::make_shared<PointerType>();
const auto ti = std::type_index(typeid(*x));
type_stack_.push(ti);
access::process(*this, *obj);
type_stack_.pop();
x = object::object_ptr<PointerType>(std::make_shared<object::object_proxy<PointerType>>(resolver, obj));
}
}
template <class CollectionType>
void query_result_impl::on_has_many(const char *, CollectionType &cont, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t<object::is_object_ptr<typename CollectionType::value_type>::value> *) {
using value_type = typename CollectionType::value_type::value_type;
@@ -16,7 +16,8 @@ namespace matador::sql::internal {
class query_result_pk_resolver final {
public:
explicit query_result_pk_resolver(query_result_reader &reader) : reader_(reader) {}
explicit query_result_pk_resolver(query_result_reader &reader)
: reader_(reader) {}
template<class Type>
utils::identifier discover(Type &obj) {
@@ -38,16 +39,22 @@ public:
utils::data_type_traits<ValueType>::read_value(reader_, id, column_index_++, value, attr.size());
pk_ = value;
}
void on_revision(const char * /*id*/, uint64_t &/*rev*/) { ++column_index_; }
void on_revision(const char * /*id*/, uint64_t &/*rev*/) {
++column_index_;
}
template < class Type >
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/) { ++column_index_; }
void on_attribute(const char *id, const utils::value &x, const utils::field_attributes &attr);
template < class Pointer >
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &attr) { on_foreign_key<typename Pointer::value_type>(attr.fetch() ); }
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &attr) {
on_foreign_key<typename Pointer::value_type>(attr.fetch() );
}
template < class Pointer >
void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &attr) { on_foreign_key<typename Pointer::value_type>(attr.fetch() ); }
void on_has_one(const char * /*id*/, Pointer &/*x*/, const char * /*join_column*/, const utils::foreign_attributes &attr) {
on_foreign_key<typename Pointer::value_type>(attr.fetch() );
}
template<class ContainerType>
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
@@ -40,6 +40,7 @@ public:
template<class Type, template < class ... > class Pointer>
static void on_has_one(const char * /*id*/,
Pointer<Type> &/*x*/,
const char * /*join_column*/,
const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many(const char * /*id*/,
+1 -1
View File
@@ -30,7 +30,7 @@ public:
template < class Pointer >
static void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template < class Pointer >
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many(const char * /*id*/,
@@ -3,7 +3,7 @@
#include <unordered_map>
#include "matador/object/abstract_collection_resolver.hpp"
#include "matador/object/abstract_joined_resolver.hpp"
#include "matador/object/object_resolver_factory.hpp"
#include "matador/object/collection_resolver_factory.hpp"
#include "matador/object/collection_utils.hpp"
@@ -22,13 +22,24 @@ private:
class producer_collection_resolver_factory : public object::collection_resolver_factory {
public:
[[nodiscard]] std::shared_ptr<object::abstract_collection_resolver> acquire_collection_resolver(const std::type_index& root_type,
[[nodiscard]] std::shared_ptr<object::abstract_joined_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;
void register_collection_resolver(std::shared_ptr<object::abstract_joined_resolver>&& resolver) override;
private:
std::unordered_map<object::collection_composite_key, std::shared_ptr<object::abstract_collection_resolver>, object::collection_composite_key_hash> resolvers_;
std::unordered_map<object::collection_composite_key, std::shared_ptr<object::abstract_joined_resolver>, object::collection_composite_key_hash> resolvers_;
};
class producer_joined_object_resolver_factory : public object::joined_object_resolver_factory {
public:
[[nodiscard]] std::shared_ptr<object::abstract_joined_resolver> acquire_joined_object_resolver(const std::type_index& root_type,
const std::type_index& element_type,
const std::string& collection_name) const override;
void register_joined_object_resolver(std::shared_ptr<object::abstract_joined_resolver>&& resolver) override;
private:
std::unordered_map<object::collection_composite_key, std::shared_ptr<object::abstract_joined_resolver>, object::collection_composite_key_hash> resolvers_;
};
}
#endif //MATADOR_RESOLVER_FACTORY_HPP
+8 -1
View File
@@ -16,12 +16,19 @@ public:
return collection_resolver_factory_.resolver<Type>(root_type, collection_name);
}
template<class Type>
std::shared_ptr<object::collection_resolver<Type>> joined_object_resolver(const std::type_index &root_type, const std::string &join_column) const {
return joined_object_resolver_factory_.resolver<Type>(root_type, join_column);
}
void register_object_resolver(std::shared_ptr<object::abstract_type_resolver> &&resolver);
void register_collection_resolver(std::shared_ptr<object::abstract_collection_resolver>&& resolver);
void register_collection_resolver(std::shared_ptr<object::abstract_joined_resolver>&& resolver);
void register_joined_object_resolver(std::shared_ptr<object::abstract_type_resolver>&& resolver);
private:
sql::producer_resolver_factory object_resolver_factory_;
sql::producer_collection_resolver_factory collection_resolver_factory_;
sql::producer_resolver_factory joined_object_resolver_factory_;
};
}
#endif // MATADOR_RESOLVER_SERVICE_HPP