added observer to repository and updated tests
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "matador/object/error_code.hpp"
|
||||
#include "matador/object/foreign_node_completer.hpp"
|
||||
#include "matador/object/object_info.hpp"
|
||||
#include "matador/object/observer.hpp"
|
||||
#include "matador/object/relation_completer.hpp"
|
||||
#include "matador/object/repository_node.hpp"
|
||||
#include "matador/object/repository_node_iterator.hpp"
|
||||
@@ -37,43 +38,53 @@ public:
|
||||
*/
|
||||
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<Type>::complete(node);
|
||||
relation_completer<Type>::complete(node);
|
||||
} else if (!has_node(name)) {
|
||||
it->second->update_name(name);
|
||||
nodes_by_name_[name] = it->second;
|
||||
if (const auto i = nodes_by_name_.find(""); i != nodes_by_name_.end()) {
|
||||
nodes_by_name_.erase(i);
|
||||
}
|
||||
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... Observers>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, Observers&&... observers) {
|
||||
return attach_type<Type, Observers...>(name, std::string{}, std::forward<Observers>(observers)...);
|
||||
}
|
||||
|
||||
template<typename Type, typename SuperType>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name) {
|
||||
template<typename Type, typename SuperType, typename... Observers>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, Observers&&... observers) {
|
||||
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());
|
||||
return attach_type<Type, Observers...>(name, (*result)->name(), std::forward<Observers>(observers)...);
|
||||
}
|
||||
|
||||
template<typename Type, typename... Observers>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, const std::string &parent, Observers&&... observers) {
|
||||
return attach_type<Type, Observers...>(name, parent, std::forward<Observers>(observers)...);
|
||||
}
|
||||
template<typename Type, typename... Observers>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach_type(const std::string &name, const std::string &parent, Observers&&... observers) {
|
||||
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, []{ return std::make_unique<Type>(); }, std::forward<Observers>(observers)...);
|
||||
if (auto result = attach_node(node, parent); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
node->on_attach();
|
||||
|
||||
foreign_node_completer<Type>::complete(node);
|
||||
relation_completer<Type>::complete(node);
|
||||
} else if (!has_node(name)) {
|
||||
it->second->update_name(name);
|
||||
nodes_by_name_[name] = it->second;
|
||||
if (const auto i = nodes_by_name_.find(""); i != nodes_by_name_.end()) {
|
||||
nodes_by_name_.erase(i);
|
||||
}
|
||||
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 {
|
||||
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + name + "' already exists"));
|
||||
}
|
||||
|
||||
return utils::ok<void>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches a given node from the schema. If the
|
||||
|
||||
Reference in New Issue
Block a user