diff --git a/include/matador/object/basic_object_info.hpp b/include/matador/object/basic_object_info.hpp index e4b892c..93eea29 100644 --- a/include/matador/object/basic_object_info.hpp +++ b/include/matador/object/basic_object_info.hpp @@ -26,7 +26,7 @@ public: [[nodiscard]] std::type_index type_index() const; [[nodiscard]] std::string name() const; - [[nodiscard]] const class object& object() const; + [[nodiscard]] std::shared_ptr object() const; [[nodiscard]] const std::list& attributes() const; [[nodiscard]] const std::list& constraints() const; @@ -34,7 +34,7 @@ public: [[nodiscard]] const utils::identifier& primary_key() const; [[nodiscard]] attribute* primary_key_attribute() const; - void update_name(const std::string& name); + void update_name(const std::string& name) const; endpoint_iterator register_relation_endpoint(const std::type_index &type, const std::shared_ptr &endpoint); void unregister_relation_endpoint(const std::type_index &type); @@ -55,10 +55,10 @@ public: [[nodiscard]] bool endpoints_empty() const; protected: - basic_object_info(std::shared_ptr node, std::unique_ptr &&obj); + basic_object_info(std::shared_ptr node, std::shared_ptr &&obj); protected: - std::unique_ptr object_; + std::shared_ptr object_; std::shared_ptr node_; /**< prototype node of the represented object type */ t_endpoint_map relation_endpoints_; }; diff --git a/include/matador/object/constraint.hpp b/include/matador/object/constraint.hpp index 71be9a7..063dc99 100644 --- a/include/matador/object/constraint.hpp +++ b/include/matador/object/constraint.hpp @@ -23,7 +23,7 @@ public: [[nodiscard]] const std::string& name() const; [[nodiscard]] const class attribute* attribute() const; [[nodiscard]] std::string column_name() const; - [[nodiscard]] const object* owner() const; + [[nodiscard]] std::shared_ptr owner() const; [[nodiscard]] bool is_primary_key_constraint() const; [[nodiscard]] bool is_foreign_key_constraint() const; [[nodiscard]] bool is_unique_constraint() const; @@ -40,7 +40,8 @@ private: std::string name_; std::variant attr_; - object *owner_{nullptr}; + std::shared_ptr owner_; + std::shared_ptr reference_; utils::constraints options_{utils::constraints::None}; std::string ref_table_name_{}; std::string ref_column_name_{}; @@ -58,7 +59,6 @@ public: private: std::string constraint_name; utils::constraints options_{utils::constraints::None}; - std::shared_ptr reference_; std::string column_name; std::string ref_table_name; std::string ref_column_name; diff --git a/include/matador/object/constraints_generator.hpp b/include/matador/object/constraints_generator.hpp index 65f4b60..575d5d8 100644 --- a/include/matador/object/constraints_generator.hpp +++ b/include/matador/object/constraints_generator.hpp @@ -17,7 +17,7 @@ class repository; class constraints_generator final { private: - constraints_generator(std::list &constraints, const repository &repo, object &obj); + constraints_generator(std::list &constraints, const repository &repo, const std::shared_ptr &obj); public: constraints_generator() = delete; @@ -71,7 +71,7 @@ private: private: std::list &constraints_; const repository &repo_; - object &obj_; + std::shared_ptr obj_; }; } diff --git a/include/matador/object/object.hpp b/include/matador/object/object.hpp index 713af7e..b3fd7c5 100644 --- a/include/matador/object/object.hpp +++ b/include/matador/object/object.hpp @@ -19,8 +19,8 @@ public: static const attribute& create_attribute(std::string name, object& obj); - void add_attribute(attribute attr); - void add_constraint(class constraint c); + // void add_attribute(attribute attr); + // void add_constraint(class constraint c); [[nodiscard]] attribute* primary_key_attribute() const; [[nodiscard]] const utils::identifier& primary_key() const; diff --git a/include/matador/object/object_generator.hpp b/include/matador/object/object_generator.hpp index 805c653..534bb54 100644 --- a/include/matador/object/object_generator.hpp +++ b/include/matador/object/object_generator.hpp @@ -50,23 +50,22 @@ private: class object_generator { private: - explicit object_generator(const repository& repo, std::unique_ptr &&object); + explicit object_generator(repository& repo, const std::shared_ptr &object); public: template < class Type > - static std::unique_ptr generate(const repository &repo, const std::string &name, const std::string &alias = "") { + static std::shared_ptr generate(const repository &repo, const std::string &name, const std::string &alias = "") { return generate(std::make_unique(), repo, name, alias); } template < class Type > - static std::unique_ptr generate(std::unique_ptr&& t, const repository &repo, const std::string &name, const std::string &alias = "") { - object_generator gen(repo, std::make_unique(name, alias)); + static std::shared_ptr generate(std::unique_ptr&& t, repository &repo, const std::string &name, const std::string &alias = "") { + auto obj = std::make_shared(name, alias); + object_generator gen(repo, obj); access::process(gen, *t); - return gen.move(); + return obj; } - [[nodiscard]] std::unique_ptr move() { return std::move(object_); } - template < class Type > void on_primary_key(const char *, Type &x, const utils::primary_key_attribute& attr = utils::default_pk_attributes); void on_revision(const char *id, uint64_t &rev); @@ -114,9 +113,11 @@ private: void prepare_primary_key(attribute &ref, utils::identifier &&pk) const; + std::shared_ptr fk_object(const std::type_index& ti) const; + private: - const repository &repo_; - std::unique_ptr object_; + repository &repo_; + std::shared_ptr object_; }; template diff --git a/include/matador/object/object_info.hpp b/include/matador/object/object_info.hpp index 614bf83..1ff2eb0 100644 --- a/include/matador/object/object_info.hpp +++ b/include/matador/object/object_info.hpp @@ -14,7 +14,7 @@ public: using create_func = std::function()>; object_info(const std::shared_ptr& node, - std::unique_ptr &&obj, + std::shared_ptr &&obj, create_func&& creator) : basic_object_info(node, std::move(obj)) , creator_(std::move(creator)){ diff --git a/include/matador/object/repository.hpp b/include/matador/object/repository.hpp index cb55be2..11b4eb6 100644 --- a/include/matador/object/repository.hpp +++ b/include/matador/object/repository.hpp @@ -177,16 +177,22 @@ private: static void insert_node(const node_ptr &parent, const node_ptr &child); void remove_node(const node_ptr &node); - bool expecting_relation_node(const std::string &name) const; + [[nodiscard]] bool expecting_relation_node(const std::string &name) const; void expect_relation_node(const std::string &name, const std::type_index &ti); void remove_expected_relation_node(const std::string &name); + [[nodiscard]] std::shared_ptr provide_object_in_advance(const std::type_index &ti, const std::shared_ptr& obj); + [[nodiscard]] bool has_object_for_type(const std::type_index &ti) const; + [[nodiscard]] std::shared_ptr object_for_type(const std::type_index &ti) const; + void remove_object_for_type(const std::type_index &ti); + private: friend class internal::shadow_repository; friend class repository_node; friend class attribute_generator; template < typename NodeType > friend class foreign_node_completer; + friend class object_generator; std::string name_; std::shared_ptr root_; @@ -197,6 +203,7 @@ private: std::unordered_map missing_references_; std::unordered_map expected_relation_nodes_; + std::unordered_map> object_by_type_; }; } diff --git a/include/matador/query/column.hpp b/include/matador/query/column.hpp index 76375d8..bf01b6b 100644 --- a/include/matador/query/column.hpp +++ b/include/matador/query/column.hpp @@ -21,7 +21,7 @@ public: [[nodiscard]] bool equals(const column &x) const; - column& as(std::string a); + column as(std::string a); [[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& alias() const; @@ -33,7 +33,8 @@ public: [[nodiscard]] std::shared_ptr table() const; void table(const std::shared_ptr& t); - operator const std::string&() const; + // ReSharper disable once CppNonExplicitConversionOperator + operator const std::string&() const; // NOLINT(*-explicit-constructor) private: std::shared_ptr table_; diff --git a/include/matador/query/intermediates/query_create_intermediate.hpp b/include/matador/query/intermediates/query_create_intermediate.hpp index 768ac59..9ea5509 100644 --- a/include/matador/query/intermediates/query_create_intermediate.hpp +++ b/include/matador/query/intermediates/query_create_intermediate.hpp @@ -26,6 +26,8 @@ public: query_create_table_columns_intermediate columns(std::initializer_list columns); query_create_table_columns_intermediate columns(const std::list &columns); + query_create_table_columns_intermediate columns(std::initializer_list columns); + query_create_table_columns_intermediate columns(const std::list &columns); }; class query_create_intermediate : public query_intermediate { diff --git a/include/matador/query/table.hpp b/include/matador/query/table.hpp index a3ffd17..0a95ef1 100644 --- a/include/matador/query/table.hpp +++ b/include/matador/query/table.hpp @@ -10,6 +10,7 @@ namespace matador::query { class column; +// ReSharper disable CppNonExplicitConvertingConstructor class table { public: table() = default; @@ -18,7 +19,7 @@ public: table(std::string name, std::string as); table(std::string name, std::string as, const std::vector &columns); - table& as(const std::string &a); + table as(const std::string &a); [[nodiscard]] bool operator==(const table &x) const; @@ -30,9 +31,8 @@ public: [[nodiscard]] const std::string& alias() const; [[nodiscard]] const std::vector& columns() const; - // [[nodiscard]] class column column(const std::string &name) const; - - operator const std::vector&() const; + // ReSharper disable once CppNonExplicitConversionOperator + operator const std::vector&() const; // NOLINT(*-explicit-constructor) private: friend class column; diff --git a/source/core/object/basic_object_info.cpp b/source/core/object/basic_object_info.cpp index e9be1a0..4ed04a0 100644 --- a/source/core/object/basic_object_info.cpp +++ b/source/core/object/basic_object_info.cpp @@ -5,22 +5,7 @@ #include namespace matador::object { -// basic_object_info::basic_object_info(std::shared_ptr node, -// const std::vector &attributes, -// utils::identifier &&pk, -// const std::shared_ptr &pk_as_fk_column) -// : node_(std::move(node)) -// , attributes_(attributes) -// , identifier_(std::move(pk)) -// , pk_as_fk_column_(pk_as_fk_column) { -// } -// -// basic_object_info::basic_object_info(std::shared_ptr node, -// const std::vector &attributes) -// : node_(std::move(node)) -// , attributes_(attributes) {} - -basic_object_info::basic_object_info(std::shared_ptr node, std::unique_ptr&& obj) +basic_object_info::basic_object_info(std::shared_ptr node, std::shared_ptr&& obj) : object_(std::move(obj)) , node_(std::move(node)) {} @@ -32,8 +17,8 @@ std::string basic_object_info::name() const { return node_->name(); } -const class object & basic_object_info::object() const { - return *object_; +std::shared_ptr basic_object_info::object() const { + return object_; } const std::list& basic_object_info::attributes() const { @@ -56,7 +41,7 @@ attribute* basic_object_info::primary_key_attribute() const { return object_->primary_key_attribute(); } -void basic_object_info::update_name(const std::string& name) { +void basic_object_info::update_name(const std::string& name) const { object_->update_name(name); } @@ -112,4 +97,4 @@ std::size_t basic_object_info::endpoints_size() const { bool basic_object_info::endpoints_empty() const { return relation_endpoints_.empty(); } -} // namespace matador::object +} diff --git a/source/core/object/constraint.cpp b/source/core/object/constraint.cpp index 3ab0f19..d9369af 100644 --- a/source/core/object/constraint.cpp +++ b/source/core/object/constraint.cpp @@ -28,7 +28,7 @@ std::string constraint::column_name() const { return ""; } -const object* constraint::owner() const { +std::shared_ptr constraint::owner() const { return owner_; } diff --git a/source/core/object/constraints_generator.cpp b/source/core/object/constraints_generator.cpp index d1df6c2..7c8dcae 100644 --- a/source/core/object/constraints_generator.cpp +++ b/source/core/object/constraints_generator.cpp @@ -5,18 +5,18 @@ #include namespace matador::object { -constraints_generator::constraints_generator(std::list &constraints, const repository& repo, object &obj) +constraints_generator::constraints_generator(std::list &constraints, const repository& repo, const std::shared_ptr &obj) : constraints_(constraints) , repo_(repo) , obj_(obj) {} void constraints_generator::create_pk_constraint(const std::string& name) const { - class constraint pk_constraint("PK_" + obj_.name()); + class constraint pk_constraint("PK_" + obj_->name()); pk_constraint.options_ |= utils::constraints::PrimaryKey; - if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(obj_.attributes_)) { + if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(obj_->attributes_)) { pk_constraint.attr_ = &*pk_attr; } - pk_constraint.owner_ = &obj_; + pk_constraint.owner_ = obj_; constraints_.emplace_back(std::move(pk_constraint)); } @@ -26,28 +26,28 @@ void constraints_generator::create_fk_constraint(const std::type_index& ti, cons return; } const auto *pk_attribute = result.value().get().primary_key_attribute(); - class constraint pk_constraint("FK_" + obj_.name() + "_" + name); + class constraint pk_constraint("FK_" + obj_->name() + "_" + name); pk_constraint.options_ |= utils::constraints::ForeignKey; - if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(obj_.attributes_)) { + if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(obj_->attributes_)) { pk_constraint.attr_ = &*pk_attr; } - pk_constraint.owner_ = &obj_; + pk_constraint.owner_ = obj_; pk_constraint.ref_column_name_ = pk_attribute->name(); pk_constraint.ref_table_name_ = pk_attribute->owner() ? pk_attribute->owner()->name() : ""; constraints_.emplace_back(std::move(pk_constraint)); } void constraints_generator::create_unique_constraint(const std::string& name) const { - class constraint pk_constraint("UK_" + obj_.name() + "_" + name); + class constraint pk_constraint("UK_" + obj_->name() + "_" + name); pk_constraint.options_ |= utils::constraints::Unique; - if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(obj_.attributes_)) { + if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(obj_->attributes_)) { pk_constraint.attr_ = &*pk_attr; } - pk_constraint.owner_ = &obj_; + pk_constraint.owner_ = obj_; } std::list::iterator constraints_generator::find_attribute_by_name(const std::string& name) const { - return std::find_if(std::begin(obj_.attributes_), std::end(obj_.attributes_), [&name](const attribute& elem) { + return std::find_if(std::begin(obj_->attributes_), std::end(obj_->attributes_), [&name](const attribute& elem) { return elem.name() == name; }); } diff --git a/source/core/object/object.cpp b/source/core/object/object.cpp index f54cf79..f16c2ec 100644 --- a/source/core/object/object.cpp +++ b/source/core/object/object.cpp @@ -11,15 +11,15 @@ const attribute& object::create_attribute( std::string name, object& obj ) { return obj.attributes_.emplace_back(std::move(attr)); } -void object::add_attribute( attribute attr ) { - auto &ref = attributes_.emplace_back(std::move(attr)); - ref.owner_ = this; -} - -void object::add_constraint( class constraint c ) { - auto &ref = constraints_.emplace_back(std::move(c)); - ref.owner_ = this; -} +// void object::add_attribute( attribute attr ) { +// auto &ref = attributes_.emplace_back(std::move(attr)); +// ref.owner_ = this; +// } +// +// void object::add_constraint( class constraint c ) { +// auto &ref = constraints_.emplace_back(std::move(c)); +// ref.owner_ = this; +// } attribute* object::primary_key_attribute() const { return pk_attribute_; diff --git a/source/core/object/object_generator.cpp b/source/core/object/object_generator.cpp index b97e929..fa5f50c 100644 --- a/source/core/object/object_generator.cpp +++ b/source/core/object/object_generator.cpp @@ -5,9 +5,9 @@ #include namespace matador::object { -object_generator::object_generator( const repository& repo, std::unique_ptr&& object ) +object_generator::object_generator(repository& repo, const std::shared_ptr& object) : repo_(repo) -, object_(std::move(object)) {} +, object_(object) {} void object_generator::on_revision(const char* id, uint64_t& rev) { on_attribute(id, rev); @@ -19,28 +19,24 @@ void object_generator::create_pk_constraint(const std::string& name) const { if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(object_->attributes_)) { pk_constraint.attr_ = &*pk_attr; } - pk_constraint.owner_ = object_.get(); + pk_constraint.owner_ = object_; object_->constraints_.emplace_back(std::move(pk_constraint)); } void object_generator::create_fk_constraint(const std::type_index& ti, const std::string& name) const { - const auto result = repo_.basic_info(ti); - if (!result) { - repo_.provide_object_in_advance(ti, std::make_shared("")); - repo_.has_object_for_type(ti); - repo_.object_for_type(ti); - repo_.remove_object_for_type(ti); - return; - } - const auto *pk_attribute = result->get().primary_key_attribute(); + const auto obj = fk_object(ti); + const auto *pk_attribute = obj->primary_key_attribute(); class constraint pk_constraint("FK_" + object_->name() + "_" + name); pk_constraint.options_ |= utils::constraints::ForeignKey; if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(object_->attributes_)) { pk_constraint.attr_ = &*pk_attr; } - pk_constraint.owner_ = object_.get(); - pk_constraint.ref_column_name_ = pk_attribute->name(); - pk_constraint.ref_table_name_ = pk_attribute->owner() ? pk_attribute->owner()->name() : ""; + pk_constraint.owner_ = object_; + pk_constraint.reference_ = obj; + if (pk_attribute) { + pk_constraint.ref_column_name_ = pk_attribute->name(); + pk_constraint.ref_table_name_ = pk_attribute->owner() ? pk_attribute->owner()->name() : ""; + } object_->constraints_.emplace_back(std::move(pk_constraint)); } @@ -50,7 +46,7 @@ void object_generator::create_unique_constraint(const std::string& name) const { if (const auto pk_attr = find_attribute_by_name(name); pk_attr != std::end(object_->attributes_)) { pk_constraint.attr_ = &*pk_attr; } - pk_constraint.owner_ = object_.get(); + pk_constraint.owner_ = object_; } std::list::iterator object_generator::find_attribute_by_name(const std::string& name) const { @@ -63,4 +59,13 @@ void object_generator::prepare_primary_key(attribute& ref, utils::identifier &&p object_->pk_attribute_ = &ref; object_->pk_identifier_ = std::move(pk); } + +std::shared_ptr object_generator::fk_object(const std::type_index& ti) const { + const auto result = repo_.basic_info(ti); + if (result) { + return result->get().object(); + } + + return repo_.provide_object_in_advance(ti, std::make_shared("")); +} } diff --git a/source/core/object/repository.cpp b/source/core/object/repository.cpp index dba97ee..3a8a6fc 100644 --- a/source/core/object/repository.cpp +++ b/source/core/object/repository.cpp @@ -62,7 +62,7 @@ utils::result repository::basic_info(const return utils::ok(basic_object_info_ref{result.value()->info()}); } -utils::result repository::basic_info( const std::string& name ) const { +utils::result repository::basic_info(const std::string& name) const { auto result = find_node(name); if (!result) { return utils::failure(result.err()); @@ -213,4 +213,20 @@ void repository::expect_relation_node(const std::string &name, const std::type_i void repository::remove_expected_relation_node( const std::string& name ) { expected_relation_nodes_.erase(name); } + +std::shared_ptr repository::provide_object_in_advance(const std::type_index &ti, const std::shared_ptr& obj) { + return object_by_type_.insert({ti, obj}).first->second; +} + +bool repository::has_object_for_type(const std::type_index &ti) const { + return object_by_type_.count(ti) > 0; +} + +std::shared_ptr repository::object_for_type(const std::type_index &ti) const { + return object_by_type_.at(ti); +} + +void repository::remove_object_for_type(const std::type_index &ti) { + object_by_type_.erase(ti); +} } // namespace matador::object diff --git a/source/orm/query/column.cpp b/source/orm/query/column.cpp index caa6c58..1a7ed87 100644 --- a/source/orm/query/column.cpp +++ b/source/orm/query/column.cpp @@ -48,7 +48,7 @@ bool column::equals(const column &x) const { function_ == x.function_; } -column &column::as(std::string a) { +column column::as(std::string a) { alias_ = std::move(a); return *this; } diff --git a/source/orm/query/intermediates/query_create_intermediate.cpp b/source/orm/query/intermediates/query_create_intermediate.cpp index 0001efc..d4f945b 100644 --- a/source/orm/query/intermediates/query_create_intermediate.cpp +++ b/source/orm/query/intermediates/query_create_intermediate.cpp @@ -37,4 +37,8 @@ query_create_table_columns_intermediate query_create_table_intermediate::columns context_->parts.push_back(std::make_unique(columns)); return {context_}; } + +query_create_table_columns_intermediate query_create_table_intermediate::columns( std::initializer_list columns ) {} + +query_create_table_columns_intermediate query_create_table_intermediate::columns( const std::list& columns ) {} } diff --git a/source/orm/query/table.cpp b/source/orm/query/table.cpp index 74e0692..a38653f 100644 --- a/source/orm/query/table.cpp +++ b/source/orm/query/table.cpp @@ -24,7 +24,7 @@ bool table::operator==( const table& x ) const { return name_ == x.name_; } -table & table::as(const std::string &a) { +table table::as(const std::string &a) { alias_ = a; return *this; } @@ -49,10 +49,6 @@ const std::vector& table::columns() const { return columns_; } -// column table::column(const std::string& name) const { -// return {std::shared_ptr(const_cast(this)), name}; -// } - table::operator const std::vector&() const { return columns_; }