diff --git a/include/matador/object/basic_object_info.hpp b/include/matador/object/basic_object_info.hpp index 7853f1d..5884981 100644 --- a/include/matador/object/basic_object_info.hpp +++ b/include/matador/object/basic_object_info.hpp @@ -2,6 +2,8 @@ #define BASIC_PROTOTYPE_INFO_HPP #include "matador/object/object_definition.hpp" +#include "matador/object/relation_endpoint.hpp" + #include "matador/utils/identifier.hpp" #include @@ -13,6 +15,10 @@ class schema_node; class basic_object_info { public: + using t_endpoint_map = std::unordered_map; + using endpoint_iterator = t_endpoint_map::iterator; + using const_endpoint_iterator = t_endpoint_map::const_iterator; + virtual ~basic_object_info() = default; [[nodiscard]] std::type_index type_index() const; @@ -20,6 +26,24 @@ public: [[nodiscard]] const object_definition& definition() const; [[nodiscard]] std::shared_ptr reference_column() const; + void register_relation_endpoint(const std::type_index &tindex, const relation_endpoint &endpoint); + void unregister_relation_endpoint(const std::type_index &tindex); + + const_endpoint_iterator find_relation_endpoint(const std::type_index &tindex) const; + endpoint_iterator find_relation_endpoint(const std::type_index &tindex); + + const_endpoint_iterator find_relation_endpoint(const std::string &field) const; + endpoint_iterator find_relation_endpoint(const std::string &field); + + endpoint_iterator endpoint_begin(); + const_endpoint_iterator endpoint_begin() const; + + endpoint_iterator endpoint_end(); + const_endpoint_iterator endpoint_end() const; + + std::size_t endpoints_size() const; + bool endpoints_empty() const; + protected: basic_object_info(std::shared_ptr node, std::type_index type_index, utils::identifier &&pk, std::shared_ptr &&pk_column, object_definition &&definition); basic_object_info(std::shared_ptr node, std::type_index type_index, utils::identifier &&pk, std::shared_ptr &&pk_column); @@ -30,6 +54,7 @@ protected: object_definition definition_; std::optional identifier_; std::shared_ptr pk_column_; + t_endpoint_map relation_endpoints_; }; using basic_object_info_ref = std::reference_wrapper; diff --git a/include/matador/object/relation_endpoint.hpp b/include/matador/object/relation_endpoint.hpp new file mode 100644 index 0000000..c12e455 --- /dev/null +++ b/include/matador/object/relation_endpoint.hpp @@ -0,0 +1,39 @@ +#ifndef MATADOR_RELATION_ENDPOINT_HPP +#define MATADOR_RELATION_ENDPOINT_HPP + +#include "matador/object/schema_node.hpp" + +#include "matador/utils/enum_mapper.hpp" + +namespace matador::object { + +enum class relation_type : uint8_t { + BELONGS_TO, + HAS_ONE, + HAS_MANY +}; + +static const utils::enum_mapper relation_type_enum({ + { relation_type::BELONGS_TO, "belongs_to" }, + { relation_type::HAS_ONE, "has_one" }, + { relation_type::HAS_MANY, "has_many" }, + }); + +class relation_endpoint { +public: + relation_endpoint(std::string field_name, relation_type type, const std::shared_ptr& node); + + [[nodiscard]] std::string field_name() const; + [[nodiscard]] relation_type type() const; + [[nodiscard]] const schema_node& node() const; + +private: + std::string field_name_; + relation_type type_; + std::shared_ptr node_; + std::weak_ptr foreign_endpoint; +}; + +} + +#endif //MATADOR_RELATION_ENDPOINT_HPP diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index 6481a65..8a2f646 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -75,6 +75,8 @@ add_library(matador-core STATIC utils/uuid.cpp utils/value.cpp utils/version.cpp + ../../include/matador/object/relation_endpoint.hpp + object/relation_endpoint.cpp ) target_link_libraries(matador-core ${CMAKE_DL_LIBS}) diff --git a/source/core/object/basic_object_info.cpp b/source/core/object/basic_object_info.cpp index 25b44dd..a639724 100644 --- a/source/core/object/basic_object_info.cpp +++ b/source/core/object/basic_object_info.cpp @@ -43,4 +43,56 @@ std::shared_ptr basic_object_info::reference_column() cons return pk_column_; } +void basic_object_info::register_relation_endpoint(const std::type_index &tindex, const relation_endpoint &endpoint) { + relation_endpoints_.insert(std::make_pair(tindex, endpoint)); +} + +void basic_object_info::unregister_relation_endpoint(const std::type_index &tindex) { + relation_endpoints_.erase(tindex); +} + +basic_object_info::const_endpoint_iterator +basic_object_info::find_relation_endpoint(const std::type_index &tindex) const { + return relation_endpoints_.find(tindex); +} + +basic_object_info::endpoint_iterator basic_object_info::find_relation_endpoint(const std::type_index &tindex) { + return relation_endpoints_.find(tindex); +} + +basic_object_info::const_endpoint_iterator basic_object_info::find_relation_endpoint(const std::string &field) const { + return std::find_if(relation_endpoints_.begin(), relation_endpoints_.end(), [&field](const t_endpoint_map::value_type &value) { + return value.second.field_name() == field; + }); +} + +basic_object_info::endpoint_iterator basic_object_info::find_relation_endpoint(const std::string &field) { + return std::find_if(relation_endpoints_.begin(), relation_endpoints_.end(), [&field](const t_endpoint_map::value_type &value) { + return value.second.field_name() == field; + }); +} + +basic_object_info::endpoint_iterator basic_object_info::endpoint_begin() { + return relation_endpoints_.begin(); +} + +basic_object_info::const_endpoint_iterator basic_object_info::endpoint_begin() const { + return relation_endpoints_.begin(); +} + +basic_object_info::endpoint_iterator basic_object_info::endpoint_end() { + return relation_endpoints_.end(); +} + +basic_object_info::const_endpoint_iterator basic_object_info::endpoint_end() const { + return relation_endpoints_.end(); +} + +std::size_t basic_object_info::endpoints_size() const { + return relation_endpoints_.size(); +} + +bool basic_object_info::endpoints_empty() const { + return relation_endpoints_.empty(); +} } // namespace matador::object diff --git a/source/core/object/relation_endpoint.cpp b/source/core/object/relation_endpoint.cpp new file mode 100644 index 0000000..bae4c59 --- /dev/null +++ b/source/core/object/relation_endpoint.cpp @@ -0,0 +1,21 @@ +#include "matador/object/relation_endpoint.hpp" + +namespace matador::object { +relation_endpoint::relation_endpoint(std::string field_name, relation_type type, const std::shared_ptr &node) +: field_name_(std::move(field_name)) +, type_(type) +, node_(node) { +} + +std::string relation_endpoint::field_name() const { + return field_name_; +} + +relation_type relation_endpoint::type() const { + return type_; +} + +const schema_node &relation_endpoint::node() const { + return *node_; +} +} \ No newline at end of file