From 1360b1d9dbbf502076c87f031888f5bafcedd10d Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Thu, 2 Jan 2014 13:11:19 +0100 Subject: [PATCH] Turned value_type::parameter_t into a non-template --- include/sqlpp11/boolean.h | 17 ++++++++++---- include/sqlpp11/expression.h | 10 ++++---- include/sqlpp11/having.h | 4 ++-- include/sqlpp11/integral.h | 39 ++++++++++++++++++++++++++------ include/sqlpp11/like.h | 2 +- include/sqlpp11/parameter.h | 10 ++++---- include/sqlpp11/parameter_list.h | 15 ++++++++---- include/sqlpp11/result_row.h | 35 +++++++++++++++++++++++++--- include/sqlpp11/select.h | 2 +- include/sqlpp11/text.h | 17 ++++++++++---- include/sqlpp11/type_traits.h | 6 ++--- include/sqlpp11/where.h | 4 ++-- tests/PreparedTest.cpp | 12 +++++----- 13 files changed, 124 insertions(+), 49 deletions(-) diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index 937a4682..c4d6eb05 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -59,25 +59,31 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = bool; - template struct _parameter_t { using _value_type = boolean; - _parameter_t(): + _parameter_t(const std::true_type&): + _trivial_value_is_null(true), _value(false), - _is_null(TrivialValueIsNull and _is_trivial()) + _is_null(_trivial_value_is_null and _is_trivial()) + {} + + _parameter_t(const std::false_type&): + _trivial_value_is_null(false), + _value(false), + _is_null(_trivial_value_is_null and _is_trivial()) {} _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(TrivialValueIsNull and _is_trivial()) + _is_null(_trivial_value_is_null and _is_trivial()) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (TrivialValueIsNull and _is_trivial()); + _is_null = (_trivial_value_is_null and _is_trivial()); return *this; } @@ -109,6 +115,7 @@ namespace sqlpp operator _cpp_value_type() const { return value(); } private: + bool _trivial_value_is_null; _cpp_value_type _value; bool _is_null; }; diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h index b79a89de..1b655e4a 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 _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; size_t _set_parameter_index(size_t index) { @@ -71,7 +71,7 @@ namespace sqlpp struct equal_t: public ValueType::template operators> { using _value_type = ValueType; - using _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; size_t _set_parameter_index(size_t index) { @@ -117,7 +117,7 @@ namespace sqlpp struct not_equal_t: public ValueType::template operators> { using _value_type = ValueType; - using _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; size_t _set_parameter_index(size_t index) { @@ -163,7 +163,7 @@ namespace sqlpp struct not_t: public ValueType::template operators> { using _value_type = ValueType; - using _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; size_t _set_parameter_index(size_t index) { @@ -205,7 +205,7 @@ namespace sqlpp struct binary_expression_t: public O::_value_type::template operators> { using _value_type = typename O::_value_type; - using _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; size_t _set_parameter_index(size_t index) { diff --git a/include/sqlpp11/having.h b/include/sqlpp11/having.h index d0c67e6f..eed521d5 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/having.h @@ -70,8 +70,8 @@ namespace sqlpp return set_parameter_index(_expressions, index); } - using _parameter_t = std::tuple; - _parameter_t _expressions; + using _parameter_tuple_t = std::tuple; + _parameter_tuple_t _expressions; // FIXME: Do we need those? detail::serializable_list _dynamic_expressions; }; diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index fc9211d1..7c28fcad 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -48,25 +48,37 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = int64_t; - template struct _parameter_t { using _value_type = integral; - _parameter_t(): + _parameter_t(const std::true_type&): + _trivial_value_is_null(true), _value(0), - _is_null(TrivialValueIsNull and _is_trivial()) + _is_null(_trivial_value_is_null and _is_trivial()) + {} + + _parameter_t(const std::false_type&): + _trivial_value_is_null(false), + _value(0), + _is_null(_trivial_value_is_null and _is_trivial()) + {} + + _parameter_t(bool trivial_value_is_null): + _trivial_value_is_null(trivial_value_is_null), + _value(0), + _is_null(_trivial_value_is_null and _is_trivial()) {} _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(TrivialValueIsNull and _is_trivial()) + _is_null(_trivial_value_is_null and _is_trivial()) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (TrivialValueIsNull and _is_trivial()); + _is_null = (_trivial_value_is_null and _is_trivial()); return *this; } @@ -90,14 +102,21 @@ namespace sqlpp return _is_null; } - const _cpp_value_type* value() const + const _cpp_value_type& value() const { - return &_value; + return _value; } operator _cpp_value_type() const { return _value; } + template + void bind(Target& target, size_t index) const + { + target.bind_integral_parameter(index, &_value, _is_null); + } + private: + bool _trivial_value_is_null; _cpp_value_type _value; bool _is_null; }; @@ -151,6 +170,12 @@ namespace sqlpp operator _cpp_value_type() const { return value(); } + template + void bind(Target& target, size_t i) const // Hint: Cannot use index here because of dynamic result rows which can use index==0 for several fields + { + target.bind_integral_result(i, &_value, _is_null); + } + private: bool _is_valid; bool _is_null; diff --git a/include/sqlpp11/like.h b/include/sqlpp11/like.h index 8e9b5bab..4ee099d0 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 _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; struct _value_type: public ValueType::_base_value_type // we require fully defined boolean here { diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 9959082d..2563f32c 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -33,14 +33,16 @@ namespace sqlpp { - template + template struct parameter_t { using _value_type = ValueType; - using _parameter_type = typename ValueType::template _parameter_t; using _is_parameter = std::true_type; using _is_expression_t = std::true_type; - using _member_t = typename NameType::_name_t::template _member_t<_parameter_type>; + using _instance_t = typename NameType::_name_t::template _member_t; + using _trivial_value_is_null = TrivialValueIsNull; + + static_assert(std::is_same<_trivial_value_is_null, std::true_type>::value or std::is_same<_trivial_value_is_null, std::false_type>::value, "Invalid template parameter TrivialValueIsNull"); template void serialize(std::ostream& os, Db& db) const @@ -61,7 +63,7 @@ namespace sqlpp size_t index; }; - template::type>::value> + template::type>> auto parameter(NamedExpr&& namedExpr) -> parameter_t::type::_value_type, typename std::decay::type, TrivialValueIsNull> { diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index 498599e7..406d752d 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -39,11 +39,15 @@ namespace sqlpp }; template - struct parameter_list_t>: public Parameter::_member_t... + struct parameter_list_t>: public Parameter::_instance_t... { - using _member_tuple_t = std::tuple; + using _member_tuple_t = std::tuple; using size = std::integral_constant; + parameter_list_t(): + Parameter::_instance_t({typename Parameter::_trivial_value_is_null()})... + {} + template void _bind(Target& target) const { @@ -56,7 +60,8 @@ namespace sqlpp template void _bind_impl(Target& target, const index_t&) const { - target.bind_param(index, static_cast::type&>(*this)()); + const auto& parameter = static_cast::type&>(*this)(); + parameter.bind(target, index); _bind_impl(target, index_t()); } @@ -88,9 +93,9 @@ 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; }; } diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 8ffda248..da67140a 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -37,6 +37,8 @@ namespace sqlpp { namespace detail { + template struct index_t {}; // this is just for overloading + template struct result_row_impl; @@ -60,14 +62,22 @@ namespace sqlpp _rest::operator=(raw_result_row); return *this; } + + template + void _bind(Target& target) + { + _field::operator().bind(target, index); + std::cerr << "binding result " << index << std::endl; + _rest::_bind(target); + } }; template struct result_row_impl>, Rest...>: - public AliasProvider::_name_t::template _member_t>, // level prevents identical closures to be present twice in the inheritance tree + public AliasProvider::_name_t::template _member_t>, // level prevents identical closures to be present twice in the inheritance tree public result_row_impl { - using _multi_field = typename AliasProvider::_name_t::template _member_t>; + using _multi_field = typename AliasProvider::_name_t::template _member_t>; using _rest = result_row_impl; static constexpr size_t _last_index = _rest::_last_index; @@ -82,6 +92,13 @@ namespace sqlpp _rest::operator=(raw_result_row); return *this; } + + template + void _bind(const Target& target) + { + _multi_field::_bind(target); + _rest::_bind(target); + } }; template @@ -95,6 +112,11 @@ namespace sqlpp { return *this; } + + template + void _bind(Target& target) + { + } }; } @@ -104,6 +126,7 @@ namespace sqlpp using _impl = detail::result_row_impl<0, 0, NamedExpr...>; bool _is_row; raw_result_row_t _raw_result_row; + static constexpr size_t _last_static_index = _impl::_last_index; result_row_t(): _impl({}), @@ -145,8 +168,14 @@ namespace sqlpp static constexpr size_t static_size() { - return sizeof...(NamedExpr); + return _last_static_index; } + + template + void bind_result(Target& target) + { + _impl::_bind(target); + } }; template diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 3d38183a..9fa3592f 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -617,7 +617,7 @@ namespace sqlpp OrderBy _order_by; Limit _limit; Offset _offset; - using _parameter_t = std::tuple; + using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; }; diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 59e3b803..83e3e6a4 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -48,25 +48,31 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = std::string; - template struct _parameter_t { using _value_type = integral; - _parameter_t(): + _parameter_t(const std::true_type&): + _trivial_value_is_null(true), _value(""), - _is_null(TrivialValueIsNull and _is_trivial()) + _is_null(_trivial_value_is_null and _is_trivial()) + {} + + _parameter_t(const std::false_type&): + _trivial_value_is_null(false), + _value(""), + _is_null(_trivial_value_is_null and _is_trivial()) {} _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(TrivialValueIsNull and _is_trivial()) + _is_null(_trivial_value_is_null and _is_trivial()) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (TrivialValueIsNull and _is_trivial()); + _is_null = (_trivial_value_is_null and _is_trivial()); return *this; } @@ -98,6 +104,7 @@ namespace sqlpp operator _cpp_value_type() const { return value(); } private: + bool _trivial_value_is_null; _cpp_value_type _value; bool _is_null; }; diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index d4afca01..ac3967d6 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -47,12 +47,12 @@ namespace sqlpp namespace detail\ {\ template\ - struct name##_impl: std::false_type {};\ + struct name##_impl { using type = std::false_type; };\ template\ - struct name##_impl::value>::type>: std::true_type {};\ + struct name##_impl::value>::type> { using type = std::true_type; };\ }\ template\ - struct name##_t: detail::name##_impl {}; + using name##_t = typename detail::name##_impl::type; #define SQLPP_TYPE_TRAIT_GENERATOR(name) \ namespace detail\ diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index a7204273..d9996d3f 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -69,8 +69,8 @@ namespace sqlpp return set_parameter_index(_expressions, index); } - using _parameter_t = std::tuple; - _parameter_t _expressions; + using _parameter_tuple_t = std::tuple; + _parameter_tuple_t _expressions; // FIXME: Do we need those? detail::serializable_list _dynamic_expressions; }; } diff --git a/tests/PreparedTest.cpp b/tests/PreparedTest.cpp index 6fac99e2..f3c36cc1 100644 --- a/tests/PreparedTest.cpp +++ b/tests/PreparedTest.cpp @@ -80,9 +80,9 @@ int main() 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::type; T npl; - static_assert(std::is_same, decltype(npl.alpha)>::value, "type requirement"); - static_assert(std::is_same, decltype(npl.beta)>::value, "type requirement"); - static_assert(std::is_same, decltype(npl.gamma)>::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); } // Wonderful, now take a look at the parameter list of a select @@ -92,9 +92,9 @@ int main() using T = sqlpp::make_parameter_list_t::type; T npl; - static_assert(std::is_same, decltype(npl.alpha)>::value, "type requirement"); - static_assert(std::is_same, decltype(npl.beta)>::value, "type requirement"); - static_assert(std::is_same, decltype(npl.gamma)>::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same::value, "type requirement"); npl.alpha = 7; auto x = npl; x = npl;