0
0
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:
Roland Bock 2013-12-15 13:02:41 +01:00
parent 51786a9f1d
commit 9597c3712c
6 changed files with 98 additions and 53 deletions

View File

@ -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>;
};
}

View File

@ -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;
};
}

View File

@ -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();
}
};

View File

@ -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;

View File

@ -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

View File

@ -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;
}