From 0f29e255d1171f358a9ef2813147746cf46ba705 Mon Sep 17 00:00:00 2001 From: rbock Date: Mon, 21 Jul 2014 09:53:17 +0200 Subject: [PATCH] Unified tvin/trivial_value_is_null usage for =,==,!= and ! --- include/sqlpp11/assignment.h | 60 ++++------------------------- include/sqlpp11/expression.h | 31 ++++++++++----- include/sqlpp11/insert_value_list.h | 22 +++++------ include/sqlpp11/rhs_is_null.h | 4 +- include/sqlpp11/tvin.h | 60 +---------------------------- include/sqlpp11/update_list.h | 10 ++--- 6 files changed, 47 insertions(+), 140 deletions(-) diff --git a/include/sqlpp11/assignment.h b/include/sqlpp11/assignment.h index 669be5b6..5307a6e8 100644 --- a/include/sqlpp11/assignment.h +++ b/include/sqlpp11/assignment.h @@ -43,12 +43,12 @@ namespace sqlpp using _traits = make_traits; using _recursive_traits = make_recursive_traits; - using _column_t = Lhs; - using _value_t = Rhs; + using _lhs_t = Lhs; + using _rhs_t = Rhs; - static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<_value_t, null_t>::value, "column must not be null"); + static_assert(can_be_null_t<_lhs_t>::value ? true : not (std::is_same<_rhs_t, null_t>::value or is_tvin_t<_rhs_t>::value), "column must not be null"); - assignment_t(_column_t lhs, _value_t rhs): + assignment_t(_lhs_t lhs, _rhs_t rhs): _lhs(lhs), _rhs(rhs) {} @@ -59,8 +59,8 @@ namespace sqlpp assignment_t& operator=(assignment_t&&) = default; ~assignment_t() = default; - _column_t _lhs; - _value_t _rhs; + _lhs_t _lhs; + _rhs_t _rhs; }; template @@ -70,7 +70,7 @@ namespace sqlpp static Context& _(const T& t, Context& context) { - if (((trivial_value_is_null_t::value or is_tvin_t::value) + if (((trivial_value_is_null_t::value or is_tvin_t::value) and is_trivial(t._rhs)) or (std::is_same::value)) { @@ -87,52 +87,6 @@ namespace sqlpp } }; - template - struct assignment_t> - { - using _traits = make_traits; - using _recursive_traits = make_recursive_traits; - - using _column_t = Lhs; - using _value_t = tvin_t; - - static_assert(can_be_null_t<_column_t>::value, "column cannot be null"); - - assignment_t(_column_t lhs, _value_t rhs): - _lhs(lhs), - _rhs(rhs) - {} - - assignment_t(const assignment_t&) = default; - assignment_t(assignment_t&&) = default; - assignment_t& operator=(const assignment_t&) = default; - assignment_t& operator=(assignment_t&&) = default; - ~assignment_t() = default; - - _column_t _lhs; - _value_t _rhs; - }; - - template - struct serializer_t>> - { - using T = assignment_t>; - - static Context& _(const T& t, Context& context) - { - serialize(simple_column(t._lhs), context); - if (t._rhs._value._is_trivial()) - { - context << "=NULL"; - } - else - { - context << "="; - serialize(t._rhs._value, context); - } - return context; - } - }; } #endif diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h index 28a72bb3..09b138a3 100644 --- a/include/sqlpp11/expression.h +++ b/include/sqlpp11/expression.h @@ -43,8 +43,10 @@ namespace sqlpp { using _traits = make_traits; using _recursive_traits = make_recursive_traits; + using _lhs_t = Lhs; + using _rhs_t = Rhs; - binary_expression_t(Lhs lhs, Rhs rhs): + binary_expression_t(_lhs_t lhs, _rhs_t rhs): _lhs(lhs), _rhs(rhs) {} @@ -55,8 +57,8 @@ namespace sqlpp binary_expression_t& operator=(binary_expression_t&&) = default; ~binary_expression_t() = default; - Lhs _lhs; - maybe_tvin_t _rhs; + _lhs_t _lhs; + _rhs_t _rhs; }; template @@ -68,7 +70,7 @@ namespace sqlpp { context << "("; serialize(t._lhs, context); - if (t._rhs._is_trivial()) + if (rhs_is_null(t)) { context << " IS NULL"; } @@ -88,6 +90,8 @@ namespace sqlpp { using _traits = make_traits; using _recursive_traits = make_recursive_traits; + using _lhs_t = Lhs; + using _rhs_t = Rhs; binary_expression_t(Lhs lhs, Rhs rhs): _lhs(lhs), @@ -100,8 +104,8 @@ namespace sqlpp binary_expression_t& operator=(binary_expression_t&&) = default; ~binary_expression_t() = default; - Lhs _lhs; - maybe_tvin_t _rhs; + _lhs_t _lhs; + _rhs_t _rhs; }; template @@ -113,7 +117,7 @@ namespace sqlpp { context << "("; serialize(t._lhs, context); - if (t._rhs._is_trivial()) + if (rhs_is_null(t)) { context << " IS NOT NULL"; } @@ -155,10 +159,17 @@ namespace sqlpp static Context& _(const T& t, Context& context) { context << "("; - context << "NOT "; - serialize(t._lhs, context); + if (trivial_value_is_null_t::value) + { + serialize(t._lhs, context); + context << " IS NULL "; + } + else + { + context << "NOT "; + serialize(t._rhs, context); + } context << ")"; - return context; } }; diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h index 513085d5..4ed222dd 100644 --- a/include/sqlpp11/insert_value_list.h +++ b/include/sqlpp11/insert_value_list.h @@ -97,8 +97,8 @@ namespace sqlpp ~insert_list_data_t() = default; std::tuple _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments) - std::tuple...> _columns; - std::tuple _values; + std::tuple...> _columns; + std::tuple _values; interpretable_list_t _dynamic_columns; interpretable_list_t _dynamic_values; }; @@ -107,7 +107,7 @@ namespace sqlpp struct insert_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _recursive_traits = make_recursive_traits; using _is_dynamic = is_database; @@ -134,9 +134,9 @@ namespace sqlpp { static_assert(_is_dynamic::value, "add must not be called for static from()"); static_assert(is_assignment_t::value, "add() arguments require to be assigments"); - using _assigned_columns = detail::make_type_set_t; - static_assert(not detail::is_element_of::value, "Must not assign value to column twice"); - static_assert(not must_not_insert_t::value, "add() argument must not be used in insert"); + using _assigned_columns = detail::make_type_set_t; + static_assert(not detail::is_element_of::value, "Must not assign value to column twice"); + static_assert(not must_not_insert_t::value, "add() argument must not be used in insert"); static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables::value, "add() contains a column from a foreign table"); using ok = ::sqlpp::detail::all_t< @@ -150,7 +150,7 @@ namespace sqlpp template void _add_impl(Assignment assignment, const std::true_type&) { - _data._dynamic_columns.emplace_back(simple_column_t{assignment._lhs}); + _data._dynamic_columns.emplace_back(simple_column_t{assignment._lhs}); _data._dynamic_values.emplace_back(assignment._rhs); } @@ -233,7 +233,7 @@ namespace sqlpp void add(Assignments... assignments) { static_assert(::sqlpp::detail::all_t::value...>::value, "add_values() arguments have to be assignments"); - using _arg_value_tuple = std::tuple...>; + using _arg_value_tuple = std::tuple...>; using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>; static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments"); @@ -248,7 +248,7 @@ namespace sqlpp template void _add_impl(const std::true_type&, Assignments... assignments) { - return _data._insert_values.emplace_back(insert_value_t{assignments}...); + return _data._insert_values.emplace_back(insert_value_t{assignments}...); } template @@ -359,9 +359,9 @@ namespace sqlpp { static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); static_assert(sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); - static_assert(sqlpp::detail::none_t::value...>::value, "at least one assignment is prohibited by its column definition in set()"); + static_assert(sqlpp::detail::none_t::value...>::value, "at least one assignment is prohibited by its column definition in set()"); - using _column_required_tables = typename ::sqlpp::detail::make_joined_set...>::type; + using _column_required_tables = typename ::sqlpp::detail::make_joined_set...>::type; static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from several tables"); return { *static_cast(this), insert_list_data_t{assignments...} }; diff --git a/include/sqlpp11/rhs_is_null.h b/include/sqlpp11/rhs_is_null.h index 2c1df7de..1eda20d9 100644 --- a/include/sqlpp11/rhs_is_null.h +++ b/include/sqlpp11/rhs_is_null.h @@ -58,9 +58,9 @@ namespace sqlpp template constexpr bool rhs_is_null(const Expression& e) { - return (((trivial_value_is_null_t::value or is_tvin_t::value) + return (((trivial_value_is_null_t::value or is_tvin_t::value) and is_trivial(e._rhs)) - or (std::is_same::value)); + or (std::is_same::value)); } } diff --git a/include/sqlpp11/tvin.h b/include/sqlpp11/tvin.h index 78741ef9..2e3474f2 100644 --- a/include/sqlpp11/tvin.h +++ b/include/sqlpp11/tvin.h @@ -77,70 +77,12 @@ namespace sqlpp template using is_tvin_t = typename detail::is_tvin_impl::type; - - +#warning: disallow tvin in other places which are not =, == or != template struct serializer_t> { using T = tvin_t; - static void _(const T& t, Context& context) - { - static_assert(wrong_t::value, "tvin() must not be used with anything but =, ==, != and !"); - } - }; - - template - struct maybe_tvin_t - { - using _traits = make_traits, tag::expression>; - using _recursive_traits = make_recursive_traits; - - static constexpr bool _is_trivial() - { - return false; - } - - maybe_tvin_t(Operand operand): - _value(operand) - {} - maybe_tvin_t(const maybe_tvin_t&) = default; - maybe_tvin_t(maybe_tvin_t&&) = default; - maybe_tvin_t& operator=(const maybe_tvin_t&) = default; - maybe_tvin_t& operator=(maybe_tvin_t&&) = default; - ~maybe_tvin_t() = default; - - Operand _value; - }; - - template - struct maybe_tvin_t> - { - using _traits = make_traits, tag::expression>; - using _recursive_traits = make_recursive_traits; - - bool _is_trivial() const - { - return _value._is_trivial(); - }; - - maybe_tvin_t(tvin_t operand): - _value(operand._value) - {} - maybe_tvin_t(const maybe_tvin_t&) = default; - maybe_tvin_t(maybe_tvin_t&&) = default; - maybe_tvin_t& operator=(const maybe_tvin_t&) = default; - maybe_tvin_t& operator=(maybe_tvin_t&&) = default; - ~maybe_tvin_t() = default; - - typename tvin_t::_operand_t _value; - }; - - template - struct serializer_t> - { - using T = maybe_tvin_t; - static Context& _(const T& t, Context& context) { if (t._is_trivial()) diff --git a/include/sqlpp11/update_list.h b/include/sqlpp11/update_list.h index 903bac66..df713a1a 100644 --- a/include/sqlpp11/update_list.h +++ b/include/sqlpp11/update_list.h @@ -78,9 +78,9 @@ namespace sqlpp { static_assert(_is_dynamic::value, "add must not be called for static from()"); static_assert(is_assignment_t::value, "invalid assignment argument in add()"); - using _assigned_columns = detail::make_type_set_t; - static_assert(not detail::is_element_of::value, "Must not assign value to column twice"); - static_assert(sqlpp::detail::not_t::value, "add() argument must not be updated"); + using _assigned_columns = detail::make_type_set_t; + static_assert(not detail::is_element_of::value, "Must not assign value to column twice"); + static_assert(sqlpp::detail::not_t::value, "add() argument must not be updated"); static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "assignment uses tables unknown to this statement in add()"); using ok = ::sqlpp::detail::all_t< @@ -192,9 +192,9 @@ namespace sqlpp { static_assert(not ::sqlpp::detail::has_duplicates::value, "at least one duplicate argument detected in set()"); static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an assignment in set()"); - static_assert(::sqlpp::detail::none_t::value...>::value, "at least one assignment is prohibited by its column definition in set()"); + static_assert(::sqlpp::detail::none_t::value...>::value, "at least one assignment is prohibited by its column definition in set()"); - using _column_required_tables = typename ::sqlpp::detail::make_joined_set...>::type; + using _column_required_tables = typename ::sqlpp::detail::make_joined_set...>::type; static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from more than one table"); return { *static_cast(this), update_list_data_t{assignments...} };