reference column progress

This commit is contained in:
Sascha Kühl 2025-02-09 20:49:00 +01:00
parent a4d6f68ee2
commit 504e111491
11 changed files with 269 additions and 188 deletions

View File

@ -1,6 +1,8 @@
#ifndef QUERY_COLUMN_DEFINITION_HPP #ifndef QUERY_COLUMN_DEFINITION_HPP
#define QUERY_COLUMN_DEFINITION_HPP #define QUERY_COLUMN_DEFINITION_HPP
#include <memory>
#include "matador/utils/basic_type_converter.hpp" #include "matador/utils/basic_type_converter.hpp"
#include "matador/utils/basic_types.hpp" #include "matador/utils/basic_types.hpp"
#include "matador/utils/default_type_traits.hpp" #include "matador/utils/default_type_traits.hpp"
@ -43,11 +45,11 @@ public:
attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, size_t index = 0); attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, size_t index = 0);
template<typename Type> template<typename Type>
attribute_definition(std::string name, std::string ref_table, std::string ref_column, const utils::field_attributes& attr, null_option null_opt) attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt)
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_table, ref_column, attr, null_opt) : attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt)
{} {}
attribute_definition(std::string name, utils::basic_type type, size_t index, std::string ref_table, std::string ref_column, const utils::field_attributes& attr, null_option null_opt); attribute_definition(std::string name, utils::basic_type type, size_t index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt);
[[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& name() const;
[[nodiscard]] std::string full_name() const; [[nodiscard]] std::string full_name() const;
@ -56,8 +58,7 @@ public:
[[nodiscard]] const utils::field_attributes& attributes() const; [[nodiscard]] const utils::field_attributes& attributes() const;
[[nodiscard]] bool is_nullable() const; [[nodiscard]] bool is_nullable() const;
[[nodiscard]] utils::basic_type type() const; [[nodiscard]] utils::basic_type type() const;
[[nodiscard]] const std::string& ref_table() const; [[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
[[nodiscard]] const std::string& ref_column() const;
[[nodiscard]] bool is_foreign_reference() const; [[nodiscard]] bool is_foreign_reference() const;
[[nodiscard]] bool is_integer() const; [[nodiscard]] bool is_integer() const;
@ -124,8 +125,9 @@ private:
utils::field_attributes attributes_; utils::field_attributes attributes_;
null_option null_option_{null_option::NOT_NULL}; null_option null_option_{null_option::NOT_NULL};
utils::value value_; utils::value value_;
std::string ref_table_; std::shared_ptr<attribute_definition> reference_column_;
std::string ref_column_; // std::string ref_table_;
// std::string ref_column_;
}; };
/** /**
@ -156,19 +158,20 @@ template <>
attribute_definition make_pk_column<std::string>(const std::string &name, size_t size); attribute_definition make_pk_column<std::string>(const std::string &name, size_t size);
template < typename Type > template < typename Type >
attribute_definition make_fk_column(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column) attribute_definition make_fk_column(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column)
{ {
return {name, utils::data_type_traits<Type>::type(size), ref_table, ref_column, { size, utils::constraints::FOREIGN_KEY }}; return {name, utils::data_type_traits<Type>::type(size), ref_column, { size, utils::constraints::FOREIGN_KEY }};
} }
template < typename Type > template < typename Type >
[[maybe_unused]] attribute_definition make_fk_column(const std::string &name, const std::string &ref_table, const std::string &ref_column) [[maybe_unused]] attribute_definition make_fk_column(const std::string &name, const std::shared_ptr<attribute_definition> &ref_column)
{ {
return {name, utils::data_type_traits<Type>::type(0), 0, ref_table, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL}; return {name, utils::data_type_traits<Type>::type(0), 0, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
} }
template <> template <>
attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column); attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column);
} }
#endif //QUERY_COLUMN_DEFINITION_HPP #endif //QUERY_COLUMN_DEFINITION_HPP

View File

@ -83,7 +83,7 @@ public:
template<class Pointer> template<class Pointer>
void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/) void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/)
{ {
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type))); const auto ref_column = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column)); columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
} }
template<class Pointer> template<class Pointer>
@ -100,7 +100,7 @@ public:
void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &/*attr*/) {} void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &/*attr*/) {}
private: private:
std::pair<std::string, std::string> determine_foreign_ref(const std::type_index &ti); std::shared_ptr<attribute_definition> determine_foreign_ref(const std::type_index &ti);
private: private:
size_t index_ = 0; size_t index_ = 0;

View File

@ -17,14 +17,16 @@ public:
[[nodiscard]] std::type_index type_index() const; [[nodiscard]] std::type_index type_index() const;
[[nodiscard]] std::string name() const; [[nodiscard]] std::string name() const;
[[nodiscard]] const object_definition& definition() const; [[nodiscard]] const object_definition& definition() const;
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
protected: protected:
basic_object_info(schema_node &node, std::type_index type_index, object_definition &&definition); basic_object_info(schema_node &node, std::type_index type_index, object_definition &&definition, std::shared_ptr<attribute_definition> &&reference_column);
protected: protected:
schema_node &node_; /**< prototype node of the represented object type */ schema_node &node_; /**< prototype node of the represented object type */
std::type_index type_index_; /**< type index of the represented object type */ std::type_index type_index_; /**< type index of the represented object type */
object_definition definition_; object_definition definition_;
std::shared_ptr<attribute_definition> reference_column_;
}; };
using basic_object_info_ref = std::reference_wrapper<const basic_object_info>; using basic_object_info_ref = std::reference_wrapper<const basic_object_info>;

View File

@ -5,14 +5,15 @@
#include "matador/object/object_definition.hpp" #include "matador/object/object_definition.hpp"
namespace matador::object { namespace matador::object {
class schema_node; class schema_node;
template<typename Type> template<typename Type>
class object_info final : public basic_object_info { class object_info final : public basic_object_info {
public: public:
explicit object_info(schema_node &node, object_definition &&definition) explicit object_info(schema_node &node, object_definition &&definition,
: basic_object_info(node, typeid(Type), std::move(definition)) {} std::shared_ptr<attribute_definition> &&ref_column)
: basic_object_info(node, typeid(Type), std::move(definition), std::move(ref_column)) {
}
const Type &prototype() const { return prototype_; } const Type &prototype() const { return prototype_; }
@ -24,11 +25,11 @@ template<typename Type>
using object_info_ref = std::reference_wrapper<const object_info<Type>>; using object_info_ref = std::reference_wrapper<const object_info<Type>>;
namespace detail { namespace detail {
struct null_type {}; struct null_type {
};
} }
using null_info = object_info<detail::null_type>; using null_info = object_info<detail::null_type>;
} }
#endif //OBJECT_INFO_HPP #endif //OBJECT_INFO_HPP

View File

@ -9,11 +9,69 @@
#include "matador/utils/error.hpp" #include "matador/utils/error.hpp"
#include <memory> #include <memory>
#include <stack>
#include <string> #include <string>
#include <unordered_map> #include <unordered_set>
namespace matador::object { namespace matador::object {
utils::error make_error(error_code ec, const std::string& msg);
class schema;
template<typename Type>
class type_analyzer final {
public:
using value_type = Type;
static void analyze(schema &scm) {
type_analyzer analyzer(scm);
Type obj;
const auto ti = std::type_index(typeid(Type));
analyzer.known_types_.emplace(ti);
access::process(analyzer, obj);
analyzer.known_types_.erase(ti);
}
template < class PrimaryKeyType >
void on_primary_key(const char * /*id*/, PrimaryKeyType &/*pk*/, std::enable_if_t<std::is_integral_v<PrimaryKeyType> && !std::is_same_v<bool, PrimaryKeyType>>* = nullptr) {}
void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t /*size*/) {}
void on_revision(const char * /*id*/, uint64_t &/*rev*/) {}
template<typename AttributeType>
void on_attribute(const char * /*id*/, AttributeType &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<typename AttributeType>
void on_attribute(const char * /*id*/, std::optional<AttributeType> &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<class ForeignPointerType>
void on_belongs_to(const char * /*id*/, ForeignPointerType &/*obj*/, const utils::foreign_attributes &/*attr*/) {
// const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
// columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
}
template<class ForeignPointerType>
void on_has_one(const char * /*id*/, ForeignPointerType &/*obj*/, const utils::foreign_attributes &/*attr*/);
template<class CollectionType>
void on_has_many(const char * /*id*/, CollectionType &, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class CollectionType>
void on_has_many_to_many(const char * /*id*/, CollectionType &/*col*/, const char * /*join_column*/, const char * /*inverse_join_column*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many_to_many(const char * /*id*/, ContainerType &/*col*/, const utils::foreign_attributes &/*attr*/) {}
private:
explicit type_analyzer(schema& schema)
: schema_(schema) {};
private:
schema &schema_;
std::unordered_set<std::type_index> known_types_;
};
class schema { class schema {
public: public:
typedef const_schema_node_iterator const_iterator; /**< Shortcut for the list const iterator. */ typedef const_schema_node_iterator const_iterator; /**< Shortcut for the list const iterator. */
@ -24,7 +82,14 @@ public:
explicit schema( const std::string& name = ""); explicit schema( const std::string& name = "");
template <typename Type> template <typename Type>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string name, const std::string &parent = "") { [[nodiscard]] utils::result<void, utils::error> attach(const std::string& name, const std::string &parent = "") {
if (has_node(name)) {
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + name + "' already exists"));
}
// analyze node (collect unknown types by type index)
type_analyzer<Type>::analyze(*this);
auto node = schema_node::make_node<Type>(*this, name); auto node = schema_node::make_node<Type>(*this, name);
auto result = attach_node(node, parent); auto result = attach_node(node, parent);
@ -37,14 +102,13 @@ public:
template <typename Type, typename ParentType> template <typename Type, typename ParentType>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string name) { [[nodiscard]] utils::result<void, utils::error> attach(const std::string name) {
auto node = schema_node::make_node<Type>(*this, name); const auto ti = std::type_index(typeid(ParentType));
auto result = find_node(ti);
auto result = attach_node(node, std::type_index(typeid(ParentType)));
if (!result) { if (!result) {
return utils::failure(result.err()); return utils::failure(make_error(error_code::NodeNotFound, "Parent node '" + std::string(ti.name()) + "' not found"));
} }
return utils::ok<void>(); return attach<Type>(name, (*result)->name());
} }
/** /**
@ -103,7 +167,7 @@ public:
return utils::ok(basic_object_info_ref{result.value()->basic_info()}); return utils::ok(basic_object_info_ref{result.value()->basic_info()});
} }
[[nodiscard]] utils::result<std::pair<std::string, std::string>, utils::error> reference(const std::type_index &type_index) const; [[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> reference(const std::type_index &type_index) const;
private: private:
using node_ptr = std::shared_ptr<schema_node>; using node_ptr = std::shared_ptr<schema_node>;
@ -117,11 +181,16 @@ private:
[[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::string &name) const;
[[nodiscard]] utils::result<std::shared_ptr<schema_node>, utils::error> find_node(const std::type_index &type_index) 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::string &name) const;
[[nodiscard]] bool has_node(const std::type_index& index) const;
[[nodiscard]] bool has_node(const std::type_index& index, const std::string &name) 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); static void push_back_child(const node_ptr &parent, const node_ptr &child);
private: private:
template <typename Type>
friend class type_analyzer;
std::string name_; std::string name_;
std::shared_ptr<schema_node> root_; std::shared_ptr<schema_node> root_;
@ -129,6 +198,22 @@ private:
t_type_index_node_map type_index_node_map_; t_type_index_node_map type_index_node_map_;
}; };
template<typename Type>
template<class ForeignPointerType>
void type_analyzer<Type>::on_has_one(const char *, ForeignPointerType &, const utils::foreign_attributes &) {
auto ti = std::type_index(typeid(typename ForeignPointerType::value_type));
if (schema_.has_node(ti)) {
return;
}
auto info = std::make_unique<object_info<typename ForeignPointerType::value_type>>();
known_types_.insert(ti);
// const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
// columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
}
} }
#endif //SCHEMA_HPP #endif //SCHEMA_HPP

View File

@ -15,10 +15,7 @@ class schema_node final {
public: public:
using node_ptr = std::shared_ptr<schema_node>; using node_ptr = std::shared_ptr<schema_node>;
template < typename Type > static std::shared_ptr<schema_node> make_node(schema& tree, const std::string& name, std::unique_ptr<basic_object_info> &&info);
static std::shared_ptr<schema_node> make_node(schema& tree, const std::string& name) {
return std::shared_ptr<schema_node>(new schema_node(tree, name, static_cast<Type*>(nullptr)));
}
schema_node(const schema_node& other) = delete; schema_node(const schema_node& other) = delete;
schema_node(schema_node&& other) = default; schema_node(schema_node&& other) = default;
@ -41,17 +38,7 @@ public:
private: private:
explicit schema_node(schema& tree); explicit schema_node(schema& tree);
template < typename Type > schema_node(schema& tree, std::string name, std::unique_ptr<basic_object_info> &&info);
schema_node(schema& tree, std::string name, Type *obj)
: schema_(tree)
, info_(std::make_unique<object_info<Type>>(*this, object_definition(attribute_definition_generator::generate<Type>(schema_))))
, first_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
, last_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
, name_(std::move(name)) {
first_child_->next_sibling_ = last_child_;
last_child_->previous_sibling_ = first_child_;
}
private: private:
friend class schema; friend class schema;

View File

@ -4,173 +4,146 @@
#include <utility> #include <utility>
namespace matador::object { namespace matador::object {
attribute_definition::attribute_definition(const char *name) attribute_definition::attribute_definition(const char *name)
: name_(name) : name_(name)
, attributes_(utils::null_attributes) , attributes_(utils::null_attributes) {
{} }
attribute_definition::attribute_definition(std::string name) attribute_definition::attribute_definition(std::string name)
: name_(std::move(name)) : name_(std::move(name))
, attributes_(utils::null_attributes) , attributes_(utils::null_attributes) {
{} }
attribute_definition::attribute_definition(std::string name, const utils::basic_type type, const utils::field_attributes& attr, const null_option null_opt, const size_t index) attribute_definition::attribute_definition(std::string name, const utils::basic_type type,
const utils::field_attributes &attr, const null_option null_opt,
const size_t index)
: name_(std::move(name)) : name_(std::move(name))
, index_(index) , index_(index)
, attributes_(attr) , attributes_(attr)
, null_option_(null_opt) , null_option_(null_opt)
, value_(type, attr.size()) , value_(type, attr.size()) {
{} }
attribute_definition::attribute_definition(std::string name, attribute_definition::attribute_definition(std::string name,
const utils::basic_type type, const utils::basic_type type,
const size_t index, const size_t index,
std::string ref_table, const std::shared_ptr<attribute_definition> &ref_column,
std::string ref_column, const utils::field_attributes &attr, const null_option null_opt)
const utils::field_attributes& attr, const null_option null_opt)
: name_(std::move(name)) : name_(std::move(name))
, index_(index) , index_(index)
, attributes_(attr) , attributes_(attr)
, null_option_(null_opt) , null_option_(null_opt)
, value_(type, attr.size()) , value_(type, attr.size())
, ref_table_(std::move(ref_table)) , reference_column_(ref_column) {
, ref_column_(std::move(ref_column)) }
{}
const std::string &attribute_definition::name() const const std::string &attribute_definition::name() const {
{
return name_; return name_;
} }
std::string attribute_definition::full_name() const std::string attribute_definition::full_name() const {
{
return table_ + "." + name_; return table_ + "." + name_;
} }
std::string attribute_definition::table_name() const std::string attribute_definition::table_name() const {
{
return table_; return table_;
} }
int attribute_definition::index() const int attribute_definition::index() const {
{
return index_; return index_;
} }
const utils::field_attributes &attribute_definition::attributes() const const utils::field_attributes &attribute_definition::attributes() const {
{
return attributes_; return attributes_;
} }
bool attribute_definition::is_nullable() const bool attribute_definition::is_nullable() const {
{
return null_option_ == null_option::NULLABLE; return null_option_ == null_option::NULLABLE;
} }
utils::basic_type attribute_definition::type() const utils::basic_type attribute_definition::type() const {
{
return value_.type(); return value_.type();
} }
const std::string &attribute_definition::ref_table() const std::shared_ptr<attribute_definition> attribute_definition::reference_column() const {
{ return reference_column_;
return ref_table_;
} }
const std::string &attribute_definition::ref_column() const bool attribute_definition::is_foreign_reference() const {
{ return reference_column_ != nullptr;
return ref_column_;
} }
bool attribute_definition::is_foreign_reference() const bool attribute_definition::is_integer() const {
{
return !ref_column_.empty() && !ref_table_.empty();
}
bool attribute_definition::is_integer() const
{
return value_.is_integer(); return value_.is_integer();
} }
bool attribute_definition::is_floating_point() const bool attribute_definition::is_floating_point() const {
{
return value_.is_floating_point(); return value_.is_floating_point();
} }
bool attribute_definition::is_bool() const bool attribute_definition::is_bool() const {
{
return value_.is_bool(); return value_.is_bool();
} }
bool attribute_definition::is_string() const bool attribute_definition::is_string() const {
{
return value_.is_string(); return value_.is_string();
} }
bool attribute_definition::is_varchar() const bool attribute_definition::is_varchar() const {
{
return value_.is_varchar(); return value_.is_varchar();
} }
bool attribute_definition::is_date() const bool attribute_definition::is_date() const {
{
return value_.is_date(); return value_.is_date();
} }
bool attribute_definition::is_time() const bool attribute_definition::is_time() const {
{
return value_.is_time(); return value_.is_time();
} }
bool attribute_definition::is_blob() const bool attribute_definition::is_blob() const {
{
return value_.is_blob(); return value_.is_blob();
} }
bool attribute_definition::is_null() const bool attribute_definition::is_null() const {
{
return value_.is_null(); return value_.is_null();
} }
void attribute_definition::type(utils::basic_type /*type*/) void attribute_definition::type(utils::basic_type /*type*/) {
{
// type_ = type; // type_ = type;
// utils::initialize_by_utils::basic_type(type, value_); // utils::initialize_by_utils::basic_type(type, value_);
} }
std::string attribute_definition::str() const std::string attribute_definition::str() const {
{
return value_.str(); return value_.str();
} }
std::ostream& operator<<(std::ostream &out, const attribute_definition &col) std::ostream &operator<<(std::ostream &out, const attribute_definition &col) {
{
out << col.str(); out << col.str();
return out; return out;
} }
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr, null_option null_opt) attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr,
{ null_option null_opt) {
return {name, type, attr, null_opt}; return {name, type, attr, null_opt};
} }
template<> template<>
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt) attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr,
{ null_option null_opt) {
return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt); return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt);
} }
template<> template<>
attribute_definition make_pk_column<std::string>(const std::string &name, size_t size) attribute_definition make_pk_column<std::string>(const std::string &name, size_t size) {
{
return make_column<std::string>(name, {size, utils::constraints::FOREIGN_KEY}); return make_column<std::string>(name, {size, utils::constraints::FOREIGN_KEY});
} }
template<> template<>
[[maybe_unused]] attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, [[maybe_unused]] attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column) {
const std::string &ref_column) return {
{ name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
return {name, utils::data_type_traits<std::string>::type(size), 0, ref_table, ref_column, {size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL}; {size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL
};
} }
} }

View File

@ -18,7 +18,7 @@ void attribute_definition_generator::on_revision(const char *id, uint64_t &rev)
on_attribute(id, rev); on_attribute(id, rev);
} }
std::pair<std::string, std::string> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti) std::shared_ptr<attribute_definition> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti)
{ {
return repo_.reference(ti).value(); return repo_.reference(ti).value();
} }

View File

@ -5,11 +5,15 @@
#include <algorithm> #include <algorithm>
namespace matador::object { namespace matador::object {
basic_object_info::basic_object_info(schema_node &node,
basic_object_info::basic_object_info(schema_node &node, const std::type_index type_index, object_definition &&definition) const std::type_index type_index,
object_definition &&definition,
std::shared_ptr<attribute_definition> &&reference_column)
: node_(node) : node_(node)
, type_index_(type_index) , type_index_(type_index)
, definition_(std::move(definition)) {} , definition_(std::move(definition))
, reference_column_(std::move(reference_column)) {
}
std::type_index basic_object_info::type_index() const { std::type_index basic_object_info::type_index() const {
return type_index_; return type_index_;
@ -19,8 +23,12 @@ std::string basic_object_info::name() const {
return node_.name(); return node_.name();
} }
const object_definition& basic_object_info::definition() const { const object_definition &basic_object_info::definition() const {
return definition_; return definition_;
} }
std::shared_ptr<attribute_definition> basic_object_info::reference_column() const {
return reference_column_;
}
} // namespace matador::object } // namespace matador::object

View File

@ -1,14 +1,13 @@
#include "matador/object/schema.hpp" #include "matador/object/schema.hpp"
namespace matador::object { namespace matador::object {
utils::error make_error(const error_code ec, const std::string &msg) {
utils::error make_error(const error_code ec, const std::string& msg) {
return utils::error(ec, msg); return utils::error(ec, msg);
} }
schema::schema( const std::string& name) schema::schema(const std::string &name)
: name_(name) : name_(name)
, root_(std::shared_ptr<schema_node>(new schema_node(*this))) { , root_(std::shared_ptr<schema_node>(new schema_node(*this))) {
root_->first_child_ = 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_->last_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
root_->first_child_->next_sibling_ = root_->last_child_; root_->first_child_->next_sibling_ = root_->last_child_;
@ -35,16 +34,18 @@ std::string schema::name() const {
return name_; return name_;
} }
utils::result<std::pair<std::string, std::string>, utils::error> schema::reference( const std::type_index& type_index ) const { utils::result<std::shared_ptr<attribute_definition>, utils::error> schema::reference(const std::type_index &type_index) const {
const auto result = find_node(type_index); const auto result = find_node(type_index);
if (!result) { if (!result) {
return utils::failure(result.err()); return utils::failure(result.err());
} }
if (!result->get()->basic_info().definition().has_primary_key()) {
return utils::failure(make_error( error_code::Failure, "Primary key not found" )); const auto &node = *result;
if (!node->basic_info().definition().has_primary_key()) {
return utils::failure(make_error(error_code::Failure, "Primary key not found"));
} }
return utils::ok(std::make_pair(result->get()->name(), result->get()->basic_info().definition().primary_key()->name())); return utils::ok(std::make_pair(node->name(), node->basic_info().definition().primary_key()->name()));
} }
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node, utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
@ -72,8 +73,8 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(co
return utils::ok(node); return utils::ok(node);
} }
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node( const std::shared_ptr<schema_node>& 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 ) { const std::type_index &type_index) {
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.")); return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
} }
@ -100,10 +101,11 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(cons
return utils::ok(i->second); 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<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); const auto i = type_index_node_map_.find(type_index);
if (i == type_index_node_map_.end()) { 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::failure(make_error(error_code::NodeNotFound,
"Couldn't find node by type '" + std::string(type_index.name()) + "'"));
} }
return utils::ok(i->second); return utils::ok(i->second);
} }
@ -124,8 +126,15 @@ void schema::push_back_child(const node_ptr &parent, const node_ptr &child) {
// child->depth = depth + 1; // child->depth = depth + 1;
} }
bool schema::has_node(const std::string &name) const {
return node_map_.count(name) > 0;
}
bool schema::has_node(const std::type_index &index) const {
return type_index_node_map_.count(index) > 0;
}
bool schema::has_node(const std::type_index &index, const std::string &name) const { 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; return node_map_.count(name) > 0 || type_index_node_map_.count(index) > 0;
} }
} // namespace matador::object } // namespace matador::object

View File

@ -3,11 +3,25 @@
#include "matador/object/schema_node.hpp" #include "matador/object/schema_node.hpp"
namespace matador::object { namespace matador::object {
schema_node::schema_node(schema &tree)
schema_node::schema_node(object::schema &tree)
: schema_(tree) : schema_(tree)
, info_(std::make_unique<null_info>(*this, object_definition{})) , info_(std::make_unique<null_info>(*this, object_definition{})) {
{} }
schema_node::schema_node(schema &tree, std::string name, std::unique_ptr<basic_object_info> &&info)
: schema_(tree)
, info_(std::move(info))
// , info_(std::make_unique<object_info<Type>>(*this, object_definition(attribute_definition_generator::generate<Type>(schema_))))
, first_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
, last_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
, name_(std::move(name)) {
first_child_->next_sibling_ = last_child_;
last_child_->previous_sibling_ = first_child_;
}
std::shared_ptr<schema_node> schema_node::make_node(schema &tree, const std::string &name, std::unique_ptr<basic_object_info> &&info) {
return std::shared_ptr<schema_node>(new schema_node(tree, name, std::move(info)));
}
std::string schema_node::name() const { std::string schema_node::name() const {
return name_; return name_;
@ -17,7 +31,7 @@ std::type_index schema_node::type_index() const {
return info_->type_index(); return info_->type_index();
} }
const basic_object_info& schema_node::basic_info() const { const basic_object_info &schema_node::basic_info() const {
return *info_; return *info_;
} }
@ -53,5 +67,4 @@ schema_node::node_ptr schema_node::prev() const {
// is the parent of the node // is the parent of the node
return parent_->parent_ ? parent_ : parent_->first_child_->next_sibling_; return parent_->parent_ ? parent_ : parent_->first_child_->next_sibling_;
} }
} }