implemented lazy loading for object_ptr and belongs_to

This commit is contained in:
2026-01-15 12:40:54 +01:00
parent db8e137c11
commit 7626331866
81 changed files with 1790 additions and 927 deletions
+35 -16
View File
@@ -2,20 +2,20 @@
#define QUERY_STATEMENT_HPP
#include "matador/sql/abstract_sql_logger.hpp"
#include "matador/sql/error_code.hpp"
#include "matador/sql/query_result.hpp"
#include "matador/sql/interface/statement_proxy.hpp"
#include "matador/object/basic_repository.hpp"
#include "matador/utils/error.hpp"
#include "matador/utils/result.hpp"
#include <iostream>
#include <memory>
namespace matador::sql {
namespace detail {
template<class Type>
class identifier_binder;
}
class statement_impl;
class statement_proxy;
@@ -104,7 +104,10 @@ public:
* @return The query result set
*/
template<class Type>
utils::result<std::unique_ptr<Type>, utils::error> fetch_one();
utils::result<object::object_ptr<Type>, utils::error> fetch_one();
template<class Type>
utils::result<std::shared_ptr<Type>, utils::error> fetch_one_raw();
/**
* Fetches the first result of a prepared statement.
* The type is a record representing an unknown variable type.
@@ -140,10 +143,6 @@ public:
[[nodiscard]] utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch_internal() const;
private:
template<class Type>
friend class detail::identifier_binder;
private:
std::shared_ptr<statement_proxy> statement_proxy_;
std::unique_ptr<utils::attribute_writer> bindings_;
@@ -165,31 +164,51 @@ statement &statement::bind(const Type &obj) {
template<class Type>
utils::result<query_result<Type>, utils::error> statement::fetch() {
std::cout << statement_proxy_->sql() << std::endl;
return statement_proxy_->fetch(*bindings_).and_then([](std::unique_ptr<query_result_impl> &&value) {
return statement_proxy_->fetch(*bindings_).and_then([this](std::unique_ptr<query_result_impl> &&value) {
auto resolver = statement_proxy_->statement_->query_.resolver_factory->resolver<Type>();
const auto prototype = value->prototype();
return utils::ok(query_result<Type>(std::forward<decltype(value)>(value), [prototype] {
return utils::ok(query_result<Type>(std::forward<decltype(value)>(value), resolver, [prototype] {
return detail::create_prototype<Type>(prototype);
}));
});
}
template<class Type>
utils::result<std::unique_ptr<Type>, utils::error> statement::fetch_one() {
utils::result<object::object_ptr<Type>, utils::error> statement::fetch_one() {
std::cout << statement_proxy_->sql() << std::endl;
auto result = statement_proxy_->fetch(*bindings_);
if (!result.is_ok()) {
return utils::failure(result.err());
}
auto resolver = statement_proxy_->statement_->query_.resolver_factory->resolver<Type>();
const auto prototype = result.value()->prototype();
auto records = query_result<Type>(result.release(), [prototype] {
auto records = query_result<Type>(result.release(), resolver, [prototype] {
return detail::create_prototype<Type>(prototype);
});
auto first = records.begin();
if (first == records.end()) {
return utils::ok(std::unique_ptr<Type>{nullptr});
return utils::failure(utils::error{
error_code::FETCH_FAILED,
"Failed to find entity."
});
}
return utils::ok(std::unique_ptr<Type>{first.release()});
return utils::ok(first.optr());
}
template<class Type>
utils::result<std::shared_ptr<Type>, utils::error> statement::fetch_one_raw() {
auto result = statement_proxy_->fetch(*bindings_);
if (!result.is_ok()) {
return utils::failure(result.err());
}
auto obj = std::make_shared<Type>();
(*result)->bind(*obj);
if (!(*result)->fetch(*obj)) {
return utils::ok(std::shared_ptr<Type>{});
}
return utils::ok(obj);
}
}