mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Unified tvin/trivial_value_is_null usage for =,==,!= and !
This commit is contained in:
parent
3506182ccf
commit
0f29e255d1
@ -43,12 +43,12 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
|
||||
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<typename Context, typename Lhs, typename Rhs>
|
||||
@ -70,7 +70,7 @@ namespace sqlpp
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (((trivial_value_is_null_t<typename T::_column_t>::value or is_tvin_t<typename T::_value_t>::value)
|
||||
if (((trivial_value_is_null_t<typename T::_lhs_t>::value or is_tvin_t<typename T::_rhs_t>::value)
|
||||
and is_trivial(t._rhs))
|
||||
or (std::is_same<Rhs, null_t>::value))
|
||||
{
|
||||
@ -87,52 +87,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t<Lhs, tvin_t<Rhs>>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
|
||||
using _column_t = Lhs;
|
||||
using _value_t = tvin_t<Rhs>;
|
||||
|
||||
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<typename Context, typename Lhs, typename Rhs>
|
||||
struct serializer_t<Context, assignment_t<Lhs, tvin_t<Rhs>>>
|
||||
{
|
||||
using T = assignment_t<Lhs, tvin_t<Rhs>>;
|
||||
|
||||
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
|
||||
|
@ -43,8 +43,10 @@ namespace sqlpp
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
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> _rhs;
|
||||
_lhs_t _lhs;
|
||||
_rhs_t _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -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<boolean, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
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> _rhs;
|
||||
_lhs_t _lhs;
|
||||
_rhs_t _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
@ -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 ";
|
||||
if (trivial_value_is_null_t<Rhs>::value)
|
||||
{
|
||||
serialize(t._lhs, context);
|
||||
context << " IS NULL ";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "NOT ";
|
||||
serialize(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -97,8 +97,8 @@ namespace sqlpp
|
||||
~insert_list_data_t() = default;
|
||||
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::_value_t...> _values;
|
||||
std::tuple<simple_column_t<typename Assignments::_lhs_t>...> _columns;
|
||||
std::tuple<typename Assignments::_rhs_t...> _values;
|
||||
interpretable_list_t<Database> _dynamic_columns;
|
||||
interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
@ -107,7 +107,7 @@ namespace sqlpp
|
||||
struct insert_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::insert_list>;
|
||||
using _recursive_traits = make_recursive_traits<typename Assignments::_column_t..., typename Assignments::_value_t...>;
|
||||
using _recursive_traits = make_recursive_traits<typename Assignments::_lhs_t..., typename Assignments::_rhs_t...>;
|
||||
|
||||
using _is_dynamic = is_database<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<Assignment>::value, "add() arguments require to be assigments");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_column_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_column_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_column_t>::value, "add() argument must not be used in insert");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_lhs_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_lhs_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_lhs_t>::value, "add() argument must not be used in insert");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add() contains a column from a foreign table");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
@ -150,7 +150,7 @@ namespace sqlpp
|
||||
template<typename Assignment>
|
||||
void _add_impl(Assignment assignment, const std::true_type&)
|
||||
{
|
||||
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_lhs_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<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
||||
using _arg_value_tuple = std::tuple<insert_value_t<typename Assignments::_column_t>...>;
|
||||
using _arg_value_tuple = std::tuple<insert_value_t<typename Assignments::_lhs_t>...>;
|
||||
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<typename... Assignments>
|
||||
void _add_impl(const std::true_type&, Assignments... assignments)
|
||||
{
|
||||
return _data._insert_values.emplace_back(insert_value_t<typename Assignments::_column_t>{assignments}...);
|
||||
return _data._insert_values.emplace_back(insert_value_t<typename Assignments::_lhs_t>{assignments}...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
@ -359,9 +359,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
static_assert(sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_lhs_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<required_tables_of<typename Assignments::_column_t>...>::type;
|
||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<required_tables_of<typename Assignments::_lhs_t>...>::type;
|
||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for columns from several tables");
|
||||
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<Database, Assignments...>{assignments...} };
|
||||
|
@ -58,9 +58,9 @@ namespace sqlpp
|
||||
template<typename Expression>
|
||||
constexpr bool rhs_is_null(const Expression& e)
|
||||
{
|
||||
return (((trivial_value_is_null_t<typename Expression::_column_t>::value or is_tvin_t<typename Expression::_value_t>::value)
|
||||
return (((trivial_value_is_null_t<typename Expression::_lhs_t>::value or is_tvin_t<typename Expression::_rhs_t>::value)
|
||||
and is_trivial(e._rhs))
|
||||
or (std::is_same<typename Expression::_value_t, null_t>::value));
|
||||
or (std::is_same<typename Expression::_rhs_t, null_t>::value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,70 +77,12 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
using is_tvin_t = typename detail::is_tvin_impl<T>::type;
|
||||
|
||||
|
||||
|
||||
#warning: disallow tvin in other places which are not =, == or !=
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, tvin_t<Operand>>
|
||||
{
|
||||
using T = tvin_t<Operand>;
|
||||
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "tvin() must not be used with anything but =, ==, != and !");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Operand>
|
||||
struct maybe_tvin_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
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<typename Operand>
|
||||
struct maybe_tvin_t<tvin_t<Operand>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _value._is_trivial();
|
||||
};
|
||||
|
||||
maybe_tvin_t(tvin_t<Operand> 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>::_operand_t _value;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand>
|
||||
struct serializer_t<Context, maybe_tvin_t<Operand>>
|
||||
{
|
||||
using T = maybe_tvin_t<Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._is_trivial())
|
||||
|
@ -78,9 +78,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_column_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_column_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add() argument must not be updated");
|
||||
using _assigned_columns = detail::make_type_set_t<typename Assignments::_lhs_t...>;
|
||||
static_assert(not detail::is_element_of<typename Assignment::_lhs_t, _assigned_columns>::value, "Must not assign value to column twice");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_lhs_t>::value, "add() argument must not be updated");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::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<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_lhs_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<required_tables_of<typename Assignments::_column_t>...>::type;
|
||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<required_tables_of<typename Assignments::_lhs_t>...>::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<typename Policies::_statement_t*>(this), update_list_data_t<Database, Assignments...>{assignments...} };
|
||||
|
Loading…
Reference in New Issue
Block a user