From 35f078bbc4c3f9f97f5611c8daec6aa4593bf8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Sat, 22 Feb 2025 15:39:38 +0100 Subject: [PATCH] added object_proxy as the holder of the object in object_ptr --- .../object/attribute_definition_generator.hpp | 17 ++++++++++---- include/matador/object/object_proxy.hpp | 22 ++++++++++++++++--- include/matador/object/object_ptr.hpp | 22 ++++++++++--------- include/matador/orm/session.hpp | 2 +- test/core/object/PrimaryKeyResolverTest.cpp | 1 + 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/include/matador/object/attribute_definition_generator.hpp b/include/matador/object/attribute_definition_generator.hpp index db19b29..0615db0 100644 --- a/include/matador/object/attribute_definition_generator.hpp +++ b/include/matador/object/attribute_definition_generator.hpp @@ -81,14 +81,23 @@ public: template void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/) { - if (const auto result = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)))) { - columns_.push_back(fk_column_generator_.generate(id, *x, *result)); - } + 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); + } + + 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)))) { - columns_.push_back(fk_column_generator_.generate(id, *x, *result)); + 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)); + + } } } template diff --git a/include/matador/object/object_proxy.hpp b/include/matador/object/object_proxy.hpp index 9ecbf44..5fce8c0 100644 --- a/include/matador/object/object_proxy.hpp +++ b/include/matador/object/object_proxy.hpp @@ -9,17 +9,33 @@ class basic_object_proxy { public: virtual ~basic_object_proxy() = default; - virtual void *get() const = 0; + [[nodiscard]] virtual void *get() const = 0; }; template class object_proxy : public basic_object_proxy { public: - void *get() const override { return static_cast(this)->get(); } + object_proxy() = default; + explicit object_proxy(Type* obj) + : obj_(obj) {} + explicit object_proxy(std::unique_ptr obj) + : obj_(std::move(obj)) {} + + [[nodiscard]] void *get() const override { return static_cast(obj_.get()); } Type* operator->() const { return obj_.get(); } + Type& operator*() { return *obj_; } + const Type& operator*() const { return *obj_; } + + Type* pointer() const { return obj_.get(); } + + Type& ref() { return *obj_; } + const Type& ref() const { return *obj_; } + + void reset(Type* obj) { obj_.reset(obj); } + private: - std::shared_ptr obj_{}; + std::unique_ptr obj_{}; }; } diff --git a/include/matador/object/object_ptr.hpp b/include/matador/object/object_ptr.hpp index 4fad358..ce19087 100644 --- a/include/matador/object/object_ptr.hpp +++ b/include/matador/object/object_ptr.hpp @@ -3,6 +3,7 @@ #include "matador/utils/identifier.hpp" +#include "matador/object/object_proxy.hpp" #include "matador/object/primary_key_resolver.hpp" #include @@ -11,35 +12,36 @@ namespace matador::object { template class object_ptr { public: - object_ptr() = default; + object_ptr() + : ptr_(std::make_shared>()) {} explicit object_ptr(Type *obj) - : ptr_(obj) + : ptr_(std::make_shared>(obj)) , pk_(primary_key_resolver::resolve_object(*obj).pk) {} - explicit object_ptr(std::shared_ptr obj) : ptr_(obj) {} object_ptr(const object_ptr &other) : ptr_(other.ptr_) {} object_ptr(object_ptr &&other) noexcept : ptr_(std::move(other.ptr_)) {} object_ptr &operator=(const object_ptr &other) = default; object_ptr &operator=(object_ptr &&other) = default; using value_type = Type; - Type* operator->() const { return ptr_.get(); } - Type& operator*() const { return *ptr_; } + Type* operator->() const { return ptr_->pointer(); } + Type& operator*() { return ptr_->ref(); } + const Type& operator*() const { return ptr_->ref(); } - [[nodiscard]] bool empty() const { return ptr_ == nullptr; } + [[nodiscard]] bool empty() const { return ptr_->pointer() == nullptr; } void reset(Type *obj) { - ptr_.reset(obj); + ptr_->reset(obj); pk_ = primary_key_resolver::resolve_object(*obj).pk; } - Type* get() { return ptr_.get(); } - const Type* get() const { return ptr_.get(); } + Type* get() const { return static_cast(ptr_->pointer()); } + operator bool() { return valid(); } bool valid() { return ptr_ != nullptr; } [[nodiscard]] const utils::identifier& primary_key() const { return pk_; } void primary_key(const utils::identifier &pk) { pk_ = pk; } private: - std::shared_ptr ptr_{}; + std::shared_ptr> ptr_{}; utils::identifier pk_; }; diff --git a/include/matador/orm/session.hpp b/include/matador/orm/session.hpp index ca742d7..4a82a7a 100644 --- a/include/matador/orm/session.hpp +++ b/include/matador/orm/session.hpp @@ -63,7 +63,7 @@ public: if (!obj->get()) { return utils::failure(make_error(error_code::FailedToFindObject, "Failed to find object of type " + info->get().name() + " with primary key " + std::to_string(pk) + ".")); } - return utils::ok(object::object_ptr{ obj.release() }); + return utils::ok(object::object_ptr{ obj->release() }); } template diff --git a/test/core/object/PrimaryKeyResolverTest.cpp b/test/core/object/PrimaryKeyResolverTest.cpp index cd1bc74..b3ec337 100644 --- a/test/core/object/PrimaryKeyResolverTest.cpp +++ b/test/core/object/PrimaryKeyResolverTest.cpp @@ -3,6 +3,7 @@ #include "matador/object/primary_key_resolver.hpp" #include "../test/models/book.hpp" +#include "../test/models/author.hpp" #include "../test/models/product.hpp" TEST_CASE("Test primary key resolver", "[PrimaryKeyResolver]") {