implemented lazy loading for object_ptr and belongs_to
This commit is contained in:
@@ -2,22 +2,24 @@
|
||||
#define QUERY_QUERY_RESULT_HPP
|
||||
|
||||
#include "matador/object/attribute.hpp"
|
||||
#include "matador/object/object_ptr.hpp"
|
||||
|
||||
#include "matador/sql/internal/query_result_impl.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
#include "matador/object/object.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
class record;
|
||||
class query_result_impl;
|
||||
|
||||
template < typename Type >
|
||||
class query_result;
|
||||
|
||||
template < typename Type >
|
||||
class query_result_iterator
|
||||
{
|
||||
class query_result_iterator {
|
||||
public:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = Type;
|
||||
@@ -31,7 +33,7 @@ public:
|
||||
explicit query_result_iterator(query_result<Type> *res)
|
||||
: result_(res)
|
||||
{}
|
||||
query_result_iterator(query_result<Type> *res, std::unique_ptr<Type> obj)
|
||||
query_result_iterator(query_result<Type> *res, object::object_ptr<Type> obj)
|
||||
: obj_(std::move(obj))
|
||||
, result_(res)
|
||||
{}
|
||||
@@ -48,19 +50,20 @@ public:
|
||||
|
||||
~query_result_iterator() = default;
|
||||
|
||||
bool operator==(const query_result_iterator& rhs) {
|
||||
bool operator==(const query_result_iterator& rhs) const {
|
||||
return obj_ == rhs.obj_;
|
||||
}
|
||||
|
||||
bool operator!=(const query_result_iterator& rhs) {
|
||||
return obj_ != rhs.obj_;
|
||||
bool operator!=(const query_result_iterator& rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
self& operator++() {
|
||||
obj_.reset(result_->create());
|
||||
result_->bind(*obj_);
|
||||
if (!result_->fetch(*obj_)) {
|
||||
obj_.reset();
|
||||
auto obj = result_->create();
|
||||
result_->bind(*obj);
|
||||
obj_.reset();
|
||||
if (result_->fetch(*obj)) {
|
||||
obj_ = object::object_ptr<Type>(std::make_shared<object::object_proxy<Type>>(result_->resolver_, std::move(obj)));
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -69,10 +72,11 @@ public:
|
||||
self operator++(int) {
|
||||
const self tmp(result_, obj_);
|
||||
|
||||
obj_.reset(result_->create());
|
||||
result_->bind(*obj_);
|
||||
if (!result_->fetch(*obj_)) {
|
||||
obj_.reset();
|
||||
auto obj = result_->create();
|
||||
result_->bind(*obj);
|
||||
obj_.reset();
|
||||
if (result_->fetch(*obj)) {
|
||||
obj_ = object::object_ptr<Type>(std::make_shared<object::object_proxy<Type>>(result_->resolver_, std::move(obj)));
|
||||
}
|
||||
|
||||
return tmp;
|
||||
@@ -82,50 +86,37 @@ public:
|
||||
return obj_.get();
|
||||
}
|
||||
|
||||
reference operator*() {
|
||||
return *obj_;
|
||||
object::object_ptr<Type> operator*() {
|
||||
return obj_;
|
||||
}
|
||||
|
||||
pointer get() {
|
||||
return obj_.get();
|
||||
}
|
||||
|
||||
pointer release() {
|
||||
return obj_.release();
|
||||
object::object_ptr<Type> optr() {
|
||||
return obj_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Type> obj_;
|
||||
object::object_ptr<Type> obj_;
|
||||
query_result<Type> *result_{nullptr};
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template < typename Type >
|
||||
Type* create_prototype(const std::vector<object::attribute> &/*prototype*/) {
|
||||
return new Type{};
|
||||
std::shared_ptr<Type> create_prototype(const std::vector<object::attribute> &/*prototype*/) {
|
||||
return std::make_shared<Type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
record* create_prototype<record>(const std::vector<object::attribute> &prototype);
|
||||
|
||||
record create_prototype(const std::vector<object::attribute> &prototype);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
class query_result final {
|
||||
public:
|
||||
using iterator = query_result_iterator<Type>;
|
||||
using creator_func = std::function<Type*()>;
|
||||
using creator_func = std::function<std::shared_ptr<Type>()>;
|
||||
|
||||
public:
|
||||
// explicit query_result(std::unique_ptr<query_result_impl> &&impl)
|
||||
// : impl_(std::move(impl))
|
||||
// , creator_([this] {
|
||||
// return detail::create_prototype<Type>(impl_->prototype());
|
||||
// }) {}
|
||||
|
||||
query_result(std::unique_ptr<query_result_impl> &&impl, creator_func&& creator)
|
||||
query_result(std::unique_ptr<query_result_impl> &&impl, const std::shared_ptr<object::object_resolver<Type>> &resolver, creator_func&& creator)
|
||||
: impl_(std::move(impl))
|
||||
, resolver_(resolver)
|
||||
, creator_(std::move(creator)) {}
|
||||
|
||||
iterator begin() { return std::move(++iterator(this)); }
|
||||
@@ -134,17 +125,18 @@ public:
|
||||
private:
|
||||
friend class query_result_iterator<Type>;
|
||||
|
||||
Type* create();
|
||||
std::shared_ptr<Type> create();
|
||||
void bind(const Type& obj);
|
||||
bool fetch(Type& obj);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<query_result_impl> impl_;
|
||||
std::shared_ptr<object::object_resolver<Type>> resolver_;
|
||||
creator_func creator_;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
Type *query_result<Type>::create() {
|
||||
std::shared_ptr<Type> query_result<Type>::create() {
|
||||
return creator_();
|
||||
}
|
||||
|
||||
@@ -157,6 +149,6 @@ template<typename Type>
|
||||
bool query_result<Type>::fetch(Type &obj) {
|
||||
return impl_->fetch(obj);
|
||||
}
|
||||
|
||||
} // namespace matador::sql
|
||||
}
|
||||
// namespace matador::sql
|
||||
#endif //QUERY_QUERY_RESULT_HPP
|
||||
|
||||
Reference in New Issue
Block a user