100 lines
3.5 KiB
C++
100 lines
3.5 KiB
C++
#include "matador/object/schema.hpp"
|
|
|
|
namespace matador::object {
|
|
|
|
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))) {
|
|
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_;
|
|
root_->last_child_->previous_sibling_ = root_->first_child_;
|
|
}
|
|
|
|
bool schema::empty() const {
|
|
return root_->first_child_ == root_->last_child_->previous_sibling_;
|
|
}
|
|
|
|
size_t schema::size() const { return 0; }
|
|
|
|
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())) {
|
|
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 (!result.is_ok() && result.err().ec() != error_code::NodeNotFound) {
|
|
return result;
|
|
}
|
|
parent_node = *result;
|
|
|
|
push_back_child(root_, 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));
|
|
|
|
// 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);
|
|
}
|
|
|
|
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::ok(i->second);
|
|
}
|
|
|
|
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_;
|
|
parent->last_child_->previous_sibling_->next_sibling_ = child;
|
|
parent->last_child_->previous_sibling_ = child;
|
|
// set depth
|
|
// child->depth = depth + 1;
|
|
}
|
|
|
|
bool schema::has_node(const std::type_index &index, const std::string &name) const {
|
|
return node_map_.count(name) > 0 || type_index_node_map_.count(index) > 0;
|
|
}
|
|
|
|
} // namespace matador::object
|