query/include/matador/object/schema.hpp

123 lines
3.6 KiB
C++

#ifndef SCHEMA_HPP
#define SCHEMA_HPP
#include "matador/object/error_code.hpp"
#include "matador/object/schema_node.hpp"
#include "matador/object/schema_node_iterator.hpp"
#include "matador/utils/result.hpp"
#include "matador/utils/error.hpp"
#include <memory>
#include <string>
#include <unordered_map>
namespace matador::object {
class schema {
public:
typedef const_schema_node_iterator const_iterator; /**< Shortcut for the list const iterator. */
/**
* Creates an empty schema
*/
explicit schema( const std::string& name = "");
template <typename Type>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string name, const std::string &parent = "") {
auto node = schema_node::make_node<Type>(*this, name);
auto result = attach_node(node, parent);
if (!result) {
return utils::failure(result.err());
}
return utils::ok<void>();
}
template <typename Type, typename ParentType>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string name) {
auto node = schema_node::make_node<Type>(*this, name);
auto result = attach_node(node, std::type_index(typeid(ParentType)));
if (!result) {
return utils::failure(result.err());
}
return utils::ok<void>();
}
/**
* Return the first schema node.
*
* @return The first schema node iterator.
*/
[[nodiscard]] const_iterator begin() const;
/**
* Return the last schema node.
*
* @return The last schema node iterator.
*/
[[nodiscard]] const_iterator end() const;
/**
* Returns true if the schema contains
* no schema nodes.
*
* @return True if schema is empty
*/
[[nodiscard]] bool empty() const;
/**
* Returns the current number of schema node.
*
* @return Number of schema nodes
*/
[[nodiscard]] size_t size() const;
/**
* Returns the name of the schema.
*
* @return The name of the schema
*/
[[nodiscard]] std::string name() const;
template <typename Type>
[[nodiscard]] utils::result<object_info_ref<Type>, utils::error> info() const {
auto result = find_node(std::type_index(typeid(Type)));
if (!result) {
return utils::failure(result.err());
}
return utils::ok(result.value()->info<Type>());
}
private:
using node_ptr = std::shared_ptr<schema_node>;
using t_node_map = std::unordered_map<std::string, node_ptr>;
using t_type_index_node_map = std::unordered_map<std::type_index, node_ptr>;
[[nodiscard]] utils::result<std::shared_ptr<schema_node>, utils::error> attach_node(const std::shared_ptr<schema_node> &node,
const std::string &parent);
[[nodiscard]] utils::result<std::shared_ptr<schema_node>, utils::error> attach_node(const std::shared_ptr<schema_node> &node,
const std::type_index &type_index);
[[nodiscard]] utils::result<std::shared_ptr<schema_node>, utils::error> find_node(const std::string &name) const;
[[nodiscard]] utils::result<std::shared_ptr<schema_node>, utils::error> find_node(const std::type_index &type_index) const;
[[nodiscard]] bool has_node(const std::type_index& index, const std::string &name) const;
static void push_back_child(const node_ptr &parent, const node_ptr &child);
private:
std::string name_;
std::shared_ptr<schema_node> root_;
t_node_map node_map_;
t_type_index_node_map type_index_node_map_;
};
}
#endif //SCHEMA_HPP