schema progress

This commit is contained in:
Sascha Kühl
2025-02-04 15:19:01 +01:00
parent 6a5974337d
commit f01e9ff87f
17 changed files with 416 additions and 276 deletions
+50 -40
View File
@@ -6,8 +6,9 @@ utils::error make_error(const error_code ec, const std::string& msg) {
return utils::error(ec, msg);
}
schema::schema()
: root_(std::shared_ptr<schema_node>(new schema_node(*this))) {
schema::schema( const std::string& name)
: name_(name)
, root_(std::shared_ptr<schema_node>(new schema_node(*this))) {
root_->first_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
root_->last_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
root_->first_child_->next_sibling_ = root_->last_child_;
@@ -30,64 +31,67 @@ size_t schema::size() const {
return static_cast<size_t>(std::distance(begin(), end()));
}
std::string schema::name() const {
return name_;
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::string &parent) {
if (!has_node(node->type_index(), node->name())) {
if (has_node(node->type_index(), node->name())) {
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
}
// set node to root node
auto parent_node = root_;
auto result = find_parent(parent);
if (!parent.empty()) {
auto result = find_node(parent);
if (!result.is_ok() && result.err().ec() != error_code::NodeNotFound) {
return result;
}
parent_node = *result;
}
push_back_child(parent_node, node);
// Todo: check return value
node_map_.insert({node->name(), node})/*.first*/;
type_index_node_map_.insert({node->type_index(), node});
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 ) {
if (has_node(node->type_index(), node->name())) {
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
}
auto result = find_node(type_index);
if (!result.is_ok() && result.err().ec() != error_code::NodeNotFound) {
return result;
}
parent_node = *result;
push_back_child(root_, node);
push_back_child(*result, node);
// if (!pk.is_null()) {
// node->primary_key_ = pk;
// }
// store prototype in map
// Todo: check return value
node_map_.insert(std::make_pair(node->name(), node))/*.first*/;
type_index_node_map_[node->type_index()].insert(std::make_pair(node->name(), node));
node_map_.insert({node->name(), node})/*.first*/;
type_index_node_map_.insert({node->type_index(), node});
// return nptr.release();
return {};
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_parent(const std::string &name) const {
if (name.empty()) {
return utils::failure(make_error(error_code::Failure, "Name of parent cannot be empty"));
}
return find_node(name);
return utils::ok(node);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(const std::string &name) const {
// first search in the prototype map
const auto i = node_map_.find(name);
if (i == node_map_.end()) {
// if not found search in the typeid to prototype map
// const auto j = type_index_node_map_.find(name);
// if (j == type_index_node_map_.end()) {
// return utils::failure(
// make_error(error_code::NodeNotFound, std::string("Could not find node with name '") + name + "'"));
// }
// const t_node_map &val = j->second;
/*
* if size is greater one (1) the name
* is a typeid and has more than one prototype
* node and therefor it is not unique and an
* exception is thrown
*/
// if (val.size() > 1) {
// return utils::failure(make_error(error_code::NodeNotFound, std::string("Type id '") + name + "' is not unique"));
// }
// // return the only prototype
// return utils::ok(val.begin()->second);
return utils::failure(make_error(error_code::NodeNotFound, "Couldn't find node by name '" + name + "'"));
}
return utils::ok(i->second);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node( const std::type_index& type_index ) const {
const auto i = type_index_node_map_.find(type_index);
if (i == type_index_node_map_.end()) {
return utils::failure(make_error(error_code::NodeNotFound, "Couldn't find node by type '" + std::string(type_index.name()) + "'"));
}
return utils::ok(i->second);
}
@@ -96,6 +100,12 @@ void schema::push_back_child(const node_ptr &parent, const node_ptr &child) {
child->parent_ = parent;
child->previous_sibling_ = parent->last_child_->previous_sibling_;
child->next_sibling_ = parent->last_child_;
/*
* +-----------------------------<- (first) parent (last) -> ----------------------------+
* | |
* first (next) -> <- (prev) child_1 (next) -> <- (prev) new_child (next) -> <- (prev) last
* ^^^^^^^ inserted ^^^^^^
*/
parent->last_child_->previous_sibling_->next_sibling_ = child;
parent->last_child_->previous_sibling_ = child;
// set depth
+34
View File
@@ -57,4 +57,38 @@ void schema_node::insert(const std::shared_ptr<schema_node> &child) {
// // 3. last
// child->op_last = op_last;
}
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)
if (first_child_ && first_child_->next_sibling_ != last_child_) {
return first_child_->next_sibling_;
}
// if there is no child, we check for sibling
// if there is a sibling, this is our next iterator to return
// if not, we go back to the parent
auto *node = this;
while (node->parent_ && node->next_sibling_ == node->parent_->last_child_) {
node = node->parent_.get();
}
return node->parent_ ? node->next_sibling_ : node->last_child_;
}
schema_node::node_ptr schema_node::prev() const {
// if node has a previous sibling, we set it
// as our next iterator. then we check if there
// are last children. if so, we set the last-last
// child as our iterator
if (previous_sibling_ && previous_sibling_->previous_sibling_) {
auto node = previous_sibling_;
while (node->last_child_ && node->first_child_->next_sibling_ != node->last_child_) {
node = node->last_child_->previous_sibling_;
}
return node;
}
// if there is no previous sibling, our next iterator
// is the parent of the node
return parent_->parent_ ? parent_ : parent_->first_child_->next_sibling_;
}
}
+4 -32
View File
@@ -24,8 +24,7 @@ const_schema_node_iterator& const_schema_node_iterator::operator++()
return *this;
}
const_schema_node_iterator const_schema_node_iterator::operator++(int)
{
const_schema_node_iterator const_schema_node_iterator::operator++( int ) {
const std::shared_ptr<value_type> tmp = node_;
increment();
return const_schema_node_iterator(tmp);
@@ -65,42 +64,15 @@ void const_schema_node_iterator::increment()
return;
}
// if we have a child, child is the next iterator to return
// (if we don't do iterate over the siblings)
if (node_->first_child_ && node_->first_child_->next_sibling_ != node_->last_child_) {
node_ = node_->first_child_->next_sibling_;
} else {
// if there is no child, we check for sibling
// if there is a sibling, this is our next iterator to return
// if not, we go back to the parent
std::shared_ptr<value_type> node = node_;
while (node_->parent_ && node_->next_sibling_ == node_->parent_->last_child_) {
node = node->parent_;
}
node_ = node_->next_sibling_;
}
node_ = node_->next();
}
void const_schema_node_iterator::decrement()
{
if (!node_) {
return;
}
// if node has a previous sibling, we set it
// as our next iterator. then we check if there
// are last children. if so, we set the last-last
// child as our iterator
if (node_->previous_sibling_ && node_->previous_sibling_->previous_sibling_) {
std::shared_ptr<value_type> node = node_->previous_sibling_;
while (node_->last_child_ && node_->first_child_->next_sibling_ != node_->last_child_) {
node = node->last_child_->previous_sibling_;
}
node_ = node;
// if there is no previous sibling, our next iterator
// is the parent of the node
} else {
node_ = node_->parent_;
}
node_ = node_->prev();
}
}