schema progress
This commit is contained in:
@@ -20,6 +20,7 @@ add_library(matador-core STATIC
|
||||
../../include/matador/utils/foreign_attributes.hpp
|
||||
../../include/matador/utils/identifier.hpp
|
||||
../../include/matador/utils/library.hpp
|
||||
../../include/matador/utils/macro_map.hpp
|
||||
../../include/matador/utils/os.hpp
|
||||
../../include/matador/utils/placeholder.hpp
|
||||
../../include/matador/utils/result.hpp
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user