From 784f6e768d521faddb4f74d12f85d9b07f1f0829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Tue, 18 Feb 2025 16:19:48 +0100 Subject: [PATCH] has many fetch progress --- backends/postgres/test/CMakeLists.txt | 2 +- include/matador/object/object_ptr.hpp | 12 +++- .../matador/object/primary_key_resolver.hpp | 6 ++ .../sql/internal/query_result_impl.hpp | 55 +++++++++++++------ test/backends/SessionTest.cpp | 4 +- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index e45efed..e5f11f9 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -2,7 +2,7 @@ CPMAddPackage("gh:catchorg/Catch2@3.7.1") list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) -set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:5432/matador") +set(POSTGRES_CONNECTION_STRING "postgres://news:news@127.0.0.1:15432/matador") configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE) diff --git a/include/matador/object/object_ptr.hpp b/include/matador/object/object_ptr.hpp index d75306f..cead78c 100644 --- a/include/matador/object/object_ptr.hpp +++ b/include/matador/object/object_ptr.hpp @@ -3,6 +3,8 @@ #include "matador/utils/identifier.hpp" +#include "matador/object/primary_key_resolver.hpp" + #include namespace matador::object { @@ -10,11 +12,13 @@ template class object_ptr { public: object_ptr() = default; - object_ptr(Type *obj) : ptr_(obj) {} + explicit object_ptr(Type *obj) + : ptr_(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=(const object_ptr &other) = default; object_ptr &operator=(object_ptr &&other) = default; using value_type = Type; @@ -22,6 +26,10 @@ public: Type& operator*() const { return *ptr_; } [[nodiscard]] bool empty() const { return ptr_ == nullptr; } + void reset(Type *obj) { + ptr_.reset(obj); + pk_ = primary_key_resolver::resolve_object(*obj).pk; + } Type* get() { return ptr_.get(); } const Type* get() const { return ptr_.get(); } diff --git a/include/matador/object/primary_key_resolver.hpp b/include/matador/object/primary_key_resolver.hpp index f108ba4..982e560 100644 --- a/include/matador/object/primary_key_resolver.hpp +++ b/include/matador/object/primary_key_resolver.hpp @@ -35,6 +35,12 @@ public: return primary_key_info_; } + template + static primary_key_info resolve_object(const Type& obj) { + primary_key_resolver resolver; + return resolver.resolve(obj); + } + template < class Type > void on_primary_key(const char *id, Type &pk, std::enable_if_t && !std::is_same_v>* = nullptr) { primary_key_info_.pk_column_name = id; diff --git a/include/matador/sql/internal/query_result_impl.hpp b/include/matador/sql/internal/query_result_impl.hpp index a3ea4c4..a609096 100644 --- a/include/matador/sql/internal/query_result_impl.hpp +++ b/include/matador/sql/internal/query_result_impl.hpp @@ -5,12 +5,15 @@ #include "matador/utils/field_attributes.hpp" #include "matador/utils/foreign_attributes.hpp" #include "matador/utils/default_type_traits.hpp" +#include "matador/utils/identifier.hpp" #include "matador/sql/interface/query_result_reader.hpp" #include "matador/object/attribute_definition.hpp" +#include #include +#include #include #include #include @@ -70,6 +73,10 @@ public: void on_primary_key(const char *id, ValueType &value, std::enable_if_t && !std::is_same_v>* = nullptr) { utils::data_type_traits::read_value(*reader_, id, column_index_++, value); + if (type_stack_.size() == 1) { + last_pk_ = current_pk_; + current_pk_ = value; + } } void on_primary_key(const char *id, std::string &value, size_t size); void on_revision(const char *id, uint64_t &rev); @@ -86,25 +93,27 @@ public: template < class Pointer > void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr) { if (x.empty()) { - x = new typename Pointer::value_type; + x.reset(new typename Pointer::value_type); } if (attr.fetch() == utils::fetch_type::LAZY) { pk_reader_.read(*x, column_index_++); } else if (const auto ti = std::type_index(typeid(*x)); processed_types_.count(ti) == 0) { processed_types_.insert(ti); + type_stack_.push(ti); access::process(*this, *x); + type_stack_.pop(); } } template < class Pointer > void on_has_one(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr) { if (x.empty()) { - x = new typename Pointer::value_type; + x.reset(new typename Pointer::value_type); } if (attr.fetch() == utils::fetch_type::LAZY) { pk_reader_.read(*x, column_index_++); } else if (const auto ti = std::type_index(typeid(*x)); processed_types_.count(ti) == 0) { - processed_types_.insert(ti); + processed_types_.insert(ti); } } @@ -116,11 +125,13 @@ public: void on_has_many(const char * /*id*/, ContainerType &cont, const char * /*join_column*/, const utils::foreign_attributes &attr) { if ( attr.fetch() == utils::fetch_type::LAZY ) { // pk_reader_.read(*id, column_index_++); - } else if (const auto ti = std::type_index(typeid(typename ContainerType::value_type::value_type)); processed_types_.count(ti) == 0) { + } else /*if (const auto ti = std::type_index(typeid(typename ContainerType::value_type::value_type)); processed_types_.count(ti) == 0)*/ { + const auto ti = std::type_index(typeid(typename ContainerType::value_type::value_type)); processed_types_.insert(ti); auto obj = std::make_unique(); - // typename ContainerType::value_type x(new typename ContainerType::value_type::value_type); + type_stack_.push(ti); access::process(*this, *obj); + type_stack_.pop(); auto ptr = typename ContainerType::value_type(obj.release()); const auto pk = ptr.primary_key(); if (ptr.primary_key().is_valid()) { @@ -138,18 +149,25 @@ public: } template - bool fetch(Type &obj) - { - column_index_ = reader_->start_column_index(); - auto fetched = reader_->fetch(); - if (!fetched.is_ok()) { - return false; - } - if (!*fetched) { - return false; - } - processed_types_.insert(typeid(Type)); - access::process(*this, obj); + bool fetch(Type &obj) { + bool result = false; + do { + column_index_ = reader_->start_column_index(); + auto fetched = reader_->fetch(); + if (!fetched.is_ok()) { + return false; + } + if (!*fetched) { + return false; + } + processed_types_.insert(typeid(Type)); + type_stack_.push(typeid(Type)); + access::process(*this, obj); + type_stack_.pop(); + std::cout << "last pk: " << last_pk_.str() << std::endl; + std::cout << "current pk: " << current_pk_.str() << std::endl; + std::cout << "last == current: " << std::boolalpha << (last_pk_ == current_pk_) << std::endl; + } while (last_pk_ == current_pk_); return true; } @@ -161,6 +179,9 @@ protected: std::unique_ptr reader_; detail::pk_reader pk_reader_; std::unordered_set processed_types_; + std::stack type_stack_; + utils::identifier current_pk_{}; + utils::identifier last_pk_{}; }; namespace detail { diff --git a/test/backends/SessionTest.cpp b/test/backends/SessionTest.cpp index e96d797..074f5da 100644 --- a/test/backends/SessionTest.cpp +++ b/test/backends/SessionTest.cpp @@ -170,7 +170,7 @@ TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with one-to-ma auto all_departments = find_result.release(); std::vector> departments_repo; for (auto it = all_departments.begin(); it != all_departments.end(); ++it) { - std::cout << "author: " << it->name << " (employees: " << it->employees.size() << ")\n"; + std::cout << "department: " << it->name << " (employees: " << it->employees.size() << ")\n"; departments_repo.emplace_back(it.release()); } REQUIRE(departments_repo.size() == 2); @@ -197,6 +197,6 @@ TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with one-to-ma all_departments = find_result.release(); for (auto it = all_departments.begin(); it != all_departments.end(); ++it) { - std::cout << "author: " << it->name << " (employees: " << it->employees.size() << ")\n"; + std::cout << "department: " << it->name << " (employees: " << it->employees.size() << ")\n"; } } \ No newline at end of file