started refactoring collection proxy
This commit is contained in:
parent
8914c06833
commit
34a5cfcc88
|
|
@ -25,19 +25,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin() {
|
iterator begin() {
|
||||||
return proxy_->items().begin();
|
return proxy_->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end() {
|
iterator end() {
|
||||||
return proxy_->items().end();
|
return proxy_->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator begin() const {
|
const_iterator begin() const {
|
||||||
return proxy_->items().begin();
|
return proxy_->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator end() const {
|
const_iterator end() const {
|
||||||
return proxy_->items().end();
|
return proxy_->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] size_t size() const {
|
[[nodiscard]] size_t size() const {
|
||||||
|
|
@ -53,7 +53,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<collection_proxy<Type>> proxy_;
|
std::shared_ptr<abstract_collection_proxy<Type>> proxy_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef MATADOR_COLLECTION_PROXY_HPP
|
#ifndef MATADOR_COLLECTION_PROXY_HPP
|
||||||
#define MATADOR_COLLECTION_PROXY_HPP
|
#define MATADOR_COLLECTION_PROXY_HPP
|
||||||
|
|
||||||
|
|
||||||
#include "matador/object/collection_resolver.hpp"
|
#include "matador/object/collection_resolver.hpp"
|
||||||
|
#include "matador/object/many_to_many_relation.hpp"
|
||||||
|
|
||||||
#include "matador/utils/identifier.hpp"
|
#include "matador/utils/identifier.hpp"
|
||||||
|
|
||||||
|
|
@ -12,14 +12,84 @@
|
||||||
|
|
||||||
namespace matador::object {
|
namespace matador::object {
|
||||||
|
|
||||||
|
// has many primitive
|
||||||
|
// relation<OwnerType, PrimitiveType>
|
||||||
|
// has many ptr
|
||||||
|
// relation<OwnerType, ObjectType>
|
||||||
|
// has many to many
|
||||||
|
// relation<OwnerType, ForeignType>
|
||||||
|
|
||||||
template<typename Type>
|
template < class RelationType >
|
||||||
class collection_proxy final {
|
struct relation_iterator_traits;
|
||||||
|
|
||||||
|
template < typename Type, typename OwnerType >
|
||||||
|
struct relation_iterator_traits<relation<OwnerType, Type>> {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type, typename RelationType = Type>
|
||||||
|
class collection_proxy_iterator {
|
||||||
public:
|
public:
|
||||||
using value_type = Type;
|
using value_type = Type;
|
||||||
|
using reference = Type&;
|
||||||
|
using pointer = Type*;
|
||||||
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
|
||||||
|
collection_proxy_iterator() = default;
|
||||||
|
explicit collection_proxy_iterator(typename std::vector<RelationType>::iterator it)
|
||||||
|
: it_(it) {}
|
||||||
|
|
||||||
|
reference operator*() { return *it_; }
|
||||||
|
pointer operator->() { return &*it_; }
|
||||||
|
collection_proxy_iterator& operator++() {
|
||||||
|
++it_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator==(const collection_proxy_iterator& other) const {
|
||||||
|
return it_ == other.it_;
|
||||||
|
}
|
||||||
|
bool operator!=(const collection_proxy_iterator& other) const {
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typename std::vector<RelationType>::iterator it_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type, typename RelationType = Type>
|
||||||
|
class abstract_collection_proxy {
|
||||||
|
public:
|
||||||
|
using value_type = Type;
|
||||||
|
using relation_type = RelationType;
|
||||||
using iterator = typename std::vector<value_type>::iterator;
|
using iterator = typename std::vector<value_type>::iterator;
|
||||||
using const_iterator = typename std::vector<value_type>::const_iterator;
|
using const_iterator = typename std::vector<value_type>::const_iterator;
|
||||||
|
|
||||||
|
virtual ~abstract_collection_proxy() = default;
|
||||||
|
|
||||||
|
virtual void push_back(const value_type& value) = 0;
|
||||||
|
|
||||||
|
virtual iterator begin() = 0;
|
||||||
|
virtual iterator end() = 0;
|
||||||
|
virtual const_iterator begin() const = 0;
|
||||||
|
virtual const_iterator end() const = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual size_t size() const = 0;
|
||||||
|
[[nodiscard]] virtual bool empty() const = 0;
|
||||||
|
// virtual collection_proxy_iterator<Type> begin() = 0;
|
||||||
|
// virtual collection_proxy_iterator<Type> end() = 0;
|
||||||
|
[[nodiscard]] virtual const utils::identifier& owner_id() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<relation_type> items_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
class collection_proxy : public abstract_collection_proxy<Type> {
|
||||||
|
public:
|
||||||
|
using value_type = Type;
|
||||||
|
using iterator = typename abstract_collection_proxy<Type>::iterator;
|
||||||
|
using const_iterator = typename abstract_collection_proxy<Type>::const_iterator;
|
||||||
|
|
||||||
collection_proxy() = default;
|
collection_proxy() = default;
|
||||||
|
|
||||||
// Lazy
|
// Lazy
|
||||||
|
|
@ -34,17 +104,36 @@ public:
|
||||||
explicit collection_proxy(std::vector<Type> items)
|
explicit collection_proxy(std::vector<Type> items)
|
||||||
: items_(std::move(items)) {}
|
: items_(std::move(items)) {}
|
||||||
|
|
||||||
[[nodiscard]] const utils::identifier& owner_id() const {
|
[[nodiscard]] const utils::identifier& owner_id() const override {
|
||||||
return owner_id_;
|
return owner_id_;
|
||||||
}
|
}
|
||||||
const std::vector<Type>& items() const {
|
|
||||||
|
iterator begin() override {
|
||||||
resolve();
|
resolve();
|
||||||
return items_;
|
return items_.begin();
|
||||||
}
|
}
|
||||||
std::vector<Type>& items() {
|
iterator end() override {
|
||||||
resolve();
|
resolve();
|
||||||
return items_;
|
return items_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const override {
|
||||||
|
resolve();
|
||||||
|
return items_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const override {
|
||||||
|
resolve();
|
||||||
|
return items_.end();
|
||||||
|
}
|
||||||
|
// const std::vector<Type>& items() const {
|
||||||
|
// resolve();
|
||||||
|
// return items_;
|
||||||
|
// }
|
||||||
|
// std::vector<Type>& items() {
|
||||||
|
// resolve();
|
||||||
|
// return items_;
|
||||||
|
// }
|
||||||
private:
|
private:
|
||||||
void resolve() {
|
void resolve() {
|
||||||
if (loaded_) {
|
if (loaded_) {
|
||||||
|
|
@ -70,5 +159,18 @@ private:
|
||||||
std::weak_ptr<collection_resolver<Type>> resolver_{};
|
std::weak_ptr<collection_resolver<Type>> resolver_{};
|
||||||
mutable std::mutex mutex_{};
|
mutable std::mutex mutex_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Type, class OwnerType>
|
||||||
|
class collection_many_to_many_proxy {
|
||||||
|
public:
|
||||||
|
using value_type = Type;
|
||||||
|
using owner_type = OwnerType;
|
||||||
|
using relation_type = many_to_many_relation<value_type, owner_type>;
|
||||||
|
using iterator = typename std::vector<relation_type>::iterator;
|
||||||
|
using const_iterator = typename std::vector<relation_type>::const_iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<relation_type> relations_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif //MATADOR_COLLECTION_PROXY_HPP
|
#endif //MATADOR_COLLECTION_PROXY_HPP
|
||||||
|
|
@ -8,6 +8,48 @@
|
||||||
|
|
||||||
namespace matador::object {
|
namespace matador::object {
|
||||||
|
|
||||||
|
template < class LocalType, class ForeignType >
|
||||||
|
class relation {
|
||||||
|
public:
|
||||||
|
relation() = default;
|
||||||
|
relation(std::string local_name, std::string remote_name)
|
||||||
|
: local_name_(std::move(local_name))
|
||||||
|
, remote_name_(std::move(remote_name)) {}
|
||||||
|
relation(std::string local_name, std::string remote_name, const object_ptr<LocalType>& local, const ForeignType& remote)
|
||||||
|
: local_name_(std::move(local_name))
|
||||||
|
, remote_name_(std::move(remote_name))
|
||||||
|
, local_(local)
|
||||||
|
, remote_(remote)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class Operator>
|
||||||
|
void process(Operator &op) {
|
||||||
|
namespace field = matador::access;
|
||||||
|
field::belongs_to(op, local_name_.c_str(), local_, utils::CascadeNoneFetchLazy);
|
||||||
|
foreign_field(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<LocalType> local() const { return local_; }
|
||||||
|
const ForeignType& remote() const { return remote_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Operator, class RemoteType = ForeignType>
|
||||||
|
void foreign_field(Operator &op, std::enable_if_t<!is_object_ptr<RemoteType>::value>* /*unused*/) {
|
||||||
|
namespace field = matador::access;
|
||||||
|
field::attribute(op, remote_name_.c_str(), remote_);
|
||||||
|
}
|
||||||
|
template<typename Operator, class RemoteType = ForeignType>
|
||||||
|
void foreign_field(Operator &op, std::enable_if_t<is_object_ptr<RemoteType>::value>* /*unused*/) {
|
||||||
|
namespace field = matador::access;
|
||||||
|
field::belongs_to(op, remote_name_.c_str(), remote_, utils::CascadeNoneFetchLazy);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string local_name_;
|
||||||
|
std::string remote_name_;
|
||||||
|
object_ptr<LocalType> local_;
|
||||||
|
ForeignType remote_;
|
||||||
|
};
|
||||||
|
|
||||||
template < class LocalType, class ForeignType >
|
template < class LocalType, class ForeignType >
|
||||||
class many_to_many_relation {
|
class many_to_many_relation {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ void relation_completer<Type, Observers...>::on_has_many(const char *id, Collect
|
||||||
using relation_value_type = many_to_many_relation<Type, value_type>;
|
using relation_value_type = many_to_many_relation<Type, value_type>;
|
||||||
|
|
||||||
// Check if the object_ptr type is already inserted in the schema (by id)
|
// Check if the object_ptr type is already inserted in the schema (by id)
|
||||||
auto foreign_node = find_node(typeid(value_type));
|
const auto foreign_node = find_node(typeid(value_type));
|
||||||
if (!foreign_node) {
|
if (!foreign_node) {
|
||||||
// Todo: throw internal error or attach node
|
// Todo: throw internal error or attach node
|
||||||
return;
|
return;
|
||||||
|
|
@ -191,7 +191,7 @@ void relation_completer<Type, Observers...>::on_has_many(const char *id, Collect
|
||||||
const auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HasMany, *foreign_node);
|
const auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HasMany, *foreign_node);
|
||||||
nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint);
|
nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint);
|
||||||
} else {
|
} else {
|
||||||
// A relation table is necessary
|
// A relation table is necessary.
|
||||||
// Endpoint was not found.
|
// Endpoint was not found.
|
||||||
// Always attach a many-to-many relation type. If later a
|
// Always attach a many-to-many relation type. If later a
|
||||||
// belongs-to relation handles this relation, the many-to-many
|
// belongs-to relation handles this relation, the many-to-many
|
||||||
|
|
@ -222,8 +222,7 @@ template<typename Type, template<typename> typename... Observers>
|
||||||
template<class CollectionType>
|
template<class CollectionType>
|
||||||
void relation_completer<Type, Observers...>::on_has_many(const char *id, CollectionType &, const char *join_column,
|
void relation_completer<Type, Observers...>::on_has_many(const char *id, CollectionType &, const char *join_column,
|
||||||
const utils::foreign_attributes &,
|
const utils::foreign_attributes &,
|
||||||
std::enable_if_t<!is_object_ptr<typename CollectionType::value_type>::value>
|
std::enable_if_t<!is_object_ptr<typename CollectionType::value_type>::value>* /*unused*/) {
|
||||||
* /*unused*/) {
|
|
||||||
using value_type = typename CollectionType::value_type;
|
using value_type = typename CollectionType::value_type;
|
||||||
using relation_value_type = many_to_relation<Type, value_type>;
|
using relation_value_type = many_to_relation<Type, value_type>;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue