From a122924d3751f7013c9eaa1cabdaa89e444236e0 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Wed, 8 Jan 2014 08:02:17 +0100 Subject: [PATCH] Accepting parameters in other parts of select now (formerly only where and having clauses) --- include/sqlpp11/group_by.h | 9 +++- include/sqlpp11/limit.h | 28 +++++++++---- include/sqlpp11/offset.h | 27 ++++++++---- include/sqlpp11/order_by.h | 9 +++- include/sqlpp11/select.h | 53 ++++++++++++++---------- include/sqlpp11/select_expression_list.h | 9 +++- include/sqlpp11/select_fwd.h | 2 + 7 files changed, 94 insertions(+), 43 deletions(-) diff --git a/include/sqlpp11/group_by.h b/include/sqlpp11/group_by.h index 35312d0a..c25e462b 100644 --- a/include/sqlpp11/group_by.h +++ b/include/sqlpp11/group_by.h @@ -43,6 +43,7 @@ namespace sqlpp { using _is_group_by = std::true_type; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; // 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 _expressions; + size_t _set_parameter_index(size_t index) + { + index = set_parameter_index(_expressions, index); + return index; + } + + _parameter_tuple_t _expressions; detail::serializable_list _dynamic_expressions; }; diff --git a/include/sqlpp11/limit.h b/include/sqlpp11/limit.h index 4205be16..15ec9f08 100644 --- a/include/sqlpp11/limit.h +++ b/include/sqlpp11/limit.h @@ -33,19 +33,29 @@ namespace sqlpp { - struct limit_t - { - using _is_limit = std::true_type; + template + struct limit_t + { + using _is_limit = std::true_type; + using _parameter_tuple_t = std::tuple; + static_assert(std::is_integral::value + or (is_parameter_t::value and is_numeric_t::value), "limit requires an integral value or integral parameter"); - template - void serialize(std::ostream& os, Db& db) const + template + 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 { diff --git a/include/sqlpp11/offset.h b/include/sqlpp11/offset.h index 2ed223f9..18593d43 100644 --- a/include/sqlpp11/offset.h +++ b/include/sqlpp11/offset.h @@ -33,18 +33,29 @@ namespace sqlpp { - struct offset_t - { - using _is_offset = std::true_type; + template + struct offset_t + { + using _is_offset = std::true_type; + using _parameter_tuple_t = std::tuple; + static_assert(std::is_integral::value + or (is_parameter_t::value and is_numeric_t::value), "offset requires an integral value or integral parameter"); - template - void serialize(std::ostream& os, Db& db) const + + template + 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 { diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h index e8c5d22d..8f04cf0f 100644 --- a/include/sqlpp11/order_by.h +++ b/include/sqlpp11/order_by.h @@ -41,6 +41,7 @@ namespace sqlpp { using _is_order_by = std::true_type; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; // 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 _expressions; + size_t _set_parameter_index(size_t index) + { + index = set_parameter_index(_expressions, index); + return index; + } + + _parameter_tuple_t _expressions; detail::serializable_list _dynamic_expressions; }; diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 68e42f14..7f549c69 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -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; + using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; // Indicators @@ -129,7 +129,6 @@ namespace sqlpp { static_assert(std::is_same>::value, "basic constructor only available for select_t (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 - { - static_assert(not is_noop::value, "cannot call limit() without a from()"); - static_assert(is_noop::value, "cannot call limit() twice for a single select"); - return { + template + auto limit(Expr limit) + -> set_limit_t::type>> + { + static_assert(not is_noop::value, "cannot call limit() without a from()"); + static_assert(is_noop::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 @@ -488,8 +486,9 @@ namespace sqlpp return *this; } - auto offset(std::size_t offset) - -> set_offset_t + template + auto offset(Expr offset) + -> set_offset_t::type>> { static_assert(not is_noop::value, "cannot call offset() without a limit"); static_assert(is_noop::value, "cannot call offset() twice for a single select"); @@ -602,21 +601,29 @@ namespace sqlpp return {db.select(*this), get_dynamic_names()}; } + // Prepare template - prepared_select_t::type, select_t> prepare(Db& db) const + auto prepare(Db& db) + -> prepared_select_t::type, select_t> { static_assert(not is_noop::value, "cannot run select without having selected anything"); static_assert(is_from_t::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; } diff --git a/include/sqlpp11/select_expression_list.h b/include/sqlpp11/select_expression_list.h index 3fb6e0f5..cb1b25c3 100644 --- a/include/sqlpp11/select_expression_list.h +++ b/include/sqlpp11/select_expression_list.h @@ -107,6 +107,7 @@ namespace sqlpp { using _is_select_expression_list = std::true_type; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; // check for duplicate select expressions static_assert(not detail::has_duplicates::value, "at least one duplicate argument detected"); @@ -160,7 +161,13 @@ namespace sqlpp _dynamic_expressions.serialize(os, db, sizeof...(NamedExpr) == 0); } - std::tuple _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 _dynamic_expressions; }; diff --git a/include/sqlpp11/select_fwd.h b/include/sqlpp11/select_fwd.h index 57486a06..ec50ce1d 100644 --- a/include/sqlpp11/select_fwd.h +++ b/include/sqlpp11/select_fwd.h @@ -50,8 +50,10 @@ namespace sqlpp template struct order_by_t; + template struct limit_t; + template struct offset_t; template<