diff --git a/include/matador/object/attribute_generator.hpp b/include/matador/object/attribute_generator.hpp index 2392015..8459fc9 100644 --- a/include/matador/object/attribute_generator.hpp +++ b/include/matador/object/attribute_generator.hpp @@ -7,6 +7,7 @@ #include "matador/utils/data_type_traits.hpp" #include "matador/utils/error.hpp" #include "matador/utils/field_attributes.hpp" +#include "matador/utils/identifier.hpp" #include "matador/utils/primary_key_attribute.hpp" #include "matador/utils/result.hpp" @@ -91,9 +92,7 @@ public: on_foreign_key(id, x); } template - void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) { - // on_foreign_key(id, x); - } + static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {} template void on_foreign_key(const char *id, Pointer &x) { @@ -123,6 +122,15 @@ 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, const std::shared_ptr& ref_column) const; + template + attribute &emplace_attribute(const char *id, const utils::field_attributes& attr, null_option_type null_option) { + auto &ref = columns_.emplace_back(id, utils::data_type_traits::type(attr.size()), attr, null_option); + ref.owner_ = &obj_; + return ref; + } + + void prepare_primary_key(attribute &ref, utils::identifier &&pk) const; + private: size_t index_ = 0; std::vector &columns_; @@ -134,19 +142,18 @@ private: template void attribute_generator::on_primary_key(const char *id, ValueType &x, const utils::primary_key_attribute& attr) { - on_attribute(id, x, { attr.size(), utils::constraints::PrimaryKey }); + auto &ref = emplace_attribute(id, { attr.size(), utils::constraints::PrimaryKey }, null_option_type::NOT_NULL); + prepare_primary_key(ref, utils::identifier(x)); } template void attribute_generator::on_attribute(const char *id, Type &/*x*/, const utils::field_attributes &attr) { - auto &ref = columns_.emplace_back(id, utils::data_type_traits::type(attr.size()), attr, null_option_type::NOT_NULL); - ref.owner_ = &obj_; + std::ignore = emplace_attribute(id, attr, null_option_type::NOT_NULL); } template void attribute_generator::on_attribute(const char *id, std::optional & /*x*/, const utils::field_attributes &attr) { - auto &ref = columns_.emplace_back(id, utils::data_type_traits::type(attr.size()), attr, null_option_type::NULLABLE); - ref.owner_ = &obj_; + std::ignore = emplace_attribute(id, attr, null_option_type::NULLABLE); } } diff --git a/include/matador/object/basic_object_info.hpp b/include/matador/object/basic_object_info.hpp index c534402..3a80cc9 100644 --- a/include/matador/object/basic_object_info.hpp +++ b/include/matador/object/basic_object_info.hpp @@ -53,6 +53,7 @@ protected: basic_object_info(std::shared_ptr node, const std::vector &attributes); protected: + std::unique_ptr node_ptr_; std::shared_ptr node_; /**< prototype node of the represented object type */ std::vector attributes_; std::optional identifier_; diff --git a/include/matador/object/object.hpp b/include/matador/object/object.hpp index b33c91f..0168e96 100644 --- a/include/matador/object/object.hpp +++ b/include/matador/object/object.hpp @@ -6,6 +6,8 @@ #include "matador/object/constraint.hpp" #include "matador/object/constraints_generator.hpp" +#include "matador/utils/identifier.hpp" + namespace matador::object { class repository; @@ -27,6 +29,10 @@ public: void add_attribute(attribute attr); void add_constraint(class constraint c); + [[nodiscard]] const attribute* primary_key_attribute() const; + [[nodiscard]] const utils::identifier& primary_key() const; + [[nodiscard]] bool has_primary_key() const; + [[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& alias() const; @@ -40,10 +46,13 @@ public: private: friend class constraints_generator; + friend class attribute_generator; std::string name_; std::string alias_; + attribute* pk_attribute_{nullptr}; + utils::identifier pk_identifier_; std::vector attributes_; std::vector constraints_; }; diff --git a/source/core/object/attribute_generator.cpp b/source/core/object/attribute_generator.cpp index c411a56..af22e18 100644 --- a/source/core/object/attribute_generator.cpp +++ b/source/core/object/attribute_generator.cpp @@ -1,5 +1,6 @@ #include "matador/object/attribute_generator.hpp" #include "matador/object/repository.hpp" +#include "matador/object/object.hpp" namespace matador::object { @@ -21,4 +22,8 @@ void attribute_generator::insert_missing_reference_column(const std::type_index& const_cast(repo_).missing_references_.insert({ti, ref_column}); } +void attribute_generator::prepare_primary_key(attribute& ref, utils::identifier &&pk) const { + obj_.pk_attribute_ = &ref; + obj_.pk_identifier_ = std::move(pk); +} } \ No newline at end of file diff --git a/source/core/object/object.cpp b/source/core/object/object.cpp index a368343..6d53fe8 100644 --- a/source/core/object/object.cpp +++ b/source/core/object/object.cpp @@ -21,6 +21,18 @@ void object::add_constraint( class constraint c ) { ref.owner_ = this; } +const attribute* object::primary_key_attribute() const { + return pk_attribute_; +} + +const utils::identifier& object::primary_key() const { + return pk_identifier_; +} + +bool object::has_primary_key() const { + return pk_attribute_ != nullptr; +} + const std::string& object::name() const { return name_; } diff --git a/test/core/object/ObjectTest.cpp b/test/core/object/ObjectTest.cpp index ac66eb0..ae69bc3 100644 --- a/test/core/object/ObjectTest.cpp +++ b/test/core/object/ObjectTest.cpp @@ -7,14 +7,15 @@ #include "../test/models/book.hpp" TEST_CASE("Generate object from type", "[object][generate]") { - using namespace matador; - object::repository repo; - auto result = repo.attach("authors"); - REQUIRE(result); + using namespace matador; + object::repository repo; + auto result = repo.attach("authors"); + REQUIRE(result); - const auto obj = object::object::generate(repo, "books"); - REQUIRE(obj->name() == "books"); - REQUIRE(obj->alias().empty()); - REQUIRE(obj->attributes().size() == 4); - REQUIRE(obj->constraints().size() == 2); + const auto obj = object::object::generate(repo, "books"); + REQUIRE(obj->name() == "books"); + REQUIRE(obj->alias().empty()); + REQUIRE(obj->attributes().size() == 4); + REQUIRE(obj->constraints().size() == 2); + REQUIRE(obj->has_primary_key()); } \ No newline at end of file