From 221e20918b1f08122331920f53c17a4d9d42c81f Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Tue, 26 Nov 2013 23:45:31 +0100 Subject: [PATCH] select now collects parameters from Where and Having --- include/sqlpp11/expression.h | 10 ++++---- include/sqlpp11/having.h | 3 ++- include/sqlpp11/like.h | 2 +- include/sqlpp11/parameter_list.h | 44 ++++++++++++++++++++++++++------ include/sqlpp11/select.h | 2 ++ include/sqlpp11/where.h | 3 ++- tests/FunctionTest.cpp | 2 +- tests/PreparedTest.cpp | 30 ++++++++++++++++++++++ tests/TabSample.h | 10 ++++++++ 9 files changed, 89 insertions(+), 17 deletions(-) diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h index 261fb2fa..607bca33 100644 --- a/include/sqlpp11/expression.h +++ b/include/sqlpp11/expression.h @@ -40,7 +40,7 @@ namespace sqlpp using _is_assignment = std::true_type; using column_type = Lhs; using value_type = Rhs; - using _parameters = std::tuple; + using _parameter_t = std::tuple; template void serialize(std::ostream& os, Db& db) const @@ -65,7 +65,7 @@ namespace sqlpp struct equal_t: public ValueType::template operators> { using _value_type = ValueType; - using _parameters = std::tuple; + using _parameter_t = std::tuple; template equal_t(L&& l, R&& r): @@ -105,7 +105,7 @@ namespace sqlpp struct not_equal_t: public ValueType::template operators> { using _value_type = ValueType; - using _parameters = std::tuple; + using _parameter_t = std::tuple; template not_equal_t(L&& l, R&& r): @@ -145,7 +145,7 @@ namespace sqlpp struct not_t: public ValueType::template operators> { using _value_type = ValueType; - using _parameters = std::tuple; + using _parameter_t = std::tuple; not_t(Lhs l): _lhs(l) @@ -182,7 +182,7 @@ namespace sqlpp struct binary_expression_t: public O::_value_type::template operators> { using _value_type = typename O::_value_type; - using _parameters = std::tuple; + using _parameter_t = std::tuple; binary_expression_t(Lhs&& l, Rhs&& r): _lhs(std::move(l)), diff --git a/include/sqlpp11/having.h b/include/sqlpp11/having.h index 0547a969..ec31d62e 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/having.h @@ -65,7 +65,8 @@ namespace sqlpp _dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0); } - std::tuple _expressions; + using _parameter_t = std::tuple; + _parameter_t _expressions; detail::serializable_list _dynamic_expressions; }; diff --git a/include/sqlpp11/like.h b/include/sqlpp11/like.h index f2ea27cd..d0d037b1 100644 --- a/include/sqlpp11/like.h +++ b/include/sqlpp11/like.h @@ -41,7 +41,7 @@ namespace sqlpp { static_assert(is_text_t::value, "Operand for like() has to be a text"); static_assert(is_text_t::value, "Pattern for like() has to be a text"); - using _parameters = std::tuple; + using _parameter_t = std::tuple; struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here { diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index 071e849e..249c0391 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -27,33 +27,54 @@ #ifndef SQLPP_PARAMETER_LIST_H #define SQLPP_PARAMETER_LIST_H +#include #include namespace sqlpp { + template + struct named_parameter_list_t + { + static_assert(detail::wrong::value, "Template parameter for named_parameter_list_t has to be a tuple"); + }; + template - struct named_parameter_list_t: public Parameter::_member_t... + struct named_parameter_list_t>: public Parameter::_member_t... { named_parameter_list_t(): Parameter::_member_t()..., _parameter_tuple(static_cast(*this)()...) {} - named_parameter_list_t(const named_parameter_list_t& rhs): + named_parameter_list_t(const named_parameter_list_t& rhs) + noexcept(std::is_nothrow_copy_constructible>::value): Parameter::_member_t(static_cast(rhs))..., _parameter_tuple(static_cast(*this)()...) {} - named_parameter_list_t(named_parameter_list_t&& rhs): + named_parameter_list_t(named_parameter_list_t&& rhs) + noexcept(std::is_nothrow_move_constructible>::value): Parameter::_member_t(std::move(static_cast(rhs)))..., _parameter_tuple(static_cast(*this)()...) {} - named_parameter_list_t& operator=(const named_parameter_list_t&) = delete; - named_parameter_list_t& operator=(named_parameter_list_t&&) = delete; + named_parameter_list_t& operator=(const named_parameter_list_t& rhs) + noexcept(std::is_nothrow_copy_assignable>::value) + { + _parameter_tuple = rhs._parameter_tuple; + return *this; + } + + named_parameter_list_t& operator=(named_parameter_list_t&& rhs) + noexcept(std::is_nothrow_move_assignable>::value) + { + _parameter_tuple = std::move(rhs._parameter_tuple); + return *this; + } + ~named_parameter_list_t() = default; - std::tuple _parameter_tuple; + std::tuple _parameter_tuple; }; namespace detail @@ -78,13 +99,20 @@ namespace sqlpp }; template - struct get_parameter_tuple::value, void>::type> + struct get_parameter_tuple::value, void>::type> { - using type = typename get_parameter_tuple::type; + using type = typename get_parameter_tuple::type; }; } + template + auto named_parameter_list(const Exp& exp) + -> named_parameter_list_t::type>::type> + { + return {}; + } + } #endif diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 82fb0869..4f62e01e 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -589,6 +590,7 @@ namespace sqlpp OrderBy _order_by; Limit _limit; Offset _offset; + decltype(named_parameter_list(std::declval>())) _parameter_list; }; // construct select flag list diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index 56d517a3..ca2008d4 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -64,7 +64,8 @@ namespace sqlpp _dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0); } - std::tuple _expressions; + using _parameter_t = std::tuple; + _parameter_t _expressions; detail::serializable_list _dynamic_expressions; }; } diff --git a/tests/FunctionTest.cpp b/tests/FunctionTest.cpp index 0cf35d4f..f4b24e93 100644 --- a/tests/FunctionTest.cpp +++ b/tests/FunctionTest.cpp @@ -32,6 +32,7 @@ #include DbMock db = {}; +SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen); int main() { @@ -374,7 +375,6 @@ int main() // test verbatim_table alias { - SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen); using T = decltype(sqlpp::verbatim_table("cheesecake").as(kaesekuchen)); static_assert(not sqlpp::is_named_expression_t::value, "type requirement"); static_assert(not sqlpp::is_expression_t::value, "type requirement"); diff --git a/tests/PreparedTest.cpp b/tests/PreparedTest.cpp index eed5920d..ae6fc935 100644 --- a/tests/PreparedTest.cpp +++ b/tests/PreparedTest.cpp @@ -27,6 +27,7 @@ #include "MockDb.h" #include "is_regular.h" #include +#include #include @@ -74,6 +75,35 @@ int main() static_assert(std::is_same>::value, "type requirement"); } + // 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)); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + + static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement"); + static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement"); + static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.gamma)&>::value, "type requirement"); + } + + // 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; + + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + + static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement"); + static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement"); + static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.gamma)&>::value, "type requirement"); + npl.alpha = 7; + auto x = npl; + x = npl; + std::cerr << x.alpha << std::endl; + } + return 0; } diff --git a/tests/TabSample.h b/tests/TabSample.h index 903bf62d..85f78ac1 100644 --- a/tests/TabSample.h +++ b/tests/TabSample.h @@ -42,6 +42,8 @@ namespace TabFoo_ struct _member_t { T epsilon; + T& operator()() { return epsilon; } + const T& operator()() const { return epsilon; } }; }; using _value_type = sqlpp::bigint; @@ -59,6 +61,8 @@ namespace TabFoo_ struct _member_t { T omega; + T& operator()() { return omega; } + const T& operator()() const { return omega; } }; }; using _value_type = sqlpp::floating_point; @@ -102,6 +106,8 @@ namespace TabSample_ struct _member_t { T alpha; + T& operator()() { return alpha; } + const T& operator()() const { return alpha; } }; }; using _value_type = sqlpp::bigint; @@ -124,6 +130,8 @@ namespace TabSample_ struct _member_t { T beta; + T& operator()() { return beta; } + const T& operator()() const { return beta; } }; }; using _value_type = sqlpp::varchar; @@ -144,6 +152,8 @@ namespace TabSample_ struct _member_t { T gamma; + T& operator()() { return gamma; } + const T& operator()() const { return gamma; } }; }; using _value_type = sqlpp::boolean;