renamed schema to repository
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
class schema;
|
||||
class repository;
|
||||
|
||||
class fk_attribute_generator
|
||||
{
|
||||
@@ -54,13 +54,13 @@ private:
|
||||
|
||||
class attribute_definition_generator final {
|
||||
private:
|
||||
attribute_definition_generator(std::vector<attribute_definition> &columns, const schema &repo);
|
||||
attribute_definition_generator(std::vector<attribute_definition> &columns, const repository &repo);
|
||||
|
||||
public:
|
||||
~attribute_definition_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<attribute_definition> generate(const schema &repo)
|
||||
static std::vector<attribute_definition> generate(const repository &repo)
|
||||
{
|
||||
std::vector<attribute_definition> columns;
|
||||
attribute_definition_generator gen(columns, repo);
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
}
|
||||
|
||||
template < class Type >
|
||||
static std::vector<attribute_definition> generate(const Type& obj, const schema &repo) {
|
||||
static std::vector<attribute_definition> generate(const Type& obj, const repository &repo) {
|
||||
std::vector<attribute_definition> columns;
|
||||
attribute_definition_generator gen(columns, repo);
|
||||
access::process(gen, obj);
|
||||
@@ -127,7 +127,7 @@ private:
|
||||
private:
|
||||
size_t index_ = 0;
|
||||
std::vector<attribute_definition> &columns_;
|
||||
const schema &repo_;
|
||||
const repository &repo_;
|
||||
|
||||
fk_attribute_generator fk_column_generator_;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
class schema_node;
|
||||
class repository_node;
|
||||
class relation_endpoint;
|
||||
|
||||
class basic_object_info {
|
||||
@@ -49,12 +49,12 @@ public:
|
||||
[[nodiscard]] bool endpoints_empty() const;
|
||||
|
||||
protected:
|
||||
basic_object_info(std::shared_ptr<schema_node> node, utils::identifier &&pk, const std::shared_ptr<attribute_definition> &pk_column, object_definition &&definition);
|
||||
basic_object_info(std::shared_ptr<schema_node> node, utils::identifier &&pk, const std::shared_ptr<attribute_definition> &pk_column);
|
||||
basic_object_info(std::shared_ptr<schema_node> node, object_definition &&definition);
|
||||
basic_object_info(std::shared_ptr<repository_node> node, utils::identifier &&pk, const std::shared_ptr<attribute_definition> &pk_column, object_definition &&definition);
|
||||
basic_object_info(std::shared_ptr<repository_node> node, utils::identifier &&pk, const std::shared_ptr<attribute_definition> &pk_column);
|
||||
basic_object_info(std::shared_ptr<repository_node> node, object_definition &&definition);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<schema_node> node_; /**< prototype node of the represented object type */
|
||||
std::shared_ptr<repository_node> node_; /**< prototype node of the represented object type */
|
||||
object_definition definition_;
|
||||
std::optional<utils::identifier> identifier_;
|
||||
std::shared_ptr<attribute_definition> pk_column_;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef FOREIGN_NODE_COMPLETER_HPP
|
||||
#define FOREIGN_NODE_COMPLETER_HPP
|
||||
|
||||
#include "matador/object/internal/shadow_schema.hpp"
|
||||
#include "matador/object/schema_node.hpp"
|
||||
#include "matador/object/internal/shadow_repository.hpp"
|
||||
#include "matador/object/repository_node.hpp"
|
||||
#include "matador/object/join_columns_collector.hpp"
|
||||
#include "matador/object/object_ptr.hpp"
|
||||
|
||||
@@ -21,12 +21,12 @@ namespace matador::object {
|
||||
*/
|
||||
class foreign_node_completer final {
|
||||
private:
|
||||
using node_ptr = std::shared_ptr<schema_node>;
|
||||
using node_ptr = std::shared_ptr<repository_node>;
|
||||
|
||||
public:
|
||||
template<class Type>
|
||||
static void complete(const std::shared_ptr<schema_node> &node) {
|
||||
internal::shadow_schema shadow(node->schema_);
|
||||
static void complete(const std::shared_ptr<repository_node> &node) {
|
||||
internal::shadow_repository shadow(node->repo_);
|
||||
foreign_node_completer completer(shadow);
|
||||
|
||||
completer.complete_node<Type>(node);
|
||||
@@ -56,10 +56,10 @@ public:
|
||||
void on_has_many_to_many(const char *id, CollectionType &collection, const utils::foreign_attributes &attr);
|
||||
|
||||
private:
|
||||
explicit foreign_node_completer(internal::shadow_schema &shadow);
|
||||
explicit foreign_node_completer(internal::shadow_repository &shadow);
|
||||
|
||||
template<typename Type>
|
||||
void complete_node(const std::shared_ptr<schema_node> &node) {
|
||||
void complete_node(const std::shared_ptr<repository_node> &node) {
|
||||
nodes_.push(node);
|
||||
|
||||
Type obj;
|
||||
@@ -69,17 +69,17 @@ private:
|
||||
|
||||
template<typename Type>
|
||||
void attach_node() {
|
||||
if (schema_.schema_contains(typeid(Type))) {
|
||||
if (repo_.contains(typeid(Type))) {
|
||||
return;
|
||||
}
|
||||
const auto node = schema_node::make_node<Type>(schema_.schema(), "");
|
||||
if (auto result = schema_.attach_node(node)) {
|
||||
const auto node = repository_node::make_node<Type>(repo_.repo(), "");
|
||||
if (auto result = repo_.attach_node(node)) {
|
||||
complete<Type>(result.value());
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::stack<node_ptr> nodes_;
|
||||
internal::shadow_schema &schema_;
|
||||
internal::shadow_repository &repo_;
|
||||
logger::logger log_;
|
||||
join_columns_collector join_columns_collector_{};
|
||||
};
|
||||
|
||||
+10
-10
@@ -8,27 +8,27 @@
|
||||
#include <typeindex>
|
||||
|
||||
namespace matador::object {
|
||||
class schema;
|
||||
class schema_node;
|
||||
class repository;
|
||||
class repository_node;
|
||||
}
|
||||
|
||||
namespace matador::object::internal {
|
||||
class shadow_schema {
|
||||
class shadow_repository {
|
||||
private:
|
||||
using node_ptr = std::shared_ptr<schema_node>;
|
||||
using node_ptr = std::shared_ptr<repository_node>;
|
||||
|
||||
public:
|
||||
explicit shadow_schema(object::schema& s);
|
||||
explicit shadow_repository(object::repository& s);
|
||||
|
||||
[[nodiscard]] object::schema& schema() const;
|
||||
[[nodiscard]] bool schema_contains(const std::type_index& ti) const;
|
||||
[[nodiscard]] object::repository& repo() const;
|
||||
[[nodiscard]] bool contains(const std::type_index& ti) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::type_index &type_index) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::string &name) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const std::shared_ptr<schema_node> &node) const;
|
||||
[[nodiscard]] utils::result<void, utils::error> detach_node(const std::shared_ptr<schema_node> &node) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const std::shared_ptr<repository_node> &node) const;
|
||||
[[nodiscard]] utils::result<void, utils::error> detach_node(const std::shared_ptr<repository_node> &node) const;
|
||||
|
||||
private:
|
||||
object::schema& schema_;
|
||||
object::repository& schema_;
|
||||
};
|
||||
}
|
||||
#endif //SHADOW_SCHEMA_HPP
|
||||
@@ -5,26 +5,26 @@
|
||||
#include "matador/object/object_definition.hpp"
|
||||
|
||||
namespace matador::object {
|
||||
class schema_node;
|
||||
class repository_node;
|
||||
|
||||
template<typename Type>
|
||||
class object_info final : public basic_object_info {
|
||||
public:
|
||||
using create_func = std::function<std::unique_ptr<Type>()>;
|
||||
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
object_info(const std::shared_ptr<repository_node>& node,
|
||||
const std::shared_ptr<attribute_definition> &ref_column)
|
||||
: basic_object_info(node, {}, ref_column, {})
|
||||
, creator_([]{return std::make_unique<Type>(); }){
|
||||
}
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
object_info(const std::shared_ptr<repository_node>& node,
|
||||
utils::identifier &&pk,
|
||||
const std::shared_ptr<attribute_definition> &ref_column,
|
||||
object_definition &&definition)
|
||||
: basic_object_info(node, std::move(pk), ref_column, std::move(definition))
|
||||
, creator_([]{return std::make_unique<Type>(); }){
|
||||
}
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
object_info(const std::shared_ptr<repository_node>& node,
|
||||
utils::identifier &&pk,
|
||||
const std::shared_ptr<attribute_definition> &ref_column,
|
||||
object_definition &&definition,
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
: basic_object_info(node, std::move(pk), ref_column, std::move(definition))
|
||||
, creator_(std::move(creator)){
|
||||
}
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
object_info(const std::shared_ptr<repository_node>& node,
|
||||
object_definition &&definition,
|
||||
create_func&& creator)
|
||||
: basic_object_info(node, std::move(definition))
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef RELATION_COMPLETER_HPP
|
||||
#define RELATION_COMPLETER_HPP
|
||||
|
||||
#include "matador/object/internal/shadow_schema.hpp"
|
||||
#include "matador/object/internal/shadow_repository.hpp"
|
||||
#include "matador/object/many_to_many_relation.hpp"
|
||||
#include "matador/object/join_columns_collector.hpp"
|
||||
#include "matador/object/object_ptr.hpp"
|
||||
#include "matador/object/schema_node.hpp"
|
||||
#include "matador/object/repository_node.hpp"
|
||||
|
||||
#include "matador/logger/log_manager.hpp"
|
||||
|
||||
@@ -94,13 +94,13 @@ private:
|
||||
template<typename Type>
|
||||
class relation_completer final {
|
||||
private:
|
||||
using node_ptr = std::shared_ptr<schema_node>;
|
||||
using node_ptr = std::shared_ptr<repository_node>;
|
||||
|
||||
public:
|
||||
using endpoint_ptr = std::shared_ptr<relation_endpoint>;
|
||||
|
||||
static void complete(const std::shared_ptr<schema_node> &node) {
|
||||
internal::shadow_schema shadow(node->schema_);
|
||||
static void complete(const std::shared_ptr<repository_node> &node) {
|
||||
internal::shadow_repository shadow(node->repo_);
|
||||
relation_completer completer(shadow);
|
||||
|
||||
completer.complete_node_relations(node);
|
||||
@@ -130,12 +130,12 @@ public:
|
||||
void on_has_many_to_many(const char *id, CollectionType &collection, const utils::foreign_attributes &attr);
|
||||
|
||||
private:
|
||||
explicit relation_completer(internal::shadow_schema &shadow)
|
||||
explicit relation_completer(internal::shadow_repository &shadow)
|
||||
: schema_(shadow)
|
||||
, log_(logger::create_logger("relation_completer")) {
|
||||
}
|
||||
|
||||
void complete_node_relations(const std::shared_ptr<schema_node> &node) {
|
||||
void complete_node_relations(const std::shared_ptr<repository_node> &node) {
|
||||
nodes_.push(node);
|
||||
|
||||
Type obj;
|
||||
@@ -150,7 +150,7 @@ private:
|
||||
|
||||
private:
|
||||
std::stack<node_ptr> nodes_;
|
||||
internal::shadow_schema &schema_;
|
||||
internal::shadow_repository &schema_;
|
||||
logger::logger log_;
|
||||
join_columns_collector join_columns_collector_{};
|
||||
};
|
||||
@@ -192,8 +192,8 @@ void relation_completer<Type>::on_has_many(const char *id, CollectionType &,
|
||||
// belongs-to relation handles this relation, the many-to-many
|
||||
// relation is maybe detached.
|
||||
log_.debug("node '%s' has has many foreign keys '%s' mapped by '%s'", nodes_.top()->name().c_str(), id, join_column);
|
||||
result = schema_node::make_relation_node<relation_value_type>(
|
||||
schema_.schema(), id, [join_column] {
|
||||
result = repository_node::make_relation_node<relation_value_type>(
|
||||
schema_.repo(), id, [join_column] {
|
||||
return std::make_unique<relation_value_type>("id", join_column);
|
||||
});
|
||||
if (!result) {
|
||||
@@ -220,8 +220,8 @@ void relation_completer<Type>::on_has_many(const char *id, CollectionType &, con
|
||||
using value_type = typename CollectionType::value_type;
|
||||
using relation_value_type = many_to_relation<Type, value_type>;
|
||||
|
||||
const auto result = schema_node::make_relation_node<relation_value_type>(
|
||||
schema_.schema(), id, [join_column] {
|
||||
const auto result = repository_node::make_relation_node<relation_value_type>(
|
||||
schema_.repo(), id, [join_column] {
|
||||
return std::make_unique<relation_value_type>(join_column, "value");
|
||||
});
|
||||
|
||||
@@ -263,7 +263,7 @@ void relation_completer<Type>::on_has_many_to_many(const char *id,
|
||||
return std::make_unique<relation_value_type>(join_column, inverse_join_column);
|
||||
};
|
||||
|
||||
result = schema_node::make_relation_node<relation_value_type>(schema_.schema(), id, std::move(creator));
|
||||
result = repository_node::make_relation_node<relation_value_type>(schema_.repo(), id, std::move(creator));
|
||||
if (!result) {
|
||||
// Todo: throw internal error
|
||||
return;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
class schema_node;
|
||||
class repository_node;
|
||||
|
||||
enum class relation_type : uint8_t {
|
||||
BELONGS_TO,
|
||||
@@ -24,14 +24,14 @@ static const utils::enum_mapper<relation_type> relation_type_enum({
|
||||
|
||||
class relation_endpoint {
|
||||
public:
|
||||
relation_endpoint(std::string field_name, relation_type type, const std::shared_ptr<schema_node>& node);
|
||||
relation_endpoint(std::string field_name, relation_type type, const std::shared_ptr<repository_node>& node);
|
||||
|
||||
[[nodiscard]] std::string field_name() const;
|
||||
[[nodiscard]] relation_type type() const;
|
||||
[[nodiscard]] std::string type_name() const;
|
||||
[[nodiscard]] const schema_node& node() const;
|
||||
[[nodiscard]] const repository_node& node() const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<schema_node> node_ptr() const;
|
||||
[[nodiscard]] std::shared_ptr<repository_node> node_ptr() const;
|
||||
|
||||
[[nodiscard]] bool is_has_one() const;
|
||||
[[nodiscard]] bool is_has_many() const;
|
||||
@@ -46,7 +46,7 @@ private:
|
||||
|
||||
std::string field_name_;
|
||||
relation_type type_;
|
||||
std::shared_ptr<schema_node> node_;
|
||||
std::shared_ptr<repository_node> node_;
|
||||
std::shared_ptr<relation_endpoint> foreign_endpoint_;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,190 +1,190 @@
|
||||
#ifndef SCHEMA_HPP
|
||||
#define SCHEMA_HPP
|
||||
|
||||
#include "matador/logger/log_manager.hpp"
|
||||
|
||||
#include "matador/object/error_code.hpp"
|
||||
#include "matador/object/foreign_node_completer.hpp"
|
||||
#include "matador/object/relation_completer.hpp"
|
||||
#include "matador/object/schema_node.hpp"
|
||||
#include "matador/object/schema_node_iterator.hpp"
|
||||
|
||||
#include "matador/utils/result.hpp"
|
||||
#include "matador/utils/error.hpp"
|
||||
|
||||
#include "matador/logger/logger.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace matador::object {
|
||||
namespace internal {
|
||||
class shadow_schema;
|
||||
}
|
||||
|
||||
utils::error make_error(error_code ec, const std::string &msg);
|
||||
|
||||
class schema {
|
||||
public:
|
||||
typedef const_schema_node_iterator const_iterator; /**< Shortcut for the list const iterator. */
|
||||
|
||||
using node_ptr = std::shared_ptr<schema_node>;
|
||||
|
||||
/**
|
||||
* Creates an empty schema
|
||||
*/
|
||||
explicit schema(std::string name = "");
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, const std::string &parent = "") {
|
||||
if (const auto it = nodes_by_type_.find(typeid(Type)); it == nodes_by_type_.end() ) {
|
||||
// if the type was not found
|
||||
auto node = schema_node::make_node<Type>(*this, name);
|
||||
if (auto result = attach_node(node, parent); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
foreign_node_completer::complete<Type>(node);
|
||||
relation_completer<Type>::complete(node);
|
||||
} else if (!has_node(name)) {
|
||||
it->second->update_name(name);
|
||||
nodes_by_name_[name] = it->second;
|
||||
relation_completer<Type>::complete(it->second);
|
||||
log_.info("attach: update node name to '%s' (type: %s)", it->second->name().c_str(), it->second->type_index().name());
|
||||
} else {
|
||||
// remove_node( )
|
||||
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + name + "' already exists"));
|
||||
}
|
||||
|
||||
return utils::ok<void>();
|
||||
}
|
||||
|
||||
template<typename Type, typename SuperType>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name) {
|
||||
const auto ti = std::type_index(typeid(SuperType));
|
||||
auto result = find_node(ti);
|
||||
if (!result) {
|
||||
return utils::failure(make_error(error_code::NodeNotFound, "Parent node '" + std::string(ti.name()) + "' not found"));
|
||||
}
|
||||
|
||||
return attach<Type>(name, (*result)->name());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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<void, utils::error> detach(const node_ptr &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)));
|
||||
}
|
||||
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<object_info_ref<Type>, utils::error> info() const {
|
||||
auto result = find_node(std::type_index(typeid(Type)));
|
||||
if (!result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
return utils::ok(result.value()->info<Type>());
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<basic_object_info_ref, utils::error> basic_info() const {
|
||||
auto result = find_node(std::type_index(typeid(Type)));
|
||||
if (!result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
return utils::ok(basic_object_info_ref{result.value()->info()});
|
||||
}
|
||||
|
||||
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> reference_column(
|
||||
const std::type_index &type_index) const;
|
||||
|
||||
void dump(std::ostream &os) const;
|
||||
static void dump(std::ostream &os, const node_ptr& node);
|
||||
|
||||
private:
|
||||
using t_node_map = std::unordered_map<std::string, node_ptr>;
|
||||
using t_type_index_node_map = std::unordered_map<std::type_index, node_ptr>;
|
||||
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const node_ptr &node, const std::string &parent);
|
||||
// [[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const node_ptr &node, const std::type_index &type_index);
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::string &name) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::type_index &type_index) const;
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> 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 node_ptr& node) const;
|
||||
|
||||
static void insert_node(const node_ptr &parent, const node_ptr &child);
|
||||
void remove_node(const node_ptr &node);
|
||||
|
||||
private:
|
||||
friend class internal::shadow_schema;
|
||||
friend class schema_node;
|
||||
friend class attribute_definition_generator;
|
||||
|
||||
std::string name_;
|
||||
std::shared_ptr<schema_node> root_;
|
||||
|
||||
t_node_map nodes_by_name_;
|
||||
t_type_index_node_map nodes_by_type_;
|
||||
logger::logger log_;
|
||||
|
||||
std::unordered_map<std::type_index, std::shared_ptr<attribute_definition> > missing_references_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //SCHEMA_HPP
|
||||
#ifndef SCHEMA_HPP
|
||||
#define SCHEMA_HPP
|
||||
|
||||
#include "matador/logger/log_manager.hpp"
|
||||
|
||||
#include "matador/object/error_code.hpp"
|
||||
#include "matador/object/foreign_node_completer.hpp"
|
||||
#include "matador/object/relation_completer.hpp"
|
||||
#include "matador/object/repository_node.hpp"
|
||||
#include "matador/object/repository_node_iterator.hpp"
|
||||
|
||||
#include "matador/utils/result.hpp"
|
||||
#include "matador/utils/error.hpp"
|
||||
|
||||
#include "matador/logger/logger.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace matador::object {
|
||||
namespace internal {
|
||||
class shadow_repository;
|
||||
}
|
||||
|
||||
utils::error make_error(error_code ec, const std::string &msg);
|
||||
|
||||
class repository {
|
||||
public:
|
||||
typedef const_repository_node_iterator const_iterator; /**< Shortcut for the list const iterator. */
|
||||
|
||||
using node_ptr = std::shared_ptr<repository_node>;
|
||||
|
||||
/**
|
||||
* Creates an empty schema
|
||||
*/
|
||||
explicit repository(std::string name = "");
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, const std::string &parent = "") {
|
||||
if (const auto it = nodes_by_type_.find(typeid(Type)); it == nodes_by_type_.end() ) {
|
||||
// if the type was not found
|
||||
auto node = repository_node::make_node<Type>(*this, name);
|
||||
if (auto result = attach_node(node, parent); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
foreign_node_completer::complete<Type>(node);
|
||||
relation_completer<Type>::complete(node);
|
||||
} else if (!has_node(name)) {
|
||||
it->second->update_name(name);
|
||||
nodes_by_name_[name] = it->second;
|
||||
relation_completer<Type>::complete(it->second);
|
||||
log_.info("attach: update node name to '%s' (type: %s)", it->second->name().c_str(), it->second->type_index().name());
|
||||
} else {
|
||||
// remove_node( )
|
||||
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + name + "' already exists"));
|
||||
}
|
||||
|
||||
return utils::ok<void>();
|
||||
}
|
||||
|
||||
template<typename Type, typename SuperType>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name) {
|
||||
const auto ti = std::type_index(typeid(SuperType));
|
||||
auto result = find_node(ti);
|
||||
if (!result) {
|
||||
return utils::failure(make_error(error_code::NodeNotFound, "Parent node '" + std::string(ti.name()) + "' not found"));
|
||||
}
|
||||
|
||||
return attach<Type>(name, (*result)->name());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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<void, utils::error> detach(const node_ptr &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)));
|
||||
}
|
||||
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<object_info_ref<Type>, utils::error> info() const {
|
||||
auto result = find_node(std::type_index(typeid(Type)));
|
||||
if (!result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
return utils::ok(result.value()->info<Type>());
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<basic_object_info_ref, utils::error> basic_info() const {
|
||||
auto result = find_node(std::type_index(typeid(Type)));
|
||||
if (!result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
return utils::ok(basic_object_info_ref{result.value()->info()});
|
||||
}
|
||||
|
||||
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> reference_column(
|
||||
const std::type_index &type_index) const;
|
||||
|
||||
void dump(std::ostream &os) const;
|
||||
static void dump(std::ostream &os, const node_ptr& node);
|
||||
|
||||
private:
|
||||
using t_node_map = std::unordered_map<std::string, node_ptr>;
|
||||
using t_type_index_node_map = std::unordered_map<std::type_index, node_ptr>;
|
||||
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const node_ptr &node, const std::string &parent);
|
||||
// [[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const node_ptr &node, const std::type_index &type_index);
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::string &name) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::type_index &type_index) const;
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> 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 node_ptr& node) const;
|
||||
|
||||
static void insert_node(const node_ptr &parent, const node_ptr &child);
|
||||
void remove_node(const node_ptr &node);
|
||||
|
||||
private:
|
||||
friend class internal::shadow_repository;
|
||||
friend class repository_node;
|
||||
friend class attribute_definition_generator;
|
||||
|
||||
std::string name_;
|
||||
std::shared_ptr<repository_node> root_;
|
||||
|
||||
t_node_map nodes_by_name_;
|
||||
t_type_index_node_map nodes_by_type_;
|
||||
logger::logger log_;
|
||||
|
||||
std::unordered_map<std::type_index, std::shared_ptr<attribute_definition> > missing_references_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //SCHEMA_HPP
|
||||
+26
-26
@@ -10,15 +10,15 @@
|
||||
namespace matador::object {
|
||||
|
||||
class basic_object_info;
|
||||
class schema;
|
||||
class repository;
|
||||
|
||||
class schema_node final {
|
||||
class repository_node final {
|
||||
public:
|
||||
using node_ptr = std::shared_ptr<schema_node>;
|
||||
using node_ptr = std::shared_ptr<repository_node>;
|
||||
|
||||
template < typename Type >
|
||||
static std::shared_ptr<schema_node> make_node(object::schema& tree, const std::string& name) {
|
||||
auto node = std::shared_ptr<schema_node>(new schema_node(tree, name, typeid(Type)));
|
||||
static std::shared_ptr<repository_node> make_node(object::repository& tree, const std::string& name) {
|
||||
auto node = std::shared_ptr<repository_node>(new repository_node(tree, name, typeid(Type)));
|
||||
|
||||
primary_key_resolver resolver;
|
||||
auto pk_info = resolver.resolve<Type>();
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
}
|
||||
|
||||
template < typename Type, typename CreatorFunc >
|
||||
static utils::result<node_ptr, utils::error> make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) {
|
||||
static utils::result<node_ptr, utils::error> make_relation_node(object::repository& tree, const std::string& name, CreatorFunc &&creator) {
|
||||
const auto result = make_and_attach_node(tree, name, typeid(Type));
|
||||
if (!result) {
|
||||
return result;
|
||||
@@ -53,13 +53,13 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::shared_ptr<schema_node> make_null_node(schema& tree);
|
||||
static std::shared_ptr<repository_node> make_null_node(repository& tree);
|
||||
|
||||
schema_node(const schema_node& other) = delete;
|
||||
schema_node(schema_node&& other) = default;
|
||||
schema_node& operator=(const schema_node& other) = delete;
|
||||
schema_node& operator=(schema_node&& other) = delete;
|
||||
~schema_node() = default;
|
||||
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;
|
||||
@@ -76,39 +76,39 @@ public:
|
||||
return std::ref(static_cast<const object_info<Type>&>(*info_));
|
||||
}
|
||||
|
||||
[[nodiscard]] const object::schema& schema() const;
|
||||
[[nodiscard]] const object::repository& schema() const;
|
||||
|
||||
[[nodiscard]] bool has_children() const;
|
||||
|
||||
private:
|
||||
explicit schema_node(object::schema& tree);
|
||||
schema_node(object::schema& tree, const std::type_index& ti);
|
||||
schema_node(object::schema& tree, std::string name, const std::type_index& ti);
|
||||
explicit repository_node(object::repository& tree);
|
||||
repository_node(object::repository& tree, const std::type_index& ti);
|
||||
repository_node(object::repository& tree, std::string name, const std::type_index& ti);
|
||||
|
||||
void unlink();
|
||||
|
||||
static utils::result<node_ptr, utils::error> make_and_attach_node(object::schema& tree, const std::string& name, const std::type_index& ti);
|
||||
static utils::result<node_ptr, utils::error> make_and_attach_node(object::repository& tree, const std::string& name, const std::type_index& ti);
|
||||
static std::shared_ptr<attribute_definition> determine_reference_column(const std::type_index& ti,
|
||||
const std::string& name,
|
||||
const primary_key_info& pk_info,
|
||||
object::schema& tree);
|
||||
object::repository& tree);
|
||||
|
||||
private:
|
||||
friend class schema;
|
||||
friend class repository;
|
||||
template<typename Type>
|
||||
friend class relation_completer;
|
||||
friend class foreign_node_completer;
|
||||
friend class const_schema_node_iterator;
|
||||
friend class const_repository_node_iterator;
|
||||
|
||||
object::schema &schema_;
|
||||
object::repository &repo_;
|
||||
std::type_index type_index_;
|
||||
std::unique_ptr<basic_object_info> info_;
|
||||
|
||||
std::shared_ptr<schema_node> parent_;
|
||||
std::shared_ptr<schema_node> previous_sibling_;
|
||||
std::shared_ptr<schema_node> next_sibling_;
|
||||
std::shared_ptr<schema_node> first_child_;
|
||||
std::shared_ptr<schema_node> last_child_;
|
||||
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};
|
||||
+24
-24
@@ -1,24 +1,24 @@
|
||||
#ifndef SCHEMA_NODE_ITERATOR_HPP
|
||||
#define SCHEMA_NODE_ITERATOR_HPP
|
||||
|
||||
#include "matador/object/schema_node.hpp"
|
||||
#include "matador/object/repository_node.hpp"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
class const_schema_node_iterator {
|
||||
class const_repository_node_iterator {
|
||||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = std::shared_ptr<schema_node>;
|
||||
using pointer = schema_node*;
|
||||
using value_type = std::shared_ptr<repository_node>;
|
||||
using pointer = repository_node*;
|
||||
using reference = value_type;
|
||||
|
||||
/**
|
||||
* Creates an empty iterator
|
||||
*/
|
||||
const_schema_node_iterator() = default;
|
||||
const_repository_node_iterator() = default;
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator for a concrete type.
|
||||
@@ -28,14 +28,14 @@ public:
|
||||
*
|
||||
* @param node The schema node of the object
|
||||
*/
|
||||
explicit const_schema_node_iterator(const value_type& node);
|
||||
explicit const_repository_node_iterator(const value_type& node);
|
||||
|
||||
/**
|
||||
* Copy from a given const_object_view_iterator.
|
||||
*
|
||||
* @param x The prototype_iterator to copy from.
|
||||
*/
|
||||
const_schema_node_iterator(const const_schema_node_iterator &x) = default;
|
||||
const_repository_node_iterator(const const_repository_node_iterator &x) = default;
|
||||
|
||||
/**
|
||||
* Assign from a given prototype_iterator.
|
||||
@@ -43,59 +43,59 @@ public:
|
||||
* @param x The prototype_iterator to assign from.
|
||||
* @return The assigned prototype_iterator.
|
||||
*/
|
||||
const_schema_node_iterator& operator=(const const_schema_node_iterator &x) = default;
|
||||
const_repository_node_iterator& operator=(const const_repository_node_iterator &x) = default;
|
||||
|
||||
~const_schema_node_iterator() = default;
|
||||
~const_repository_node_iterator() = default;
|
||||
|
||||
/**
|
||||
* @brief Compares this with another iterators.
|
||||
* @brief Compares this with other iterators.
|
||||
*
|
||||
* Compares this with another iterators. Returns true
|
||||
* Compares this with other iterators. Returns true
|
||||
* if the iterators node prototype_type are the same.
|
||||
*
|
||||
* @param i The iterator to compare with.
|
||||
* @return True if the iterators are the same.
|
||||
*/
|
||||
bool operator==(const const_schema_node_iterator &i) const;
|
||||
bool operator==(const const_repository_node_iterator &i) const;
|
||||
|
||||
/**
|
||||
* @brief Compares this with another iterators.
|
||||
* @brief Compares this with other iterators.
|
||||
*
|
||||
* Compares this with another iterators. Returns true
|
||||
* if the iterators node prototype_node are not the same.
|
||||
* Compares this with other iterators. Returns true
|
||||
* if the iterators node prototype_node are different.
|
||||
*
|
||||
* @param i The iterator to compare with.
|
||||
* @return True if the iterators are not the same.
|
||||
* @return True if the iterators are different.
|
||||
*/
|
||||
bool operator!=(const const_schema_node_iterator &i) const;
|
||||
bool operator!=(const const_repository_node_iterator &i) const;
|
||||
|
||||
/**
|
||||
* Pre increments the iterator
|
||||
* Pre-increments the iterator
|
||||
*
|
||||
* @return Returns iterators successor.
|
||||
*/
|
||||
const_schema_node_iterator& operator++();
|
||||
const_repository_node_iterator& operator++();
|
||||
|
||||
/**
|
||||
* Post increments the iterator
|
||||
*
|
||||
* @return Returns iterator before incrementing.
|
||||
*/
|
||||
const_schema_node_iterator operator++( int );
|
||||
const_repository_node_iterator operator++( int );
|
||||
|
||||
/**
|
||||
* Pre increments the iterator
|
||||
* Pre-increments the iterator
|
||||
*
|
||||
* @return Returns iterators predecessor.
|
||||
*/
|
||||
const_schema_node_iterator& operator--();
|
||||
const_repository_node_iterator& operator--();
|
||||
|
||||
/**
|
||||
* Post decrements the iterator
|
||||
*
|
||||
* @return Returns iterator before decrementing.
|
||||
*/
|
||||
const_schema_node_iterator operator--(int);
|
||||
const_repository_node_iterator operator--(int);
|
||||
|
||||
/**
|
||||
* Returns the pointer to the node.
|
||||
@@ -123,7 +123,7 @@ private:
|
||||
void decrement();
|
||||
|
||||
private:
|
||||
value_type node_;
|
||||
value_type node_{};
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user