From 0d93b9b1edafebabc1e315e3c96705300f268054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Mon, 14 Jul 2025 15:57:14 +0200 Subject: [PATCH] attaching schema nodes progress --- demo/work.cpp | 17 +++++-- .../matador/object/attribute_definition.hpp | 5 +- .../object/attribute_definition_generator.hpp | 39 +++++++++++----- include/matador/object/basic_object_info.hpp | 5 +- include/matador/object/object_info.hpp | 12 ++--- include/matador/object/relation_completer.hpp | 26 +++++------ include/matador/object/schema.hpp | 11 +++-- include/matador/object/schema_node.hpp | 31 +++++++++---- .../matador/object/schema_node_iterator.hpp | 12 ++--- include/matador/utils/error.hpp | 2 +- source/core/object/attribute_definition.cpp | 8 ++++ .../object/attribute_definition_generator.cpp | 8 +++- source/core/object/basic_object_info.cpp | 13 ++---- source/core/object/schema.cpp | 6 +-- source/core/object/schema_node.cpp | 46 ++++++++++++++++--- source/core/object/schema_node_iterator.cpp | 10 ++-- source/core/utils/error.cpp | 11 +++-- source/orm/orm/session.cpp | 9 +++- source/orm/query/query_compiler.cpp | 2 +- 19 files changed, 182 insertions(+), 91 deletions(-) diff --git a/demo/work.cpp b/demo/work.cpp index d6283d9..1c939dd 100644 --- a/demo/work.cpp +++ b/demo/work.cpp @@ -70,9 +70,13 @@ using namespace work::models; // payload.is_polymorphic_type(); int main() { + logger::default_min_log_level(logger::log_level::LVL_DEBUG); + logger::add_log_sink(logger::create_stdout_sink()); + const object::schema schema("Administration"); - sql::connection_pool pool("postgres://test:test123!@127.0.0.1:5432/matador", 4); + sql::connection_pool pool("postgres://news:news@127.0.0.1:15432/matador", 4); + // sql::connection_pool pool("postgres://test:test123!@127.0.0.1:5432/matador", 4); orm::session ses(pool); @@ -92,14 +96,20 @@ int main() { .and_then([&ses] { return ses.attach("id_list_payloads"); }) .and_then([&ses] { return ses.attach("id_payloads"); }) .and_then([&ses] { return ses.attach("tasks"); }) - .and_then([&ses] { return ses.create_schema(); }); + ; + // ses.dump_schema(std::cout); if (!result) { std::cout << "error: " << result.err().message() << std::endl; return 0; } - ses.dump_schema(std::cout); + result = ses.create_schema(); + if (!result) { + std::cout << "error: " << result.err() << std::endl; + return 0; + } + // const std::string dns{"sqlite://demo.db"}; // sql::connection c(dns); // @@ -110,7 +120,6 @@ int main() { // return 0; // } - return 0; } diff --git a/include/matador/object/attribute_definition.hpp b/include/matador/object/attribute_definition.hpp index 75413f7..c32b31d 100644 --- a/include/matador/object/attribute_definition.hpp +++ b/include/matador/object/attribute_definition.hpp @@ -25,6 +25,7 @@ public: attribute_definition(attribute_definition&&) noexcept = default; attribute_definition& operator=(attribute_definition&&) noexcept = default; + attribute_definition() = default; template explicit attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr) : attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits::type(attr.size()), attr) @@ -61,8 +62,10 @@ public: void name(const std::string& n); [[nodiscard]] std::string full_name() const; [[nodiscard]] std::string table_name() const; + void table_name(const std::string& tn); [[nodiscard]] int index() const; [[nodiscard]] const utils::field_attributes& attributes() const; + [[nodiscard]] utils::field_attributes& attributes(); [[nodiscard]] bool is_nullable() const; [[nodiscard]] utils::basic_type type() const; [[nodiscard]] std::shared_ptr reference_column() const; @@ -141,7 +144,7 @@ private: * @param type * @param attr Length of the column name * @param null_opt - * @return A column object with given name + * @return A column object with a given name */ attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL); diff --git a/include/matador/object/attribute_definition_generator.hpp b/include/matador/object/attribute_definition_generator.hpp index ca3ad96..32126f3 100644 --- a/include/matador/object/attribute_definition_generator.hpp +++ b/include/matador/object/attribute_definition_generator.hpp @@ -1,13 +1,13 @@ #ifndef QUERY_COLUMN_DEFINITION_GENERATOR_HPP #define QUERY_COLUMN_DEFINITION_GENERATOR_HPP -#include "attribute_definition.hpp" +#include "matador/object/attribute_definition.hpp" #include "matador/utils/access.hpp" #include "matador/utils/data_type_traits.hpp" #include "matador/utils/error.hpp" #include "matador/utils/field_attributes.hpp" -#include "matador/utils/foreign_attributes.hpp" + #include #include @@ -54,13 +54,13 @@ private: class attribute_definition_generator final { private: - attribute_definition_generator(std::vector &columns, const schema &repo); + attribute_definition_generator(std::vector &columns, schema &repo); public: ~attribute_definition_generator() = default; template < class Type > - static std::vector generate(const schema &repo) + static std::vector generate(schema &repo) { std::vector columns; attribute_definition_generator gen(columns, repo); @@ -69,6 +69,14 @@ public: return columns; } + template < class Type > + static std::vector generate(const Type& obj, schema &repo) { + std::vector columns; + attribute_definition_generator gen(columns, repo); + access::process(gen, obj); + return columns; + } + template < class V > void on_primary_key(const char *, V &x, std::enable_if_t && !std::is_same_v>* = nullptr); void on_primary_key(const char *id, std::string &pk, size_t size); @@ -91,13 +99,19 @@ public: template void on_foreign_key(const char *id, Pointer &x) { - if (const auto result = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)))) { - if (x.empty()) { - typename Pointer::value_type temp_val; - columns_.push_back(fk_column_generator_.generate(id, temp_val, *result)); - } else { - columns_.push_back(fk_column_generator_.generate(id, *x, *result)); - } + std::shared_ptr ref_column; + std::type_index ti = typeid(typename Pointer::value_type); + if (const auto result = determine_foreign_ref(std::type_index(ti))) { + ref_column = *result; + } else { + ref_column = std::make_shared(); + insert_missing_reference_column(ti, ref_column); + } + if (x.empty()) { + typename Pointer::value_type temp_val; + columns_.push_back(fk_column_generator_.generate(id, temp_val, ref_column)); + } else { + columns_.push_back(fk_column_generator_.generate(id, *x, ref_column)); } } template @@ -109,11 +123,12 @@ public: private: [[nodiscard]] utils::result, utils::error> determine_foreign_ref(const std::type_index &ti) const; + void insert_missing_reference_column(const std::type_index &ti, std::shared_ptr ref_column) const; private: size_t index_ = 0; std::vector &columns_; - const schema &repo_; + schema &repo_; fk_attribute_generator fk_column_generator_; }; diff --git a/include/matador/object/basic_object_info.hpp b/include/matador/object/basic_object_info.hpp index 06e4589..bbc28ff 100644 --- a/include/matador/object/basic_object_info.hpp +++ b/include/matador/object/basic_object_info.hpp @@ -49,13 +49,12 @@ public: [[nodiscard]] bool endpoints_empty() const; protected: - basic_object_info(std::shared_ptr node, std::type_index type_index, utils::identifier &&pk, std::shared_ptr &&pk_column, object_definition &&definition); - basic_object_info(std::shared_ptr node, std::type_index type_index, utils::identifier &&pk, std::shared_ptr &&pk_column); + basic_object_info(std::shared_ptr node, std::type_index type_index, utils::identifier &&pk, const std::shared_ptr &pk_column, object_definition &&definition); + basic_object_info(std::shared_ptr node, std::type_index type_index, utils::identifier &&pk, const std::shared_ptr &pk_column); basic_object_info(std::shared_ptr node, std::type_index type_index, object_definition &&definition); protected: std::shared_ptr node_; /**< prototype node of the represented object type */ - std::type_index type_index_; /**< type index of the represented object type */ object_definition definition_; std::optional identifier_; std::shared_ptr pk_column_; diff --git a/include/matador/object/object_info.hpp b/include/matador/object/object_info.hpp index ad08f1e..eba9bdf 100644 --- a/include/matador/object/object_info.hpp +++ b/include/matador/object/object_info.hpp @@ -13,23 +13,23 @@ public: using create_func = std::function()>; object_info(const std::shared_ptr& node, - std::shared_ptr &&ref_column) - : basic_object_info(node, typeid(Type), {}, std::move(ref_column), {}) + const std::shared_ptr &ref_column) + : basic_object_info(node, typeid(Type), {}, ref_column, {}) , creator_([]{return std::make_unique(); }){ } object_info(const std::shared_ptr& node, utils::identifier &&pk, - std::shared_ptr &&ref_column, + const std::shared_ptr &ref_column, object_definition &&definition) - : basic_object_info(node, typeid(Type), std::move(pk), std::move(ref_column), std::move(definition)) + : basic_object_info(node, typeid(Type), std::move(pk), ref_column, std::move(definition)) , creator_([]{return std::make_unique(); }){ } object_info(const std::shared_ptr& node, utils::identifier &&pk, - std::shared_ptr &&ref_column, + const std::shared_ptr &ref_column, object_definition &&definition, create_func&& creator) - : basic_object_info(node, typeid(Type), std::move(pk), std::move(ref_column), std::move(definition)) + : basic_object_info(node, typeid(Type), std::move(pk), ref_column, std::move(definition)) , creator_(std::move(creator)){ } object_info(const std::shared_ptr& node, diff --git a/include/matador/object/relation_completer.hpp b/include/matador/object/relation_completer.hpp index f48ce45..852fe3f 100644 --- a/include/matador/object/relation_completer.hpp +++ b/include/matador/object/relation_completer.hpp @@ -129,17 +129,16 @@ void relation_completer::on_has_many(const char *id, CollectionType &, if (const auto endpoint = nodes_.top()->info().find_relation_endpoint(typeid(relation_value_type)); endpoint == nodes_.top()->info().endpoint_end()) { // Endpoint was not found log_.debug("node '%s' has has many foreign keys '%s' mapped by '%s'", nodes_.top()->name().c_str(), id, join_column); - const auto node = schema_node::make_relation_node( + result = schema_node::make_relation_node( schema_.schema(), id, [join_column] { - return std::make_unique(join_column, "id"); + return std::make_unique("id", join_column); }); - result = schema_.attach_node(node); if (!result) { // Todo: throw internal error return; } const auto local_endpoint = std::make_shared(id, relation_type::HAS_MANY, nodes_.top()); - const auto foreign_endpoint = std::make_shared(join_column, relation_type::BELONGS_TO, node); + const auto foreign_endpoint = std::make_shared(join_column, relation_type::BELONGS_TO, result.value()); nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint); foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), foreign_endpoint); link_relation_endpoints(local_endpoint, foreign_endpoint); @@ -171,18 +170,17 @@ void relation_completer::on_has_many(const char *id, CollectionType &, con using value_type = typename CollectionType::value_type; using relation_value_type = many_to_relation; - const auto node = schema_node::make_relation_node( + const auto result = schema_node::make_relation_node( schema_.schema(), id, [join_column] { return std::make_unique(join_column, "value"); }); - const auto result = schema_.attach_node(node); if (!result) { // Todo: throw internal exception } const auto local_endpoint = std::make_shared(id, relation_type::HAS_MANY, nodes_.top()); - const auto foreign_endpoint = std::make_shared(join_column, relation_type::BELONGS_TO, node); + const auto foreign_endpoint = std::make_shared(join_column, relation_type::BELONGS_TO, result.value()); nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint); foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), foreign_endpoint); link_relation_endpoints(local_endpoint, foreign_endpoint); @@ -210,13 +208,18 @@ void relation_completer::on_has_many_to_many(const char *id, } link_relation_endpoints(local_endpoint, it->second); } else { - // Relation not not found. + // Relation not found. auto creator = [join_column, inverse_join_column] { return std::make_unique(join_column, inverse_join_column); }; - auto node = schema_node::make_relation_node(schema_.schema(), id, std::move(creator)); + result = schema_node::make_relation_node(schema_.schema(), id, std::move(creator)); + if (!result) { + // Todo: throw internal error + return; + } + auto& node = result.value(); auto local_endpoint = std::make_shared(id, relation_type::HAS_MANY, nodes_.top()); auto join_endpoint = std::make_shared(join_column, relation_type::BELONGS_TO, node); auto inverse_join_endpoint = std::make_shared(inverse_join_column, relation_type::BELONGS_TO, @@ -226,11 +229,6 @@ void relation_completer::on_has_many_to_many(const char *id, link_relation_endpoints(local_endpoint, join_endpoint); node->info_->register_relation_endpoint(typeid(typename CollectionType::value_type::value_type), inverse_join_endpoint); - result = schema_.attach_node(node); - if (!result) { - // Todo: throw internal error - return; - } } } diff --git a/include/matador/object/schema.hpp b/include/matador/object/schema.hpp index b2514fd..6737231 100644 --- a/include/matador/object/schema.hpp +++ b/include/matador/object/schema.hpp @@ -40,11 +40,11 @@ public: [[nodiscard]] utils::result attach(const std::string &name, const std::string &parent = "") { if (const auto it = nodes_by_type_.find(typeid(Type)); it == nodes_by_type_.end() ) { auto node = schema_node::make_node(*this, name); - foreign_node_completer::complete(node); - relation_completer::complete(node); if (auto result = attach_node(node, parent); !result) { return utils::failure(result.err()); } + foreign_node_completer::complete(node); + relation_completer::complete(node); } else if (!has_node(name)) { it->second->update_name(name); nodes_by_name_[name] = it->second; @@ -142,7 +142,7 @@ public: return utils::ok(basic_object_info_ref{result.value()->info()}); } - [[nodiscard]] utils::result, utils::error> reference( + [[nodiscard]] utils::result, utils::error> reference_column( const std::type_index &type_index) const; void dump(std::ostream &os) const; @@ -169,7 +169,8 @@ private: private: friend class internal::shadow_schema; - friend class foreign_node_completer; + friend class schema_node; + friend class attribute_definition_generator; std::string name_; std::shared_ptr root_; @@ -177,6 +178,8 @@ private: t_node_map nodes_by_name_; t_type_index_node_map nodes_by_type_; logger::logger log_; + + std::unordered_map > missing_references_; }; } diff --git a/include/matador/object/schema_node.hpp b/include/matador/object/schema_node.hpp index e268bde..662c8cb 100644 --- a/include/matador/object/schema_node.hpp +++ b/include/matador/object/schema_node.hpp @@ -18,14 +18,15 @@ public: template < typename Type > static std::shared_ptr make_node(object::schema& tree, const std::string& name) { - auto node = std::shared_ptr(new schema_node(tree, name)); + auto node = std::shared_ptr(new schema_node(tree, name, typeid(Type))); primary_key_resolver resolver; auto pk_info = resolver.resolve(); + auto ref_column = determine_reference_column(typeid(Type), name, pk_info, tree); auto info = std::make_unique>( node, std::move(pk_info.pk), - std::make_shared(pk_info.pk_column_name, name, pk_info.type, utils::constraints::FOREIGN_KEY), + ref_column, object_definition{attribute_definition_generator::generate(tree)}, []{ return std::make_unique(); } ); @@ -35,17 +36,21 @@ public: } template < typename Type, typename CreatorFunc > - static std::shared_ptr make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) { - auto node = std::shared_ptr(new schema_node(tree, name)); + static utils::result make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) { + const auto result = make_and_attach_node(tree, name, typeid(Type)); + if (!result) { + return result; + } + auto obj = creator(); auto info = std::make_unique>( - node, - object_definition{attribute_definition_generator::generate(tree)}, + result.value(), + object_definition{attribute_definition_generator::generate(*obj, tree)}, std::move(creator) ); - node->info_ = std::move(info); + result.value()->info_ = std::move(info); - return node; + return result; } static std::shared_ptr make_null_node(schema& tree); @@ -77,10 +82,17 @@ public: private: explicit schema_node(object::schema& tree); - schema_node(object::schema& tree, std::string name); + schema_node(object::schema& tree, const std::type_index& ti); + schema_node(object::schema& tree, std::string name, const std::type_index& ti); void unlink(); + static utils::result make_and_attach_node(object::schema& tree, const std::string& name, const std::type_index& ti); + static std::shared_ptr determine_reference_column(const std::type_index& ti, + const std::string& name, + const primary_key_info& pk_info, + object::schema& tree); + private: friend class schema; template @@ -89,6 +101,7 @@ private: friend class const_schema_node_iterator; object::schema &schema_; + std::type_index type_index_; std::unique_ptr info_; std::shared_ptr parent_; diff --git a/include/matador/object/schema_node_iterator.hpp b/include/matador/object/schema_node_iterator.hpp index 2bc64d9..1ca0149 100644 --- a/include/matador/object/schema_node_iterator.hpp +++ b/include/matador/object/schema_node_iterator.hpp @@ -11,9 +11,9 @@ class const_schema_node_iterator { public: using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; - using value_type = schema_node; - using pointer = value_type*; - using reference = value_type&; + using value_type = std::shared_ptr; + using pointer = schema_node*; + using reference = value_type; /** * Creates an empty iterator @@ -28,7 +28,7 @@ public: * * @param node The schema node of the object */ - explicit const_schema_node_iterator(std::shared_ptr node); + explicit const_schema_node_iterator(const value_type& node); /** * Copy from a given const_object_view_iterator. @@ -109,7 +109,7 @@ public: * * @return The iterators underlying node. */ - const reference operator*() const; + reference operator*() const; /** * Returns the pointer to the node. @@ -123,7 +123,7 @@ private: void decrement(); private: - std::shared_ptr node_; + value_type node_; }; } diff --git a/include/matador/utils/error.hpp b/include/matador/utils/error.hpp index 95fbe54..54942b6 100644 --- a/include/matador/utils/error.hpp +++ b/include/matador/utils/error.hpp @@ -50,7 +50,7 @@ public: friend bool operator<(const error &lhs, const error &rhs); friend bool operator<(const error &lhs, const std::error_code &rhs); - // friend std::ostream& operator<<(std::ostream &out, const error &err); + friend std::ostream& operator<<(std::ostream &out, const error &err); [[nodiscard]] std::string message() const; [[nodiscard]] std::string category() const; diff --git a/source/core/object/attribute_definition.cpp b/source/core/object/attribute_definition.cpp index bb0569d..cbd9c5b 100644 --- a/source/core/object/attribute_definition.cpp +++ b/source/core/object/attribute_definition.cpp @@ -77,6 +77,10 @@ std::string attribute_definition::table_name() const { return table_; } +void attribute_definition::table_name( const std::string& tn ) { + table_= tn; +} + int attribute_definition::index() const { return index_; } @@ -85,6 +89,10 @@ const utils::field_attributes &attribute_definition::attributes() const { return attributes_; } +utils::field_attributes& attribute_definition::attributes() { + return attributes_; +} + bool attribute_definition::is_nullable() const { return null_option_ == null_option::NULLABLE; } diff --git a/source/core/object/attribute_definition_generator.cpp b/source/core/object/attribute_definition_generator.cpp index 1a27b63..7e82537 100644 --- a/source/core/object/attribute_definition_generator.cpp +++ b/source/core/object/attribute_definition_generator.cpp @@ -3,7 +3,7 @@ namespace matador::object { -attribute_definition_generator::attribute_definition_generator(std::vector &columns, const schema &repo) +attribute_definition_generator::attribute_definition_generator(std::vector &columns, schema &repo) : columns_(columns) , repo_(repo) {} @@ -19,7 +19,11 @@ void attribute_definition_generator::on_revision(const char *id, uint64_t &rev) } utils::result, utils::error> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti) const { - return repo_.reference(ti); + return repo_.reference_column(ti); +} + +void attribute_definition_generator::insert_missing_reference_column(const std::type_index& ti, std::shared_ptr ref_column) const { + repo_.missing_references_.insert({ti, ref_column}); } void fk_attribute_generator::on_primary_key(const char *, std::string &, const size_t size) diff --git a/source/core/object/basic_object_info.cpp b/source/core/object/basic_object_info.cpp index 61cb13d..807e519 100644 --- a/source/core/object/basic_object_info.cpp +++ b/source/core/object/basic_object_info.cpp @@ -8,34 +8,31 @@ namespace matador::object { basic_object_info::basic_object_info(std::shared_ptr node, const std::type_index type_index, utils::identifier &&pk, - std::shared_ptr &&pk_column, + const std::shared_ptr &pk_column, object_definition &&definition) : node_(std::move(node)) -, type_index_(type_index) , definition_(std::move(definition)) , identifier_(std::move(pk)) -, pk_column_(std::move(pk_column)) { +, pk_column_(pk_column) { } basic_object_info::basic_object_info(std::shared_ptr node, const std::type_index type_index, utils::identifier &&pk, - std::shared_ptr &&pk_column) + const std::shared_ptr &pk_column) : node_(std::move(node)) -, type_index_(type_index) , identifier_(std::move(pk)) -, pk_column_(std::move(pk_column)) { +, pk_column_(pk_column) { } basic_object_info::basic_object_info(std::shared_ptr node, const std::type_index type_index, object_definition &&definition) : node_(std::move(node)) -, type_index_(type_index) , definition_(std::move(definition)) {} std::type_index basic_object_info::type_index() const { - return type_index_; + return node_->type_index(); } std::string basic_object_info::name() const { diff --git a/source/core/object/schema.cpp b/source/core/object/schema.cpp index a76b4dc..35deb42 100644 --- a/source/core/object/schema.cpp +++ b/source/core/object/schema.cpp @@ -53,7 +53,7 @@ bool schema::contains( const std::type_index& index ) const { return nodes_by_type_.count(index) > 0; } -utils::result, utils::error> schema::reference(const std::type_index &type_index) const { +utils::result, utils::error> schema::reference_column(const std::type_index &type_index) const { const auto result = find_node(type_index); if (result) { return utils::ok((*result)->info().reference_column()); @@ -64,8 +64,8 @@ utils::result, utils::error> schema::refer void schema::dump(std::ostream &os) const { for (const auto &node : *this) { - os << "node [" << node.name() << "] (" << node.type_index().name() << ")\n"; - for (auto it = node.info().endpoint_begin(); it != node.info().endpoint_end(); ++it) { + os << "node [" << node->name() << "] (" << node->type_index().name() << ")\n"; + for (auto it = node->info().endpoint_begin(); it != node->info().endpoint_end(); ++it) { os << " " << /*node.name() << "::" <<*/ it->second->field_name() << " (" << it->second->type_name() << ")"; if (it->second->foreign_endpoint()) { os << " <---> " << it->second->foreign_endpoint()->node().name() << "::" << it->second->foreign_endpoint()->field_name() << " (" << it->second->foreign_endpoint()->type_name() << ")\n"; diff --git a/source/core/object/schema_node.cpp b/source/core/object/schema_node.cpp index 32d01e3..1fb7e16 100644 --- a/source/core/object/schema_node.cpp +++ b/source/core/object/schema_node.cpp @@ -1,14 +1,22 @@ #include +#include "matador/object/schema.hpp" #include "matador/object/schema_node.hpp" namespace matador::object { schema_node::schema_node(object::schema &tree) -: schema_(tree) { +: schema_(tree) +, type_index_(typeid(detail::null_type)){ } -schema_node::schema_node(object::schema &tree, std::string name) +schema_node::schema_node(object::schema &tree, const std::type_index& ti) : schema_(tree) +, type_index_(ti) { +} + +schema_node::schema_node(object::schema &tree, std::string name, const std::type_index& ti) +: schema_(tree) +, type_index_(ti) , first_child_(std::shared_ptr(new schema_node(tree))) , last_child_(std::shared_ptr(new schema_node(tree))) , name_(std::move(name)) { @@ -28,7 +36,7 @@ std::string schema_node::name() const { } std::type_index schema_node::type_index() const { - return info_->type_index(); + return type_index_; } const basic_object_info &schema_node::info() const { @@ -37,7 +45,7 @@ const basic_object_info &schema_node::info() const { void schema_node::update_name(const std::string& name) { name_ = name; - info_->reference_column()->name(name); + info_->reference_column()->table_name(name); } const object::schema& schema_node::schema() const { @@ -50,7 +58,7 @@ bool schema_node::has_children() const { 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 we don't iterate over the siblings) if (first_child_ && first_child_->next_sibling_ != last_child_) { return first_child_->next_sibling_; } @@ -65,7 +73,7 @@ schema_node::node_ptr schema_node::next() const { } schema_node::node_ptr schema_node::prev() const { - // if node has a previous sibling, we set it + // if the 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 @@ -87,4 +95,30 @@ void schema_node::unlink() { next_sibling_.reset(); previous_sibling_.reset(); } + +utils::result schema_node::make_and_attach_node(object::schema& tree, const std::string& name, const std::type_index& ti) { + const auto node = std::shared_ptr(new schema_node(tree, name, ti)); + + return tree.attach_node(node, ""); +} + +std::shared_ptr schema_node::determine_reference_column(const std::type_index& ti, const std::string& name, const primary_key_info& pk_info, object::schema& tree) { + const auto it = tree.missing_references_.find(ti); + if (it == tree.missing_references_.end()) { + return std::make_shared(pk_info.pk_column_name, name, pk_info.type, utils::constraints::FOREIGN_KEY); + } + + auto ref_column = it->second; + tree.missing_references_.erase(it); + ref_column->name(pk_info.pk_column_name); + ref_column->table_name(name); + ref_column->type(pk_info.type); + ref_column->attributes() = utils::constraints::FOREIGN_KEY; + + if (name.empty()) { + tree.missing_references_.insert({ti, ref_column}); + } + + return ref_column; +} } diff --git a/source/core/object/schema_node_iterator.cpp b/source/core/object/schema_node_iterator.cpp index 82f1e97..cd522f1 100644 --- a/source/core/object/schema_node_iterator.cpp +++ b/source/core/object/schema_node_iterator.cpp @@ -4,8 +4,8 @@ namespace matador::object { -const_schema_node_iterator::const_schema_node_iterator(std::shared_ptr node) -: node_(std::move(node)) +const_schema_node_iterator::const_schema_node_iterator(const value_type& node) +: node_(node) {} bool const_schema_node_iterator::operator==(const const_schema_node_iterator &i) const @@ -25,7 +25,7 @@ const_schema_node_iterator& const_schema_node_iterator::operator++() } const_schema_node_iterator const_schema_node_iterator::operator++( int ) { - const std::shared_ptr tmp = node_; + const value_type tmp = node_; increment(); return const_schema_node_iterator(tmp); } @@ -38,7 +38,7 @@ const_schema_node_iterator& const_schema_node_iterator::operator--() const_schema_node_iterator const_schema_node_iterator::operator--(int) { - const std::shared_ptr tmp = node_; + const value_type tmp = node_; decrement(); return const_schema_node_iterator(tmp); } @@ -50,7 +50,7 @@ const_schema_node_iterator::pointer const_schema_node_iterator::operator->() con const_schema_node_iterator::reference const_schema_node_iterator::operator*() const { - return *node_; + return node_; } const_schema_node_iterator::pointer const_schema_node_iterator::get() const diff --git a/source/core/utils/error.cpp b/source/core/utils/error.cpp index baf4c7b..9ae4bbe 100644 --- a/source/core/utils/error.cpp +++ b/source/core/utils/error.cpp @@ -81,9 +81,12 @@ bool operator<(const error &lhs, const std::error_code &rhs) { return lhs.ec_ < rhs; } -// std::ostream & operator<<(std::ostream &out, const error &err) { - // out << err.ec_ << " " << err.ec_.message(); - // return out; -// } +std::ostream & operator<<(std::ostream &out, const error &err) { + out << err.ec_ << " " << err.ec_.message() << "\n"; + for (const auto & [key, value] : err.error_infos_) { + out << " " << key << ": " << value << "\n"; + } + return out; +} } diff --git a/source/orm/orm/session.cpp b/source/orm/orm/session.cpp index 0276ecc..24d9f53 100644 --- a/source/orm/orm/session.cpp +++ b/source/orm/orm/session.cpp @@ -18,10 +18,15 @@ session::session(sql::connection_pool &pool) , schema_(std::make_unique(dialect_.default_schema_name())){} utils::result session::create_schema() const { + std::vector> relations_nodes; auto c = pool_.acquire(); - for (const auto &t : *schema_) { + for (const auto &node : *schema_) { + // if (!node->info().has_primary_key()) { + // relations_nodes.push_back(node); + // continue; + // } auto result = query::query::create() - .table(t.name(), t.info().definition().columns()) + .table(node->name(), node->info().definition().columns()) .execute(*c); if ( !result ) { return utils::failure(result.err()); diff --git a/source/orm/query/query_compiler.cpp b/source/orm/query/query_compiler.cpp index 19efa79..4987254 100644 --- a/source/orm/query/query_compiler.cpp +++ b/source/orm/query/query_compiler.cpp @@ -276,7 +276,7 @@ void query_compiler::visit(internal::query_create_table_part &create_table_part) for (const auto &[column, reference_column]: context.foreign_contexts) { result += ", CONSTRAINT FK_" + create_table_part.table().name; result += "_" + column; - result += " FOREIGN KEY (" + column + ")"; + result += " FOREIGN KEY (" + dialect_->prepare_identifier_string(column) + ")"; result += " REFERENCES " + reference_column->table_name() + "(" + reference_column->name() + ")"; }