schema progress (does not compile)

This commit is contained in:
2025-12-31 11:56:12 +01:00
parent d104222fdd
commit ab2d39407c
65 changed files with 1355 additions and 922 deletions
+33 -15
View File
@@ -38,44 +38,55 @@ public:
*/
explicit repository(std::string name = "");
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, template<typename> typename... Observers>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, Observers<Type>&&... observers) {
return attach_type<Type, Observers...>(name, std::string{}, std::forward<Observers<Type>>(observers)...);
}
template<typename Type, typename SuperType, typename... Observers>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, Observers&&... observers) {
template<typename Type, typename SuperType, template<typename> typename... Observers>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, Observers<Type>&&... 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<Type, Observers...>(name, (*result)->name(), std::forward<Observers>(observers)...);
return attach_type<Type, Observers...>(name, (*result)->name(), std::forward<Observers<Type>>(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, template<typename> typename... Observers>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, const std::string &parent, Observers<Type>&&... observers) {
return attach_type<Type, Observers...>(name, parent, std::forward<Observers<Type>>(observers)...);
}
template<typename Type, typename... Observers>
[[nodiscard]] utils::result<void, utils::error> attach_type(const std::string &name, const std::string &parent, Observers&&... observers) {
template<typename Type, template<typename> typename... Observers>
[[nodiscard]] utils::result<void, utils::error> attach_type(const std::string &name, const std::string &parent, Observers<Type>&&... observers) {
if (const auto it = nodes_by_type_.find(typeid(Type)); it == nodes_by_type_.end() ) {
std::vector<std::unique_ptr<observer<Type>>> obs;
obs.reserve(sizeof...(Observers));
(obs.push_back(std::unique_ptr<observer<Type>>(new Observers<Type>(std::forward<Observers<Type>>(observers)))), ...);
// if the type was not found
auto node = repository_node::make_node<Type>(*this, name, []{ return std::make_unique<Type>(); }, std::forward<Observers>(observers)...);
std::shared_ptr<repository_node> node;
if (is_node_announced(typeid(Type))) {
node = pop_announce_node(typeid(Type));
node->update_name(name);
} else {
node = repository_node::make_node<Type>(*this, name, []{ return std::make_unique<Type>(); }, std::move(obs));
}
if (auto result = attach_node(node, parent); !result) {
return utils::failure(result.err());
}
foreign_node_completer<Type>::complete(node);
relation_completer<Type>::complete(node);
const auto info = node->template info<Type>();
foreign_node_completer<Type, Observers...>::complete(node, info.get().observers());
relation_completer<Type, Observers...>::complete(node, info.get().observers());
} 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);
const auto info = it->second->info<Type>();
relation_completer<Type, Observers...>::complete(it->second, info.get().observers());
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"));
@@ -195,6 +206,11 @@ private:
[[nodiscard]] std::shared_ptr<object> 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, const node_ptr &node);
[[nodiscard]] node_ptr announce_node(const std::type_index &ti);
[[nodiscard]] node_ptr pop_announce_node(const std::type_index &ti);
private:
friend class internal::shadow_repository;
friend class repository_node;
@@ -209,9 +225,11 @@ private:
t_type_index_node_map nodes_by_type_;
logger::logger log_;
std::unordered_map<std::type_index, std::shared_ptr<repository_node>> announced_node_;
std::unordered_map<std::type_index, attribute*> missing_references_;
std::unordered_map<std::string, std::type_index> expected_relation_nodes_;
std::unordered_map<std::type_index, std::shared_ptr<object>> object_by_type_;
};
}