0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Accepting parameters in other parts of select now

(formerly only where and having clauses)
This commit is contained in:
Roland Bock 2014-01-08 08:02:17 +01:00
parent e601747fca
commit a122924d37
7 changed files with 94 additions and 43 deletions

View File

@ -43,6 +43,7 @@ namespace sqlpp
{
using _is_group_by = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
// ensure one argument at least
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
@ -73,7 +74,13 @@ namespace sqlpp
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
}
std::tuple<Expr...> _expressions;
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_expressions, index);
return index;
}
_parameter_tuple_t _expressions;
detail::serializable_list<Database> _dynamic_expressions;
};

View File

@ -33,19 +33,29 @@
namespace sqlpp
{
struct limit_t
{
using _is_limit = std::true_type;
template<typename Limit>
struct limit_t
{
using _is_limit = std::true_type;
using _parameter_tuple_t = std::tuple<Limit>;
static_assert(std::is_integral<Limit>::value
or (is_parameter_t<Limit>::value and is_numeric_t<Limit>::value), "limit requires an integral value or integral parameter");
template<typename Db>
void serialize(std::ostream& os, Db& db) const
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
static_assert(Db::_supports_limit, "limit not supported by current database");
os << " LIMIT " << _limit;
}
size_t _set_parameter_index(size_t index)
{
static_assert(Db::_supports_limit, "limit not supported by current database");
os << " LIMIT " << _limit;
index = set_parameter_index(_limit, index);
return index;
}
std::size_t _limit;
};
Limit _limit;
};
struct dynamic_limit_t
{

View File

@ -33,18 +33,29 @@
namespace sqlpp
{
struct offset_t
{
using _is_offset = std::true_type;
template<typename Offset>
struct offset_t
{
using _is_offset = std::true_type;
using _parameter_tuple_t = std::tuple<Offset>;
static_assert(std::is_integral<Offset>::value
or (is_parameter_t<Offset>::value and is_numeric_t<Offset>::value), "offset requires an integral value or integral parameter");
template<typename Db>
void serialize(std::ostream& os, Db& db) const
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
os << " OFFSET " << _offset;
}
size_t _set_parameter_index(size_t index)
{
os << " OFFSET " << _offset;
index = set_parameter_index(_offset, index);
return index;
}
const std::size_t _offset;
};
Offset _offset;
};
struct dynamic_offset_t
{

View File

@ -41,6 +41,7 @@ namespace sqlpp
{
using _is_order_by = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
@ -71,7 +72,13 @@ namespace sqlpp
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
}
std::tuple<Expr...> _expressions;
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_expressions, index);
return index;
}
_parameter_tuple_t _expressions;
detail::serializable_list<Database> _dynamic_expressions;
};

View File

@ -111,7 +111,7 @@ namespace sqlpp
using _result_row_t = typename ExpressionList::_result_row_t;
using _dynamic_names_t = typename ExpressionList::_dynamic_names_t;
using _parameter_tuple_t = std::tuple<Where, Having>;
using _parameter_tuple_t = std::tuple<ExpressionList, Where, GroupBy, Having, OrderBy, Limit, Offset>;
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
// Indicators
@ -129,7 +129,6 @@ namespace sqlpp
{
static_assert(std::is_same<select_t, sqlpp::select_t<Database, Flags, ExpressionList>>::value,
"basic constructor only available for select_t<Flags, ExpressionList> (default template parameters)");
_set_parameter_index(0);
}
select_t(const select_t& rhs) = default;
@ -153,7 +152,6 @@ namespace sqlpp
_limit(std::move(limit)),
_offset(std::move(offset))
{
_set_parameter_index(0);
}
select_t(const Flags& flags, const ExpressionList& expression_list, const From& from,
@ -169,7 +167,6 @@ namespace sqlpp
_limit(limit),
_offset(offset)
{
_set_parameter_index(0);
}
auto dynamic_columns()
@ -443,23 +440,24 @@ namespace sqlpp
return *this;
}
auto limit(std::size_t limit)
-> set_limit_t<limit_t>
{
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
return {
template<typename Expr>
auto limit(Expr limit)
-> set_limit_t<limit_t<typename std::decay<Expr>::type>>
{
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
return {
_flags,
_expression_list,
_from,
_where,
_group_by,
_having,
_order_by,
{limit},
_offset,
};
}
_expression_list,
_from,
_where,
_group_by,
_having,
_order_by,
{limit},
_offset,
};
}
auto dynamic_limit(std::size_t limit = 0)
->set_limit_t<dynamic_limit_t>
@ -488,8 +486,9 @@ namespace sqlpp
return *this;
}
auto offset(std::size_t offset)
-> set_offset_t<offset_t>
template<typename Expr>
auto offset(Expr offset)
-> set_offset_t<offset_t<typename std::decay<Expr>::type>>
{
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit");
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
@ -602,21 +601,29 @@ namespace sqlpp
return {db.select(*this), get_dynamic_names()};
}
// Prepare
template<typename Db>
prepared_select_t<typename std::decay<Db>::type, select_t> prepare(Db& db) const
auto prepare(Db& db)
-> prepared_select_t<typename std::decay<Db>::type, select_t>
{
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()");
// 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.
_set_parameter_index(0);
return {{}, get_dynamic_names(), db.prepare_select(*this)};
}
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_expression_list, index);
index = set_parameter_index(_where, index);
index = set_parameter_index(_group_by, index);
index = set_parameter_index(_having, index);
index = set_parameter_index(_order_by, index);
index = set_parameter_index(_limit, index);
index = set_parameter_index(_offset, index);
return index;
}

View File

@ -107,6 +107,7 @@ namespace sqlpp
{
using _is_select_expression_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<NamedExpr...>;
// check for duplicate select expressions
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
@ -160,7 +161,13 @@ namespace sqlpp
_dynamic_expressions.serialize(os, db, sizeof...(NamedExpr) == 0);
}
std::tuple<NamedExpr...> _expressions;
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_expressions, index);
return index;
}
_parameter_tuple_t _expressions;
detail::dynamic_select_expression_list<Database> _dynamic_expressions;
};

View File

@ -50,8 +50,10 @@ namespace sqlpp
template<typename Database, typename... Expr> struct order_by_t;
template<typename Limit>
struct limit_t;
template<typename Offset>
struct offset_t;
template<