#ifndef MATADOR_BASIC_REPOSITORY_HPP #define MATADOR_BASIC_REPOSITORY_HPP #include "matador/object/error_code.hpp" #include "matador/object/object_info.hpp" #include "matador/object/repository_node_iterator.hpp" #include "matador/logger/logger.hpp" #include "matador/utils/error.hpp" #include "matador/utils/result.hpp" #include #include namespace matador::object { utils::error make_error(error_code ec, const std::string &msg); class repository_node; class const_repository_node_iterator; class basic_repository { public: typedef const_repository_node_iterator const_iterator; /**< Shortcut for the list const iterator. */ explicit basic_repository(std::string name = ""); ~basic_repository(); /** * * @param node Node to attach * @param parent Name of parent node * @return Attached node */ [[nodiscard]] utils::result attach_node(repository_node *node, const std::string &parent); /** * Detaches a given node from the schema. If the * node is a parent of other nodes, these nodes are * detached as well. * * @param node Node to detach from schema * @return Result object indicating success or failure */ [[nodiscard]] utils::result detach(repository_node *node); /** * Return the first schema node. * * @return The first schema node iterator. */ [[nodiscard]] const_iterator begin() const; /** * Return the last schema node. * * @return The last schema node iterator. */ [[nodiscard]] const_iterator end() const; /** * Returns true if the schema contains * no schema nodes. * * @return True if the schema is empty */ [[nodiscard]] bool empty() const; /** * Returns the current number of the schema node. * * @return Number of schema nodes */ [[nodiscard]] size_t size() const; /** * Returns the name of the schema. * * @return The name of the schema */ [[nodiscard]] std::string name() const; [[nodiscard]] bool contains(const std::string &name) const; [[nodiscard]] bool contains(const std::type_index &index) const; template < typename Type > [[nodiscard]] bool contains() const { return contains(std::type_index(typeid(Type))); } [[nodiscard]] utils::result basic_info(const std::type_index& ti) const; [[nodiscard]] utils::result basic_info(const std::string &name) const; template [[nodiscard]] utils::result basic_info() const { return basic_info(std::type_index(typeid(Type))); } [[nodiscard]] utils::result primary_key_attribute(const std::type_index &ti) const; void dump(std::ostream &os) const; static void dump(std::ostream &os, const repository_node& node); protected: using t_node_map = std::unordered_map; using t_type_index_node_map = std::unordered_map; protected: [[nodiscard]] const_iterator find_node(const std::string &name) const; [[nodiscard]] const_iterator find_node(const std::type_index &type_index) const; template [[nodiscard]] const_iterator find_node() const { return find_node(std::type_index(typeid(Type))); } [[nodiscard]] bool has_node(const std::string &name) const; [[nodiscard]] bool has_node(const std::type_index &index) const; [[nodiscard]] bool has_node(const repository_node* node) const; static void insert_node(repository_node *parent, repository_node *child); void remove_node(repository_node *node); [[nodiscard]] bool expecting_relation_node(const std::string &name) const; void expect_relation_node(const std::string &name, const std::type_index &ti); void remove_expected_relation_node(const std::string &name); [[nodiscard]] std::shared_ptr provide_object_in_advance(const std::type_index &ti, const std::shared_ptr& obj); [[nodiscard]] bool has_object_for_type(const std::type_index &ti) const; [[nodiscard]] std::shared_ptr object_for_type(const std::type_index &ti) const; void remove_object_for_type(const std::type_index &ti); [[nodiscard]] bool is_node_announced(const std::type_index &ti) const; void push_announce_node(const std::type_index &ti, std::unique_ptr &&node); [[nodiscard]] repository_node* announce_node(const std::type_index &ti) const; [[nodiscard]] std::unique_ptr pop_announce_node(const std::type_index &ti); protected: friend class object_generator; template < typename NodeType, template typename ...Observers > friend class foreign_node_completer; template < typename NodeType, template typename ...Observers > friend class relation_completer; std::string name_; repository_node* root_{nullptr}; t_node_map nodes_by_name_; t_type_index_node_map nodes_by_type_; logger::logger log_; std::unordered_map> announced_node_; std::unordered_map missing_references_{}; std::unordered_map expected_relation_nodes_; std::unordered_map> object_by_type_{}; }; } #endif //MATADOR_BASIC_REPOSITORY_HPP