mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Added static assert to prevent automatic rivial->null conversion to happen in where/having
This commit is contained in:
parent
409fa3baac
commit
51e0db883f
@ -41,11 +41,15 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_having = std::true_type;
|
using _is_having = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
|
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
|
||||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
|
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
|
||||||
|
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||||
|
static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of having expression, use where_parameter() instead of parameter() to turn off automatic conversion");
|
||||||
|
|
||||||
template<typename E>
|
template<typename E>
|
||||||
void add(E&& expr)
|
void add(E&& expr)
|
||||||
{
|
{
|
||||||
@ -70,8 +74,7 @@ namespace sqlpp
|
|||||||
return set_parameter_index(_expressions, index);
|
return set_parameter_index(_expressions, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
_parameter_tuple_t _expressions;
|
||||||
_parameter_tuple_t _expressions; // FIXME: Do we need those?
|
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ namespace sqlpp
|
|||||||
using _is_parameter = std::true_type;
|
using _is_parameter = std::true_type;
|
||||||
using _is_expression_t = std::true_type;
|
using _is_expression_t = std::true_type;
|
||||||
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
|
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
|
||||||
using _trivial_value_is_null = TrivialValueIsNull;
|
using _trivial_value_is_null_t = 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");
|
static_assert(std::is_same<_trivial_value_is_null_t, std::true_type>::value or std::is_same<_trivial_value_is_null_t, std::false_type>::value, "Invalid template parameter TrivialValueIsNull");
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
@ -70,6 +70,13 @@ namespace sqlpp
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename NamedExpr>
|
||||||
|
auto where_parameter(NamedExpr&& namedExpr)
|
||||||
|
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, std::false_type>
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +32,25 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename... T>
|
||||||
|
struct or_t;
|
||||||
|
|
||||||
|
template<typename T, typename... Rest>
|
||||||
|
struct or_t<T, Rest...>
|
||||||
|
{
|
||||||
|
static constexpr bool value = T::value or or_t<Rest...>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct or_t<>
|
||||||
|
{
|
||||||
|
static constexpr bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct parameter_list_t
|
struct parameter_list_t
|
||||||
{
|
{
|
||||||
@ -43,9 +62,10 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
||||||
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
||||||
|
using _contains_trivial_value_is_null_t = detail::or_t<typename Parameter::_trivial_value_is_null_t...>;
|
||||||
|
|
||||||
parameter_list_t():
|
parameter_list_t():
|
||||||
Parameter::_instance_t({typename Parameter::_trivial_value_is_null()})...
|
Parameter::_instance_t({typename Parameter::_trivial_value_is_null_t()})...
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename Target>
|
template<typename Target>
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/detail/serialize_tuple.h>
|
||||||
#include <sqlpp11/detail/serializable_list.h>
|
#include <sqlpp11/detail/serializable_list.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -42,11 +43,15 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_where = std::true_type;
|
using _is_where = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
|
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
|
||||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
|
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
|
||||||
|
|
||||||
|
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||||
|
static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of where expression, use where_parameter() instead of parameter() to turn off automatic conversion");
|
||||||
|
|
||||||
template<typename E>
|
template<typename E>
|
||||||
void add(E&& expr)
|
void add(E&& expr)
|
||||||
{
|
{
|
||||||
@ -69,8 +74,7 @@ namespace sqlpp
|
|||||||
return set_parameter_index(_expressions, index);
|
return set_parameter_index(_expressions, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
_parameter_tuple_t _expressions;
|
||||||
_parameter_tuple_t _expressions; // FIXME: Do we need those?
|
|
||||||
detail::serializable_list<Database> _dynamic_expressions;
|
detail::serializable_list<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ int main()
|
|||||||
|
|
||||||
// Wonderful, now take a look at the parameter list of a select
|
// Wonderful, now take a look at the parameter list of a select
|
||||||
{
|
{
|
||||||
auto s = 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));
|
auto s = select(all_of(t)).from(t).where(t.beta.like(where_parameter(t.beta)) and t.alpha == where_parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||||
using S = decltype(s);
|
using S = decltype(s);
|
||||||
using T = sqlpp::make_parameter_list_t<S>::type;
|
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||||
T npl;
|
T npl;
|
||||||
|
Loading…
Reference in New Issue
Block a user