mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Moved result construction more towards connector.
This will make it easier to handle different formats
This commit is contained in:
parent
51786a9f1d
commit
9597c3712c
@ -33,48 +33,50 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T>
|
||||
struct named_parameter_list_t
|
||||
struct parameter_list_t
|
||||
{
|
||||
static_assert(detail::wrong<T>::value, "Template parameter for named_parameter_list_t has to be a tuple");
|
||||
static_assert(detail::wrong<T>::value, "Template parameter for parameter_list_t has to be a tuple");
|
||||
};
|
||||
|
||||
template<typename... Parameter>
|
||||
struct named_parameter_list_t<std::tuple<Parameter...>>: public Parameter::_member_t...
|
||||
struct parameter_list_t<std::tuple<Parameter...>>: public Parameter::_member_t...
|
||||
{
|
||||
named_parameter_list_t():
|
||||
parameter_list_t():
|
||||
Parameter::_member_t()...,
|
||||
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
|
||||
{}
|
||||
|
||||
named_parameter_list_t(const named_parameter_list_t& rhs)
|
||||
parameter_list_t(const parameter_list_t& rhs)
|
||||
noexcept(std::is_nothrow_copy_constructible<std::tuple<typename Parameter::_member_t...>>::value):
|
||||
Parameter::_member_t(static_cast<const typename Parameter::_member_t&>(rhs))...,
|
||||
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
|
||||
{}
|
||||
|
||||
named_parameter_list_t(named_parameter_list_t&& rhs)
|
||||
parameter_list_t(parameter_list_t&& rhs)
|
||||
noexcept(std::is_nothrow_move_constructible<std::tuple<typename Parameter::_member_t...>>::value):
|
||||
Parameter::_member_t(std::move(static_cast<typename Parameter::_member_t&>(rhs)))...,
|
||||
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
|
||||
{}
|
||||
|
||||
named_parameter_list_t& operator=(const named_parameter_list_t& rhs)
|
||||
parameter_list_t& operator=(const parameter_list_t& rhs)
|
||||
noexcept(std::is_nothrow_copy_assignable<std::tuple<typename Parameter::_member_t&...>>::value)
|
||||
{
|
||||
_parameter_tuple = rhs._parameter_tuple;
|
||||
return *this;
|
||||
}
|
||||
|
||||
named_parameter_list_t& operator=(named_parameter_list_t&& rhs)
|
||||
parameter_list_t& operator=(parameter_list_t&& rhs)
|
||||
noexcept(std::is_nothrow_move_assignable<std::tuple<typename Parameter::_member_t&...>>::value)
|
||||
{
|
||||
_parameter_tuple = std::move(rhs._parameter_tuple);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~named_parameter_list_t() = default;
|
||||
~parameter_list_t() = default;
|
||||
|
||||
std::tuple<typename Parameter::_value_type::_cpp_value_type&...> _parameter_tuple;
|
||||
using parameter_tuple_t = std::tuple<typename Parameter::_value_type::_cpp_value_type&...>;
|
||||
using size = std::tuple_size<parameter_tuple_t>;
|
||||
parameter_tuple_t _parameter_tuple;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
@ -107,11 +109,10 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Exp>
|
||||
auto named_parameter_list(const Exp& exp)
|
||||
-> named_parameter_list_t<typename detail::get_parameter_tuple<typename std::decay<Exp>::type>::type>
|
||||
{
|
||||
return {};
|
||||
}
|
||||
struct make_parameter_list_t
|
||||
{
|
||||
using type = parameter_list_t<typename detail::get_parameter_tuple<typename std::decay<Exp>::type>::type>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define SQLPP_PREPARED_SELECT_H
|
||||
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <tuple>
|
||||
#include <sqlpp11/result.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -37,8 +37,18 @@ namespace sqlpp
|
||||
{
|
||||
using _result_row_t = typename Select::_result_row_t;
|
||||
using _parameter_list_t = typename Select::_parameter_list_t;
|
||||
using _dynamic_names_t = typename Select::_dynamic_names_t;
|
||||
using _handle_t = typename Db::_prepared_handle_t;
|
||||
|
||||
typename Db::prepared_query_handle _name;
|
||||
auto run(Db& db) const
|
||||
-> result_t<decltype(db.run_prepared_select(this))>
|
||||
{
|
||||
return {db.run_prepared_select(_handle, params), _dynamic_names};
|
||||
}
|
||||
|
||||
_parameter_list_t params;
|
||||
_dynamic_names_t _dynamic_names;
|
||||
_handle_t _handle;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -33,31 +33,27 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename ResultRow, typename DynamicNames>
|
||||
template<typename DbResult>
|
||||
class result_t
|
||||
{
|
||||
using db_result_t = typename Db::_result_t;
|
||||
using db_result_t = DbResult;
|
||||
using result_row_t = typename db_result_t::result_row_t;
|
||||
|
||||
db_result_t _result;
|
||||
raw_result_row_t _raw_result_row;
|
||||
raw_result_row_t _end;
|
||||
DynamicNames _dynamic_columns; // only needed in case of dynamic columns in the select
|
||||
ResultRow _result_row;
|
||||
db_result_t _db_result;
|
||||
result_row_t _result_row;
|
||||
result_row_t _end;
|
||||
|
||||
public:
|
||||
result_t():
|
||||
_raw_result_row({}),
|
||||
_end({}),
|
||||
_dynamic_columns(),
|
||||
_result_row(_raw_result_row, _dynamic_columns)
|
||||
_db_result(),
|
||||
_result_row(),
|
||||
_end()
|
||||
{}
|
||||
|
||||
result_t(db_result_t&& result, DynamicNames dynamic_columns):
|
||||
_result(std::move(result)),
|
||||
_raw_result_row(_result.next()),
|
||||
_end({}),
|
||||
_dynamic_columns(dynamic_columns),
|
||||
_result_row(_raw_result_row, _dynamic_columns)
|
||||
result_t(db_result_t&& result):
|
||||
_db_result(std::move(result)),
|
||||
_result_row(_db_result.next()),
|
||||
_end({})
|
||||
{}
|
||||
|
||||
result_t(const result_t&) = delete;
|
||||
@ -69,26 +65,26 @@ namespace sqlpp
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator(result_t& result, raw_result_row_t& raw_result_row):
|
||||
iterator(result_t& result, result_row_t& result_row):
|
||||
_result(result),
|
||||
_raw_result_row(raw_result_row)
|
||||
_result_row(result_row)
|
||||
{
|
||||
//std::cerr << "result::iterator::constructor" << std::endl;
|
||||
}
|
||||
|
||||
const ResultRow& operator*() const
|
||||
const result_row_t& operator*() const
|
||||
{
|
||||
return _result.front();
|
||||
}
|
||||
|
||||
const ResultRow* operator->() const
|
||||
const result_row_t* operator->() const
|
||||
{
|
||||
return &_result.front();
|
||||
}
|
||||
|
||||
bool operator==(const iterator& rhs) const
|
||||
{
|
||||
return _raw_result_row == rhs._raw_result_row;
|
||||
return _result_row == rhs._result_row;
|
||||
}
|
||||
|
||||
bool operator!=(const iterator& rhs) const
|
||||
@ -102,12 +98,12 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
result_t& _result;
|
||||
raw_result_row_t& _raw_result_row;
|
||||
result_row_t& _result_row;
|
||||
};
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(*this, _raw_result_row);
|
||||
return iterator(*this, _result_row);
|
||||
}
|
||||
|
||||
iterator end()
|
||||
@ -115,20 +111,19 @@ namespace sqlpp
|
||||
return iterator(*this, _end);
|
||||
}
|
||||
|
||||
const ResultRow& front() const
|
||||
const result_row_t& front() const
|
||||
{
|
||||
return _result_row;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return _raw_result_row == _end;
|
||||
return _result_row == _end;
|
||||
}
|
||||
|
||||
void pop_front()
|
||||
{
|
||||
_raw_result_row = _result.next();
|
||||
_result_row = _raw_result_row;
|
||||
_result_row = _db_result.next();
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -103,21 +103,36 @@ namespace sqlpp
|
||||
{
|
||||
using _impl = detail::result_row_impl<0, 0, NamedExpr...>;
|
||||
bool _is_row;
|
||||
raw_result_row_t _raw_result_row;
|
||||
|
||||
result_row_t():
|
||||
_raw_result_row(),
|
||||
_impl(_raw_result_row),
|
||||
_is_row(false)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
result_row_t(const raw_result_row_t& raw_result_row, const T&):
|
||||
_impl(raw_result_row),
|
||||
_is_row(raw_result_row.data != nullptr)
|
||||
_raw_result_row(raw_result_row),
|
||||
_impl(_raw_result_row),
|
||||
_is_row(_raw_result_row.data != nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
result_row_t& operator=(const raw_result_row_t& raw_result_row)
|
||||
{
|
||||
_impl::operator=(raw_result_row);
|
||||
_is_row = raw_result_row.data != nullptr;
|
||||
_raw_result_row = raw_result_row;
|
||||
_is_row = _raw_result_row.data != nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const result_row_t& rhs)
|
||||
{
|
||||
return _raw_result_row == rhs._raw_result_row;
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return _is_row;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <sqlpp11/offset.h>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_select.h>
|
||||
|
||||
#include <sqlpp11/detail/wrong.h>
|
||||
#include <sqlpp11/detail/make_flag_tuple.h>
|
||||
@ -569,7 +570,21 @@ namespace sqlpp
|
||||
|
||||
// Execute
|
||||
template<typename Db>
|
||||
result_t<Db, _result_row_t, _dynamic_names_t> run(Db& db) const
|
||||
auto run(Db& db) const
|
||||
-> result_t<decltype(db.select(*this))>
|
||||
{
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
static_assert(_parameter_list_t::size::value == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
// FIXME: Check for missing aliases (if references are used)
|
||||
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||
|
||||
return {db.select(*this)};
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
prepared_select_t<Db, select_t> run(Db& db) const
|
||||
{
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
@ -578,8 +593,9 @@ namespace sqlpp
|
||||
|
||||
std::ostringstream oss;
|
||||
serialize(oss, db);
|
||||
return {db.select(oss.str()), _expression_list._dynamic_expressions._dynamic_expression_names};
|
||||
return {db.prepare_select(oss.str()), _expression_list._dynamic_expressions._dynamic_expression_names};
|
||||
}
|
||||
*/
|
||||
|
||||
Flags _flags;
|
||||
ExpressionList _expression_list;
|
||||
@ -590,7 +606,8 @@ namespace sqlpp
|
||||
OrderBy _order_by;
|
||||
Limit _limit;
|
||||
Offset _offset;
|
||||
decltype(named_parameter_list(std::declval<std::tuple<Where, Having>>())) _parameter_list;
|
||||
using _parameter_t = std::tuple<Where, Having>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
|
||||
};
|
||||
|
||||
// construct select flag list
|
||||
|
@ -77,7 +77,9 @@ int main()
|
||||
|
||||
// OK, fine, now create a named parameter list from an expression
|
||||
{
|
||||
auto npl = named_parameter_list(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||
using Exp = decltype(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||
using T = sqlpp::make_parameter_list_t<Exp>::type;
|
||||
T npl;
|
||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_cpp_value_type, decltype(npl.alpha)>::value, "type requirement");
|
||||
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_cpp_value_type, decltype(npl.beta)>::value, "type requirement");
|
||||
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_cpp_value_type, decltype(npl.gamma)>::value, "type requirement");
|
||||
@ -89,7 +91,10 @@ int main()
|
||||
|
||||
// Wonderful, now take a look at the parameter list of a select
|
||||
{
|
||||
auto npl = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma))._parameter_list;
|
||||
auto s = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||
using S = decltype(s);
|
||||
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||
T npl;
|
||||
|
||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_cpp_value_type, decltype(npl.alpha)>::value, "type requirement");
|
||||
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_cpp_value_type, decltype(npl.beta)>::value, "type requirement");
|
||||
@ -102,6 +107,8 @@ int main()
|
||||
auto x = npl;
|
||||
x = npl;
|
||||
std::cerr << x.alpha << std::endl;
|
||||
x = decltype(npl)();
|
||||
std::cerr << x.alpha << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user