164 lines
3.2 KiB
C++
164 lines
3.2 KiB
C++
#ifndef QUERY_QUERY_RESULT_HPP
|
|
#define QUERY_QUERY_RESULT_HPP
|
|
|
|
#include "matador/sql/column_definition.hpp"
|
|
|
|
#include "matador/sql/internal/query_result_impl.hpp"
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
namespace matador::sql {
|
|
|
|
class record;
|
|
|
|
template < typename Type >
|
|
class query_result;
|
|
|
|
template < typename Type >
|
|
class query_result_iterator
|
|
{
|
|
public:
|
|
using iterator_category = std::forward_iterator_tag;
|
|
using value_type = Type;
|
|
using difference_type = std::ptrdiff_t;
|
|
using self = query_result_iterator; /**< Shortcut for this class. */
|
|
using pointer = value_type*; /**< Shortcut for the pointer type. */
|
|
using reference = value_type&; /**< Shortcut for the reference type */
|
|
|
|
public:
|
|
query_result_iterator() = default;
|
|
explicit query_result_iterator(query_result<Type> *res)
|
|
: result_(res)
|
|
{}
|
|
query_result_iterator(query_result<Type> *res, std::unique_ptr<Type> obj)
|
|
: obj_(std::move(obj))
|
|
, result_(res)
|
|
{}
|
|
query_result_iterator(query_result_iterator&& x) noexcept
|
|
: obj_(std::move(x.obj_))
|
|
, result_(x.result_)
|
|
{}
|
|
|
|
query_result_iterator& operator=(query_result_iterator&& x) noexcept
|
|
{
|
|
result_ = x.result_;
|
|
obj_ = std::move(x.obj_);
|
|
return *this;
|
|
}
|
|
|
|
~query_result_iterator() = default;
|
|
|
|
bool operator==(const query_result_iterator& rhs)
|
|
{
|
|
return obj_ == rhs.obj_;
|
|
}
|
|
|
|
bool operator!=(const query_result_iterator& rhs)
|
|
{
|
|
return obj_ != rhs.obj_;
|
|
}
|
|
|
|
self& operator++()
|
|
{
|
|
obj_.reset(result_->create());
|
|
result_->bind(*obj_);
|
|
if (!result_->fetch(*obj_)) {
|
|
obj_.reset();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
self operator++(int)
|
|
{
|
|
const self tmp(result_, obj_);
|
|
|
|
obj_.reset(result_->create());
|
|
result_->bind(*obj_);
|
|
if (!result_->fetch(*obj_)) {
|
|
obj_.reset();
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
pointer operator->()
|
|
{
|
|
return obj_.get();
|
|
}
|
|
|
|
reference operator*()
|
|
{
|
|
return *obj_;
|
|
}
|
|
|
|
pointer get()
|
|
{
|
|
return obj_.get();
|
|
}
|
|
|
|
pointer release()
|
|
{
|
|
return obj_.release();
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<Type> obj_;
|
|
query_result<Type> *result_{nullptr};
|
|
};
|
|
|
|
namespace detail {
|
|
|
|
template < typename Type >
|
|
Type* create_prototype(const std::vector<column_definition> &/*prototype*/)
|
|
{
|
|
return new Type{};
|
|
}
|
|
|
|
template <>
|
|
record* create_prototype<record>(const std::vector<column_definition> &prototype);
|
|
|
|
}
|
|
|
|
template<typename Type>
|
|
class query_result final {
|
|
public:
|
|
using iterator = query_result_iterator<Type>;
|
|
using creator_func = std::function<Type*()>;
|
|
|
|
public:
|
|
explicit query_result(std::unique_ptr<query_result_impl> &&impl)
|
|
: impl_(std::move(impl)) {}
|
|
|
|
iterator begin() { return std::move(++iterator(this)); }
|
|
iterator end() { return {}; }
|
|
|
|
private:
|
|
friend class query_result_iterator<Type>;
|
|
|
|
Type* create();
|
|
void bind(const Type& obj);
|
|
bool fetch(Type& obj);
|
|
|
|
protected:
|
|
std::unique_ptr<query_result_impl> impl_;
|
|
};
|
|
|
|
template<typename Type>
|
|
Type *query_result<Type>::create() {
|
|
return detail::create_prototype<Type>(impl_->prototype());
|
|
}
|
|
template<typename Type>
|
|
void query_result<Type>::bind(const Type &obj) {
|
|
impl_->bind(obj);
|
|
}
|
|
|
|
template<typename Type>
|
|
bool query_result<Type>::fetch(Type &obj) {
|
|
return impl_->fetch(obj);
|
|
}
|
|
|
|
} // namespace matador::sql
|
|
#endif //QUERY_QUERY_RESULT_HPP
|