relation completer progress

This commit is contained in:
2025-07-06 20:06:26 +02:00
parent 5c1e0ae0d8
commit c974628bee
11 changed files with 358 additions and 163 deletions
+3 -3
View File
@@ -58,7 +58,7 @@ const utils::identifier& basic_object_info::primary_key() const {
return identifier_.value();
}
void basic_object_info::register_relation_endpoint(const std::type_index &type, const relation_endpoint &endpoint) {
void basic_object_info::register_relation_endpoint(const std::type_index &type, const std::shared_ptr<relation_endpoint> &endpoint) {
relation_endpoints_.insert(std::make_pair(type, endpoint));
}
@@ -77,13 +77,13 @@ basic_object_info::endpoint_iterator basic_object_info::find_relation_endpoint(c
basic_object_info::const_endpoint_iterator basic_object_info::find_relation_endpoint(const std::string &field) const {
return std::find_if(relation_endpoints_.begin(), relation_endpoints_.end(), [&field](const t_endpoint_map::value_type &value) {
return value.second.field_name() == field;
return value.second->field_name() == field;
});
}
basic_object_info::endpoint_iterator basic_object_info::find_relation_endpoint(const std::string &field) {
return std::find_if(relation_endpoints_.begin(), relation_endpoints_.end(), [&field](const t_endpoint_map::value_type &value) {
return value.second.field_name() == field;
return value.second->field_name() == field;
});
}
+4
View File
@@ -17,6 +17,10 @@ relation_type relation_endpoint::type() const {
return type_;
}
std::string relation_endpoint::type_name() const {
return relation_type_enum.to_string(type_);
}
const schema_node &relation_endpoint::node() const {
return *node_;
}
+71 -6
View File
@@ -17,6 +17,33 @@ root_->first_child_->next_sibling_ = root_->last_child_;
root_->last_child_->previous_sibling_ = root_->first_child_;
}
utils::result<void, utils::error> schema::detach(const node_ptr &node) {
log_.debug("detach node '%s' (type: %s)", node->name().c_str(), node->type_index().name());
remove_node(node);
return utils::ok<void>();
}
// utils::result<void, utils::error> schema::detach(const std::string& name) {
// const auto nit = nodes_by_name_.find(name);
// if (nit == nodes_by_name_.end()) {
// return utils::failure(make_error(error_code::NodeNotFound, "Node '" + name + "' not found."));
// }
//
// const auto ti = nit->second->type_index();
// nodes_by_name_.erase(nit);
//
// const auto it = nodes_by_type_.find(ti);
// if (it == nodes_by_type_.end()) {
// return utils::failure(make_error(error_code::NodeNotFound, "Node '" + name + "' not found."));
// }
//
// nodes_by_type_.erase(it);
//
// return utils::ok<void>();
// }
schema::const_iterator schema::begin() const {
return const_iterator(root_->first_child_->next_sibling_);
}
@@ -50,12 +77,23 @@ utils::result<std::shared_ptr<attribute_definition>, utils::error> schema::refer
return utils::failure(result.err());
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::string &parent) {
void schema::dump(std::ostream &os) const {
for (const auto &node : *this) {
os << "node [" << node.name() << "] (" << node.type_index().name() << ")\n";
for (auto it = node.info().endpoint_begin(); it != node.info().endpoint_end(); ++it) {
os << " " << node.name() << "::" << it->second->field_name() << " (" << it->second->type_name() << ") <---> " << it->second->foreign_endpoint()->node().name() << "::" << it->second->foreign_endpoint()->field_name() << " (" << it->second->foreign_endpoint()->type_name() << ")\n";
}
}
}
utils::result<schema::node_ptr, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::string &parent) {
if (has_node(node->type_index(), node->name())) {
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
}
log_.info("attach node '%s' (type: %s)", node->name().c_str(), node->type_index().name());
// set node to root node
auto parent_node = root_;
if (!parent.empty()) {
@@ -75,8 +113,8 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(co
return utils::ok(node);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::type_index &type_index) {
utils::result<schema::node_ptr, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::type_index &type_index) {
if (has_node(node->type_index(), node->name())) {
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
}
@@ -94,7 +132,7 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(co
return utils::ok(node);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(const std::string &name) const {
utils::result<schema::node_ptr, utils::error> schema::find_node(const std::string &name) const {
// first search in the prototype map
const auto i = nodes_by_name_.find(name);
if (i == nodes_by_name_.end()) {
@@ -103,7 +141,7 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(cons
return utils::ok(i->second);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(const std::type_index &type_index) const {
utils::result<schema::node_ptr, utils::error> schema::find_node(const std::type_index &type_index) const {
const auto i = nodes_by_type_.find(type_index);
if (i == nodes_by_type_.end()) {
return utils::failure(make_error(error_code::NodeNotFound,
@@ -128,6 +166,33 @@ void schema::push_back_child(const node_ptr &parent, const node_ptr &child) {
// child->depth = depth + 1;
}
void schema::remove_node(const node_ptr &node) {
auto next = node->next();
std::stack<node_ptr> nodes_to_remove;
nodes_to_remove.push(node);
while (!nodes_to_remove.empty()) {
const auto current = nodes_to_remove.top();
if (current->has_children()) {
// Push all children to the stack (from right to left to maintain order)
auto child = current->last_child_->previous_sibling_;
while (child != current->first_child_) {
nodes_to_remove.push(child);
child = child->previous_sibling_;
}
continue;
}
// No children left, safe to remove this node
nodes_to_remove.pop();
current->unlink();
nodes_by_name_.erase(current->name());
nodes_by_type_.erase(current->type_index());
}
}
bool schema::has_node(const std::string &name) const {
return nodes_by_name_.count(name) > 0;
}
+11
View File
@@ -44,6 +44,10 @@ const object::schema& schema_node::schema() const {
return schema_;
}
bool schema_node::has_children() const {
return first_child_->next_sibling_ != last_child_;
}
schema_node::node_ptr schema_node::next() const {
// if we have a child, child is the next iterator to return
// (if we don't do iterate over the siblings)
@@ -76,4 +80,11 @@ schema_node::node_ptr schema_node::prev() const {
// is the parent of the node
return parent_->parent_ ? parent_ : parent_->first_child_->next_sibling_;
}
void schema_node::unlink() {
previous_sibling_->next_sibling_ = next_sibling_;
next_sibling_->previous_sibling_ = previous_sibling_;
next_sibling_.reset();
previous_sibling_.reset();
}
}