121 lines
3.8 KiB
C++
121 lines
3.8 KiB
C++
#ifndef SCHEMA_NODE_HPP
|
|
#define SCHEMA_NODE_HPP
|
|
|
|
#include "matador/object/attribute_generator.hpp"
|
|
#include "matador/object/object_info.hpp"
|
|
#include "matador/object/primary_key_resolver.hpp"
|
|
|
|
#include <memory>
|
|
|
|
namespace matador::object {
|
|
|
|
class basic_object_info;
|
|
class repository;
|
|
|
|
class repository_node final {
|
|
public:
|
|
using node_ptr = std::shared_ptr<repository_node>;
|
|
|
|
template < typename Type >
|
|
static std::shared_ptr<repository_node> make_node(repository& repo, const std::string& name) {
|
|
auto node = std::shared_ptr<repository_node>(new repository_node(repo, name, typeid(Type)));
|
|
|
|
primary_key_resolver resolver;
|
|
auto pk_info = resolver.resolve<Type>();
|
|
auto ref_column = determine_reference_column(typeid(Type), name, pk_info, repo);
|
|
const auto attributes = attribute_generator::generate<Type>(repo);
|
|
auto info = std::make_unique<object_info<Type>>(
|
|
node,
|
|
attributes,
|
|
std::move(pk_info.pk),
|
|
ref_column,
|
|
// obj,
|
|
[]{ return std::make_unique<Type>(); }
|
|
);
|
|
node->info_ = std::move(info);
|
|
|
|
return node;
|
|
}
|
|
|
|
template < typename Type, typename CreatorFunc >
|
|
static utils::result<node_ptr, utils::error> make_relation_node(repository& repo, const std::string& name, CreatorFunc &&creator) {
|
|
const auto result = make_and_attach_node(repo, name, typeid(Type));
|
|
if (!result) {
|
|
return result;
|
|
}
|
|
|
|
auto obj = creator();
|
|
auto info = std::make_unique<object_info<Type>>(
|
|
result.value(),
|
|
attribute_generator::generate(*obj, repo),
|
|
std::forward<CreatorFunc>(creator)
|
|
);
|
|
result.value()->info_ = std::move(info);
|
|
|
|
return result;
|
|
}
|
|
|
|
static std::shared_ptr<repository_node> make_null_node(repository& repo);
|
|
|
|
repository_node(const repository_node& other) = delete;
|
|
repository_node(repository_node&& other) = default;
|
|
repository_node& operator=(const repository_node& other) = delete;
|
|
repository_node& operator=(repository_node&& other) = delete;
|
|
~repository_node() = default;
|
|
|
|
[[nodiscard]] std::string name() const;
|
|
[[nodiscard]] std::type_index type_index() const;
|
|
|
|
[[nodiscard]] node_ptr next() const;
|
|
[[nodiscard]] node_ptr prev() const;
|
|
|
|
[[nodiscard]] const basic_object_info& info() const;
|
|
|
|
void update_name(const std::string& name);
|
|
|
|
template <typename Type>
|
|
[[nodiscard]] object_info_ref<Type> info() const {
|
|
return std::ref(static_cast<const object_info<Type>&>(*info_));
|
|
}
|
|
|
|
[[nodiscard]] const repository& schema() const;
|
|
|
|
[[nodiscard]] bool has_children() const;
|
|
|
|
private:
|
|
explicit repository_node(repository& repo);
|
|
repository_node(repository& repo, const std::type_index& ti);
|
|
repository_node(repository& repo, std::string name, const std::type_index& ti);
|
|
|
|
void unlink();
|
|
|
|
static utils::result<node_ptr, utils::error> make_and_attach_node(repository& repo, const std::string& name, const std::type_index& ti);
|
|
static std::shared_ptr<attribute> determine_reference_column(const std::type_index& ti,
|
|
const std::string& table_name,
|
|
const primary_key_info& pk_info,
|
|
repository& repo);
|
|
|
|
private:
|
|
friend class repository;
|
|
template<typename Type>
|
|
friend class relation_completer;
|
|
friend class foreign_node_completer;
|
|
friend class const_repository_node_iterator;
|
|
|
|
repository &repo_;
|
|
std::type_index type_index_;
|
|
std::unique_ptr<basic_object_info> info_;
|
|
|
|
std::shared_ptr<repository_node> parent_;
|
|
std::shared_ptr<repository_node> previous_sibling_;
|
|
std::shared_ptr<repository_node> next_sibling_;
|
|
std::shared_ptr<repository_node> first_child_;
|
|
std::shared_ptr<repository_node> last_child_;
|
|
|
|
std::string name_;
|
|
size_t depth_{0};
|
|
};
|
|
|
|
}
|
|
#endif //SCHEMA_NODE_HPP
|