mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
(Only) allow comparison with ANY and introduce BETWEEN
This commit is contained in:
parent
937dd31a13
commit
25200ba4cb
@ -26,11 +26,17 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <sqlpp11/char_sequence.h>
|
#include <sqlpp11/char_sequence.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
struct name_tag
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#define SQLPP_ALIAS_PROVIDER(name) \
|
#define SQLPP_ALIAS_PROVIDER(name) \
|
||||||
struct name##_t \
|
struct name##_t : public sqlpp::name_tag \
|
||||||
{ \
|
{ \
|
||||||
struct _alias_t \
|
struct _alias_t \
|
||||||
{ \
|
{ \
|
||||||
@ -54,7 +60,7 @@
|
|||||||
constexpr name##_t name = {};
|
constexpr name##_t name = {};
|
||||||
|
|
||||||
#define SQLPP_QUOTED_ALIAS_PROVIDER(name) \
|
#define SQLPP_QUOTED_ALIAS_PROVIDER(name) \
|
||||||
struct name##_t \
|
struct name##_t : public sqlpp::name_tag \
|
||||||
{ \
|
{ \
|
||||||
struct _alias_t \
|
struct _alias_t \
|
||||||
{ \
|
{ \
|
||||||
@ -79,20 +85,6 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template <typename T, typename Enable = void>
|
|
||||||
struct is_alias_provider_t
|
|
||||||
{
|
|
||||||
static constexpr bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct is_alias_provider_t<
|
|
||||||
T,
|
|
||||||
typename std::enable_if<std::is_class<typename T::_alias_t::template _member_t<int>>::value, void>::type>
|
|
||||||
{
|
|
||||||
static constexpr bool value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace alias
|
namespace alias
|
||||||
{
|
{
|
||||||
SQLPP_ALIAS_PROVIDER(a)
|
SQLPP_ALIAS_PROVIDER(a)
|
||||||
|
@ -71,6 +71,7 @@ namespace sqlpp
|
|||||||
return _table{};
|
return _table{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#warning: Let's do if_(condition, expression) -> if_t<Expression>, which can be used exclusively in SELECT, AND, OR, JOIN
|
||||||
sqlpp::compat::optional<column_t> if_(bool condition) const
|
sqlpp::compat::optional<column_t> if_(bool condition) const
|
||||||
{
|
{
|
||||||
return condition ? sqlpp::compat::make_optional(*this) : sqlpp::compat::nullopt;
|
return condition ? sqlpp::compat::make_optional(*this) : sqlpp::compat::nullopt;
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
#include <sqlpp11/case.h>
|
#include <sqlpp11/case.h>
|
||||||
#include <sqlpp11/lower.h>
|
#include <sqlpp11/lower.h>
|
||||||
#include <sqlpp11/upper.h>
|
#include <sqlpp11/upper.h>
|
||||||
#include <sqlpp11/any.h>
|
|
||||||
#include <sqlpp11/some.h>
|
|
||||||
#include <sqlpp11/value_type.h>
|
#include <sqlpp11/value_type.h>
|
||||||
#include <sqlpp11/verbatim.h> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
#include <sqlpp11/verbatim.h> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||||
#include <sqlpp11/parameterized_verbatim.h>
|
#include <sqlpp11/parameterized_verbatim.h>
|
||||||
|
@ -36,8 +36,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <sqlpp11/operator/logical_expression.h>
|
#include <sqlpp11/operator/logical_expression.h>
|
||||||
|
|
||||||
// comparison
|
// comparison
|
||||||
|
#include <sqlpp11/operator/any.h>
|
||||||
#include <sqlpp11/operator/comparison_expression.h>
|
#include <sqlpp11/operator/comparison_expression.h>
|
||||||
#include <sqlpp11/operator/in_expression.h>
|
#include <sqlpp11/operator/in_expression.h>
|
||||||
|
#include <sqlpp11/operator/between_expression.h>
|
||||||
|
|
||||||
// arithmetic
|
// arithmetic
|
||||||
#include <sqlpp11/operator/arithmetic_expression.h>
|
#include <sqlpp11/operator/arithmetic_expression.h>
|
||||||
|
@ -51,11 +51,23 @@ namespace sqlpp
|
|||||||
Select _select;
|
Select _select;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Select>
|
// No value_type_of defined for any_t, because it is to be used with basic comparison operators, only.
|
||||||
struct value_type_of<any_t<Select>> : value_type_of<Select>
|
|
||||||
|
template <typename T>
|
||||||
|
struct remove_any
|
||||||
{
|
{
|
||||||
|
using type = T;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Select>
|
||||||
|
struct remove_any<any_t<Select>>
|
||||||
|
{
|
||||||
|
using type = Select;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using remove_any_t = typename remove_any<T>::type;
|
||||||
|
|
||||||
template <typename Context, typename Select>
|
template <typename Context, typename Select>
|
||||||
Context& serialize(const any_t<Select>& t, Context& context)
|
Context& serialize(const any_t<Select>& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -64,9 +76,8 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning: Need tests
|
|
||||||
template <typename Select>
|
template <typename Select>
|
||||||
using check_any_args = std::enable_if_t<is_statement_t<Select>::value and has_value_type<Select>::value>;
|
using check_any_args = std::enable_if_t<has_value_type<Select>::value>;
|
||||||
|
|
||||||
template <typename ...Policies, typename = check_any_args<statement_t<Policies...>>>
|
template <typename ...Policies, typename = check_any_args<statement_t<Policies...>>>
|
||||||
auto any(statement_t<Policies...> t) -> any_t<statement_t<Policies...>>
|
auto any(statement_t<Policies...> t) -> any_t<statement_t<Policies...>>
|
143
include/sqlpp11/operator/between_expression.h
Normal file
143
include/sqlpp11/operator/between_expression.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2024, Roland Bock
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/logic.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename L, typename R1, typename R2>
|
||||||
|
struct between_expression
|
||||||
|
{
|
||||||
|
L l;
|
||||||
|
R1 r1;
|
||||||
|
R2 r2;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename L, typename R1, typename R2>
|
||||||
|
using check_between_args =
|
||||||
|
std::enable_if_t<values_are_comparable<L, R1>::value and values_are_comparable<L, R2>::value>;
|
||||||
|
|
||||||
|
template <typename L, typename R1, typename R2>
|
||||||
|
struct value_type_of<between_expression<L, R1, R2>>
|
||||||
|
: public std::conditional<sqlpp::is_optional<value_type_of_t<L>>::value or
|
||||||
|
sqlpp::is_optional<value_type_of_t<R1>>::value or
|
||||||
|
sqlpp::is_optional<value_type_of_t<R2>>::value,
|
||||||
|
sqlpp::compat::optional<boolean>,
|
||||||
|
boolean>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
template <typename L, typename... Args>
|
||||||
|
struct nodes_of<between_t<L, Args...>>
|
||||||
|
{
|
||||||
|
using type = type_vector<L, Args...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename L, typename... Args>
|
||||||
|
constexpr auto in(L l, Args... args)
|
||||||
|
-> std::enable_if_t<((sizeof...(Args) > 0) and ... and values_are_compatible_v<L, Args>), between_t<L, Args...>>
|
||||||
|
{
|
||||||
|
return between_t<L, Args...>{l, std::tuple{args...}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename L, typename... Args>
|
||||||
|
constexpr auto requires_braces_v<between_t<L, Args...>> = true;
|
||||||
|
|
||||||
|
template <typename Context, typename L, typename... Args>
|
||||||
|
[[nodiscard]] auto to_sql_string(Context& context, const between_t<L, Args...>& t)
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(Args) == 1)
|
||||||
|
{
|
||||||
|
return to_sql_string(context, embrace(t.l)) + " IN(" + to_sql_string(context, std::get<0>(t.args)) + ")";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return to_sql_string(context, embrace(t.l)) + " IN(" + tuple_to_sql_string(context, ", ", t.args) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#warning: Need tests for between expressions
|
||||||
|
template <typename L, typename R1, typename R2, typename = check_between_args<L, R1, R2>>
|
||||||
|
constexpr auto between(L l, R1 r1, R2 r2) -> between_expression<L, R1, R2>
|
||||||
|
{
|
||||||
|
return {std::move(l), std::move(r1), std::move(r2)};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // original serialize implementation
|
||||||
|
template <typename Context, typename Operand, typename Arg, typename... Args>
|
||||||
|
Context& serialize(const between_t<Operand, Arg, Args...>& t, Context& context)
|
||||||
|
{
|
||||||
|
serialize(t._operand, context);
|
||||||
|
context << " IN(";
|
||||||
|
if (sizeof...(Args) == 0)
|
||||||
|
{
|
||||||
|
serialize(std::get<0>(t._args), context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
interpret_tuple(t._args, ',', context);
|
||||||
|
}
|
||||||
|
context << ')';
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Context, typename Operand>
|
||||||
|
Context& serialize(const between_t<Operand>&, Context& context)
|
||||||
|
{
|
||||||
|
serialize(boolean_operand{false}, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
struct value_list_t;
|
||||||
|
|
||||||
|
template <typename Context, typename Operand, typename Container>
|
||||||
|
Context& serialize(const between_t<Operand, value_list_t<Container>>& t, Context& context)
|
||||||
|
{
|
||||||
|
const auto& value_list = std::get<0>(t._args);
|
||||||
|
if (value_list._container.empty())
|
||||||
|
{
|
||||||
|
serialize(boolean_operand{false}, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serialize(t._operand, context);
|
||||||
|
context << " IN(";
|
||||||
|
serialize(value_list, context);
|
||||||
|
context << ')';
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace sqlpp
|
@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <sqlpp11/operator/any.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -44,7 +45,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
template <typename L, typename Operator, typename R>
|
template <typename L, typename Operator, typename R>
|
||||||
struct value_type_of<comparison_expression<L, Operator, R>>
|
struct value_type_of<comparison_expression<L, Operator, R>>
|
||||||
: std::conditional<sqlpp::is_optional<value_type_of_t<L>>::value or sqlpp::is_optional<value_type_of_t<R>>::value,
|
: std::conditional<sqlpp::is_optional<value_type_of_t<L>>::value or sqlpp::is_optional<value_type_of_t<remove_any_t<R>>>::value,
|
||||||
sqlpp::compat::optional<boolean>,
|
sqlpp::compat::optional<boolean>,
|
||||||
boolean>
|
boolean>
|
||||||
{
|
{
|
||||||
@ -113,7 +114,9 @@ namespace sqlpp
|
|||||||
static constexpr auto symbol = " < ";
|
static constexpr auto symbol = " < ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R, typename = check_comparison_args<L, R>>
|
// We are using remove_any_t in the basic comparison operators to allow comparison with ANY-expressions.
|
||||||
|
// Note: any_t does not have a specialization for value_type_of to disallow it from being used in other contexts.
|
||||||
|
template <typename L, typename R, typename = check_comparison_args<L, remove_any_t<R>>>
|
||||||
constexpr auto operator<(L l, R r) -> comparison_expression<L, less, R>
|
constexpr auto operator<(L l, R r) -> comparison_expression<L, less, R>
|
||||||
{
|
{
|
||||||
return {std::move(l), std::move(r)};
|
return {std::move(l), std::move(r)};
|
||||||
@ -124,7 +127,7 @@ namespace sqlpp
|
|||||||
static constexpr auto symbol = " <= ";
|
static constexpr auto symbol = " <= ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R, typename = check_comparison_args<L, R>>
|
template <typename L, typename R, typename = check_comparison_args<L, remove_any_t<R>>>
|
||||||
constexpr auto operator<=(L l, R r) -> comparison_expression<L, less_equal, R>
|
constexpr auto operator<=(L l, R r) -> comparison_expression<L, less_equal, R>
|
||||||
{
|
{
|
||||||
return {std::move(l), std::move(r)};
|
return {std::move(l), std::move(r)};
|
||||||
@ -135,7 +138,7 @@ namespace sqlpp
|
|||||||
static constexpr auto symbol = " = ";
|
static constexpr auto symbol = " = ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R, typename = check_comparison_args<L, R>>
|
template <typename L, typename R, typename = check_comparison_args<L, remove_any_t<R>>>
|
||||||
constexpr auto operator==(L l, R r) -> comparison_expression<L, equal_to, R>
|
constexpr auto operator==(L l, R r) -> comparison_expression<L, equal_to, R>
|
||||||
{
|
{
|
||||||
return {l, r};
|
return {l, r};
|
||||||
@ -146,7 +149,7 @@ namespace sqlpp
|
|||||||
static constexpr auto symbol = " != ";
|
static constexpr auto symbol = " != ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R, typename = check_comparison_args<L, R>>
|
template <typename L, typename R, typename = check_comparison_args<L, remove_any_t<R>>>
|
||||||
constexpr auto operator!=(L l, R r) -> comparison_expression<L, not_equal_to, R>
|
constexpr auto operator!=(L l, R r) -> comparison_expression<L, not_equal_to, R>
|
||||||
{
|
{
|
||||||
return {std::move(l), std::move(r)};
|
return {std::move(l), std::move(r)};
|
||||||
@ -157,7 +160,7 @@ namespace sqlpp
|
|||||||
static constexpr auto symbol = " >= ";
|
static constexpr auto symbol = " >= ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R, typename = check_comparison_args<L, R>>
|
template <typename L, typename R, typename = check_comparison_args<L, remove_any_t<R>>>
|
||||||
constexpr auto operator>=(L l, R r) -> comparison_expression<L, greater_equal, R>
|
constexpr auto operator>=(L l, R r) -> comparison_expression<L, greater_equal, R>
|
||||||
{
|
{
|
||||||
return {std::move(l), std::move(r)};
|
return {std::move(l), std::move(r)};
|
||||||
@ -168,7 +171,7 @@ namespace sqlpp
|
|||||||
static constexpr auto symbol = " > ";
|
static constexpr auto symbol = " > ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R, typename = check_comparison_args<L, R>>
|
template <typename L, typename R, typename = check_comparison_args<L, remove_any_t<R>>>
|
||||||
constexpr auto operator>(L l, R r) -> comparison_expression<L, greater, R>
|
constexpr auto operator>(L l, R r) -> comparison_expression<L, greater, R>
|
||||||
{
|
{
|
||||||
return {std::move(l), std::move(r)};
|
return {std::move(l), std::move(r)};
|
||||||
|
@ -73,7 +73,7 @@ namespace sqlpp
|
|||||||
-> parameter_t<ValueType, AliasProvider>
|
-> parameter_t<ValueType, AliasProvider>
|
||||||
{
|
{
|
||||||
static_assert(is_value_type_t<ValueType>::value, "first argument is not a value type");
|
static_assert(is_value_type_t<ValueType>::value, "first argument is not a value type");
|
||||||
static_assert(is_alias_provider_t<AliasProvider>::value, "second argument is not an alias provider");
|
static_assert(has_name<AliasProvider>::value, "second argument does not have a name");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
} // namespace sqlpp
|
} // namespace sqlpp
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2015, Roland Bock
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
* other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sqlpp11/statement_fwd.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
#include <sqlpp11/char_sequence.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
template <typename Select>
|
|
||||||
struct some_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<value_type_of_t<Select>, tag::is_multi_expression>;
|
|
||||||
using _nodes = detail::type_vector<Select>;
|
|
||||||
|
|
||||||
some_t(Select select) : _select(select)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
some_t(const some_t&) = default;
|
|
||||||
some_t(some_t&&) = default;
|
|
||||||
some_t& operator=(const some_t&) = default;
|
|
||||||
some_t& operator=(some_t&&) = default;
|
|
||||||
~some_t() = default;
|
|
||||||
|
|
||||||
Select _select;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Select>
|
|
||||||
struct value_type_of<some_t<Select>> : value_type_of<Select>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Context, typename Select>
|
|
||||||
Context& serialize(const some_t<Select>& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "SOME";
|
|
||||||
serialize_operand(t._select, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
#warning : Need tests
|
|
||||||
template <typename Select>
|
|
||||||
using check_some_args = std::enable_if_t<has_value_type<Select>::value>;
|
|
||||||
|
|
||||||
template <typename ... Policies, typename = check_some_args<statement_t<Policies...>>>
|
|
||||||
auto some(statement_t<Policies...> t) -> some_t<statement_t<Policies...>>
|
|
||||||
{
|
|
||||||
return {std::move(t)};
|
|
||||||
}
|
|
||||||
} // namespace sqlpp
|
|
@ -420,7 +420,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_sql_null)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_sql_null)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_value_type)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_value_type)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value)
|
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_selectable)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_selectable)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_expression)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_expression)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression)
|
||||||
@ -481,9 +480,6 @@ namespace sqlpp
|
|||||||
using is_database =
|
using is_database =
|
||||||
typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using cpp_value_type_of_t = typename value_type_of_t<T>::_cpp_value_type;
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T, typename HasNodes = void>
|
template <typename T, typename HasNodes = void>
|
||||||
@ -666,14 +662,15 @@ namespace sqlpp
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
using parameters_of = typename detail::parameters_of_impl<T>::type;
|
using parameters_of = typename detail::parameters_of_impl<T>::type;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using alias_of = typename T::_alias_t;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using name_of = typename T::_alias_t::_name_t;
|
using name_of = typename T::_alias_t::_name_t;
|
||||||
|
|
||||||
|
// Used by SQLPP_ALIAS_PROVIDER.
|
||||||
|
struct name_tag;
|
||||||
|
|
||||||
|
// Override this for other classes like columns or tables.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct has_name : public std::false_type {};
|
struct has_name : public std::integral_constant<bool, std::is_base_of<name_tag, T>::value> {};
|
||||||
|
|
||||||
template <typename ValueType, typename... Tags>
|
template <typename ValueType, typename... Tags>
|
||||||
struct make_traits
|
struct make_traits
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sqlpp11/operator/as_expression.h>
|
||||||
#include <sqlpp11/expression_operators.h>
|
#include <sqlpp11/expression_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ function(test_compile name)
|
|||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
test_compile(any)
|
||||||
test_compile(aggregate_functions)
|
test_compile(aggregate_functions)
|
||||||
test_compile(comparison_expression)
|
test_compile(comparison_expression)
|
||||||
test_compile(in_expression)
|
test_compile(in_expression)
|
||||||
|
96
tests/core/types/any.cpp
Normal file
96
tests/core/types/any.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2016, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sqlpp11/sqlpp11.h>
|
||||||
|
|
||||||
|
SQLPP_ALIAS_PROVIDER(r_not_null);
|
||||||
|
SQLPP_ALIAS_PROVIDER(r_maybe_null);
|
||||||
|
|
||||||
|
template <typename Value>
|
||||||
|
void test_any(Value v)
|
||||||
|
{
|
||||||
|
using ValueType = sqlpp::value_type_of_t<Value>;
|
||||||
|
using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>;
|
||||||
|
|
||||||
|
// Selectable values.
|
||||||
|
auto v_not_null = sqlpp::value(v).as(r_not_null);
|
||||||
|
const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null);
|
||||||
|
|
||||||
|
// ANY expression are not to be in most expressions and therefore have no value defined.
|
||||||
|
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(any(select(v_not_null)))>, sqlpp::no_value_t>::value, "");
|
||||||
|
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(any(select(v_maybe_null)))>, sqlpp::no_value_t>::value,
|
||||||
|
"");
|
||||||
|
|
||||||
|
// ANY expression can be used in basic comparison expressions, which use remove_any_t to look inside.
|
||||||
|
static_assert(
|
||||||
|
std::is_same<sqlpp::value_type_of_t<sqlpp::remove_any_t<decltype(any(select(v_not_null)))>>, ValueType>::value,
|
||||||
|
"");
|
||||||
|
static_assert(std::is_same<sqlpp::value_type_of_t<sqlpp::remove_any_t<decltype(any(select(v_maybe_null)))>>,
|
||||||
|
OptValueType>::value,
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// boolean
|
||||||
|
test_any(bool{true});
|
||||||
|
|
||||||
|
// integral
|
||||||
|
test_any(int8_t{7});
|
||||||
|
test_any(int16_t{7});
|
||||||
|
test_any(int32_t{7});
|
||||||
|
test_any(int64_t{7});
|
||||||
|
|
||||||
|
// unsigned integral
|
||||||
|
test_any(uint8_t{7});
|
||||||
|
test_any(uint16_t{7});
|
||||||
|
test_any(uint32_t{7});
|
||||||
|
test_any(uint64_t{7});
|
||||||
|
|
||||||
|
// floating point
|
||||||
|
test_any(float{7.7});
|
||||||
|
test_any(double{7.7});
|
||||||
|
|
||||||
|
// text
|
||||||
|
test_any('7');
|
||||||
|
test_any("seven");
|
||||||
|
test_any(std::string("seven"));
|
||||||
|
test_any(sqlpp::compat::string_view("seven"));
|
||||||
|
|
||||||
|
// blob
|
||||||
|
test_any(std::vector<uint8_t>{});
|
||||||
|
|
||||||
|
// date
|
||||||
|
test_any(::sqlpp::chrono::day_point{});
|
||||||
|
|
||||||
|
// timestamp
|
||||||
|
test_any(::sqlpp::chrono::microsecond_point{});
|
||||||
|
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||||
|
test_any(minute_point{});
|
||||||
|
|
||||||
|
// time_of_day
|
||||||
|
test_any(std::chrono::microseconds{});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user