mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Added more tests and cleaned up type traits a bit
This commit is contained in:
parent
c2c5f15690
commit
87f4c348e9
@ -34,32 +34,8 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct count_alias_t
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "count_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T count;
|
||||
T& operator()()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct count_t : public expression_operators<count_t<Flag, Expr>, integral>,
|
||||
public aggregate_function_operators<count_t<Flag, Expr>>,
|
||||
public alias_operators<count_t<Flag, Expr>>
|
||||
struct count_t
|
||||
{
|
||||
using _traits = make_traits<integral, tag::is_expression /*, tag::is_selectable*/>;
|
||||
|
||||
@ -67,11 +43,6 @@ namespace sqlpp
|
||||
using _can_be_null = std::false_type;
|
||||
using _is_aggregate_expression = std::true_type;
|
||||
|
||||
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value,
|
||||
"count() used with flag other than 'distinct'");
|
||||
|
||||
using _auto_alias_t = count_alias_t;
|
||||
|
||||
count_t(const Expr expr) : _expr(expr)
|
||||
{
|
||||
}
|
||||
@ -85,6 +56,12 @@ namespace sqlpp
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct value_type_of<count_t<Flag, Expr>>
|
||||
{
|
||||
using type = integral;
|
||||
};
|
||||
|
||||
template <typename Context, typename Flag, typename Expr>
|
||||
Context& serialize(const count_t<Flag, Expr>& t, Context& context)
|
||||
{
|
||||
@ -100,20 +77,19 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto count(T t) -> count_t<noop, wrap_operand_t<T>>
|
||||
using check_count_arg =
|
||||
std::enable_if_t<values_are_comparable<T, T>::value and not contains_aggregate_function_t<T>::value>;
|
||||
|
||||
template <typename T, typename = check_count_arg<T>>
|
||||
auto count(T t) -> count_t<noop, T>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
|
||||
"count() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
||||
return {t};
|
||||
return {std::move(t)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto count(const distinct_t& /*unused*/, T t) -> count_t<distinct_t, wrap_operand_t<T>>
|
||||
template <typename T, typename = check_count_arg<T>>
|
||||
auto count(const distinct_t& /*unused*/, T t) -> count_t<distinct_t, T>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
|
||||
"count() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
||||
return {t};
|
||||
return {std::move(t)};
|
||||
}
|
||||
|
||||
} // namespace sqlpp
|
||||
|
@ -31,40 +31,14 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct min_alias_t
|
||||
{
|
||||
struct _alias_t
|
||||
{
|
||||
static constexpr const char _literal[] = "min_";
|
||||
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
|
||||
template <typename T>
|
||||
struct _member_t
|
||||
{
|
||||
T min;
|
||||
T& operator()()
|
||||
{
|
||||
return min;
|
||||
}
|
||||
const T& operator()() const
|
||||
{
|
||||
return min;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct min_t : public expression_operators<min_t<Flag, Expr>, value_type_of_t<Expr>>,
|
||||
public aggregate_function_operators<min_t<Flag, Expr>>,
|
||||
public alias_operators<min_t<Flag, Expr>>
|
||||
struct min_t
|
||||
{
|
||||
using _traits = make_traits<value_type_of_t<Expr>, tag::is_expression, tag::is_selectable>;
|
||||
using _nodes = detail::type_vector<Expr, aggregate_function>;
|
||||
using _can_be_null = std::true_type;
|
||||
using _is_aggregate_expression = std::true_type;
|
||||
|
||||
using _auto_alias_t = min_alias_t;
|
||||
|
||||
min_t(Expr expr) : _expr(expr)
|
||||
{
|
||||
}
|
||||
@ -78,6 +52,12 @@ namespace sqlpp
|
||||
Expr _expr;
|
||||
};
|
||||
|
||||
template <typename Flag, typename Expr>
|
||||
struct value_type_of<min_t<Flag, Expr>>
|
||||
{
|
||||
using type = sqlpp::force_optional_t<value_type_of_t<Expr>>;
|
||||
};
|
||||
|
||||
template <typename Context, typename Flag, typename Expr>
|
||||
Context& serialize(const min_t<Flag, Expr>& t, Context& context)
|
||||
{
|
||||
@ -93,20 +73,18 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto min(T t) -> min_t<noop, wrap_operand_t<T>>
|
||||
using check_min_arg =
|
||||
std::enable_if_t<values_are_comparable<T, T>::value and not contains_aggregate_function_t<T>::value>;
|
||||
|
||||
template <typename T, typename = check_min_arg<T>>
|
||||
auto min(T t) -> min_t<noop, T>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
|
||||
"min() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "min() requires an expression as argument");
|
||||
return {t};
|
||||
return {std::move(t)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto min(const distinct_t& /*unused*/, T t) -> min_t<distinct_t, wrap_operand_t<T>>
|
||||
template <typename T, typename = check_min_arg<T>>
|
||||
auto min(const distinct_t& /*unused*/, T t) -> min_t<distinct_t, T>
|
||||
{
|
||||
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
|
||||
"min() cannot be used on an aggregate function");
|
||||
static_assert(is_expression_t<wrap_operand_t<T>>::value, "min() requires an expression as argument");
|
||||
return {t};
|
||||
return {std::move(t)};
|
||||
}
|
||||
} // namespace sqlpp
|
||||
|
@ -66,7 +66,7 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
using check_arithmetic_args = std::enable_if_t<has_numeric_value<L>::value and has_numeric_value<R>::value>;
|
||||
using check_arithmetic_args = std::enable_if_t<is_numeric<L>::value and is_numeric<R>::value>;
|
||||
|
||||
#warning: need to document that this is on purpose (not integral, or unsigned integral, or floating_point) because it is difficult to know for the library to know what the actual result type will be (it is difficult to guess in C++ already, and it is probably different from DB vendor to vendor).
|
||||
template <typename L, typename Operator, typename R>
|
||||
|
@ -127,7 +127,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct value_type_of<sqlpp::compat::optional<T>>
|
||||
{
|
||||
using type = sqlpp::compat::optional<value_type_of_t<remove_optional_t<T>>>;
|
||||
using type = sqlpp::force_optional_t<value_type_of_t<remove_optional_t<T>>>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -232,10 +232,23 @@ namespace sqlpp
|
||||
struct is_unsigned_integral<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_floating_point : public std::is_same<remove_optional_t<value_type_of_t<T>>, floating_point>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_floating_point<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
// A generic numeric type which could be (unsigned) integral or floating point.
|
||||
struct numeric;
|
||||
template <typename T>
|
||||
struct is_numeric : public std::integral_constant<bool, is_integral<T>::value or is_unsigned_integral<T>::value or std::is_floating_point<T>::value>{};
|
||||
struct is_numeric : public std::integral_constant<bool,
|
||||
is_integral<T>::value or is_unsigned_integral<T>::value or
|
||||
is_floating_point<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_numeric<numeric> : public std::true_type{};
|
||||
@ -244,125 +257,64 @@ namespace sqlpp
|
||||
struct is_numeric<sqlpp::compat::nullopt_t> : public std::true_type{};
|
||||
|
||||
template <typename T>
|
||||
struct has_numeric_value : public std::integral_constant<bool,
|
||||
is_numeric<remove_optional_t<T>>::value or is_numeric<remove_optional_t<value_type_of_t<T>>>::value>{};
|
||||
|
||||
struct text;
|
||||
template <typename T>
|
||||
struct is_text : public std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_text<text> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_text<char> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_text<const char*> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_text<std::string> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_text<sqlpp::compat::string_view> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_text<sqlpp::compat::nullopt_t> : public std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_text_value : public std::integral_constant<bool,
|
||||
is_text<remove_optional_t<T>>::value or
|
||||
is_text<remove_optional_t<value_type_of_t<T>>>::value>{};
|
||||
|
||||
struct blob;
|
||||
template <typename T>
|
||||
struct is_blob : public std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_blob<blob> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_blob<std::vector<std::uint8_t>> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_blob<sqlpp::compat::span<std::uint8_t>> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_blob<sqlpp::compat::nullopt_t> : public std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_blob_value : public std::integral_constant<bool,
|
||||
is_blob<remove_optional_t<T>>::value or
|
||||
is_blob<remove_optional_t<value_type_of_t<T>>>::value>{};
|
||||
|
||||
struct day_point;
|
||||
template <typename T>
|
||||
struct is_day_point : public std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_day_point<day_point> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_day_point<std::chrono::time_point<std::chrono::system_clock, sqlpp::chrono::days>> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_day_point<sqlpp::compat::nullopt_t> : public std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_day_point_value : public std::integral_constant<bool,
|
||||
is_day_point<remove_optional_t<T>>::value or
|
||||
is_day_point<remove_optional_t<value_type_of_t<T>>>::value>{};
|
||||
|
||||
struct time_of_day;
|
||||
template <typename T>
|
||||
struct is_time_of_day : public std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_time_of_day<time_of_day> : public std::true_type {};
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
struct is_time_of_day<std::chrono::duration<Rep, Period>> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_time_of_day<sqlpp::compat::nullopt_t> : public std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_time_of_day_value : public std::integral_constant<bool,
|
||||
is_time_of_day<remove_optional_t<T>>::value or
|
||||
is_time_of_day<remove_optional_t<value_type_of_t<T>>>::value>{};
|
||||
|
||||
struct time_point;
|
||||
template <typename T>
|
||||
struct is_time_point : public std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_time_point<time_point> : public std::true_type {};
|
||||
|
||||
template <typename Period>
|
||||
struct is_time_point<std::chrono::time_point<std::chrono::system_clock, Period>> : public std::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_time_point<sqlpp::compat::nullopt_t> : public std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_time_point_value : public std::integral_constant<bool,
|
||||
is_time_point<remove_optional_t<T>>::value or
|
||||
is_time_point<remove_optional_t<value_type_of_t<T>>>::value>{};
|
||||
|
||||
#warning: Need to add float and unsigned traits?
|
||||
template <typename L, typename R>
|
||||
struct values_are_comparable
|
||||
: public std::integral_constant<bool,
|
||||
(has_blob_value<L>::value and has_blob_value<R>::value) or
|
||||
(is_boolean<L>::value and is_boolean<R>::value) or
|
||||
(has_day_point_value<L>::value and has_day_point_value<R>::value) or
|
||||
(has_numeric_value<L>::value and has_numeric_value<R>::value) or
|
||||
(has_text_value<L>::value and has_text_value<R>::value) or
|
||||
(has_time_of_day_value<L>::value and has_time_of_day_value<R>::value) or
|
||||
(has_time_point_value<L>::value and has_time_point_value<R>::value)>
|
||||
struct is_text : public std::is_same<remove_optional_t<value_type_of_t<T>>, text>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_text<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_blob : public std::is_same<remove_optional_t<value_type_of_t<T>>, blob>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_blob<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_day_point : public std::is_same<remove_optional_t<value_type_of_t<T>>, day_point>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_day_point<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_time_point : public std::is_same<remove_optional_t<value_type_of_t<T>>, time_point>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_time_point<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_time_of_day : public std::is_same<remove_optional_t<value_type_of_t<T>>, time_of_day>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_time_of_day<sqlpp::compat::nullopt_t> : public std::true_type {
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct values_are_comparable
|
||||
: public std::integral_constant<bool,
|
||||
(is_blob<L>::value and is_blob<R>::value) or
|
||||
(is_boolean<L>::value and is_boolean<R>::value) or
|
||||
(is_day_point<L>::value and is_day_point<R>::value) or
|
||||
(is_numeric<L>::value and is_numeric<R>::value) or
|
||||
(is_text<L>::value and is_text<R>::value) or
|
||||
(is_time_of_day<L>::value and is_time_of_day<R>::value) or
|
||||
(is_time_point<L>::value and is_time_point<R>::value)>
|
||||
{
|
||||
};
|
||||
|
||||
#warning: These something_t data type classifiers should be removed
|
||||
// data types
|
||||
struct blob;
|
||||
template <typename T>
|
||||
@ -400,7 +352,6 @@ namespace sqlpp
|
||||
using is_time_point_t = std::is_same<value_type_of_t<T>, time_point>;
|
||||
|
||||
// joined data type
|
||||
#warning: These something_t data type classifiers should be removed
|
||||
template <typename T>
|
||||
using is_numeric_t =
|
||||
logic::any_t<is_integral_t<T>::value, is_unsigned_integral_t<T>::value, is_floating_point_t<T>::value>;
|
||||
|
@ -34,4 +34,10 @@ function(test_compile name)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
test_compile(result_row)
|
||||
test_compile(aggregate_functions)
|
||||
test_compile(comparison_expression)
|
||||
test_compile(in_expression)
|
||||
test_compile(logical_expression)
|
||||
test_compile(result_row)
|
||||
test_compile(value)
|
||||
|
||||
|
100
tests/core/types/aggregate_functions.cpp
Normal file
100
tests/core/types/aggregate_functions.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
auto db = MockDb{};
|
||||
|
||||
template <typename T, typename V>
|
||||
using is_same_type = std::is_same<sqlpp::value_type_of_t<T>, V>;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_aggregate_functions(Value v)
|
||||
{
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
|
||||
using ValueType = sqlpp::value_type_of_t<Value>;
|
||||
using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>;
|
||||
|
||||
// Aggregate of non-nullable
|
||||
static_assert(is_same_type<decltype(count(v_not_null)), sqlpp::integral>::value, "");
|
||||
static_assert(is_same_type<decltype(max(v_not_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(min(v_not_null)), OptValueType>::value, "");
|
||||
|
||||
// Aggregate of nullable
|
||||
static_assert(is_same_type<decltype(count(v_not_null)), sqlpp::integral>::value, "");
|
||||
static_assert(is_same_type<decltype(max(v_maybe_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(min(v_maybe_null)), OptValueType>::value, "");
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_aggregate_functions(bool{true});
|
||||
|
||||
// integral
|
||||
test_aggregate_functions(int8_t{7});
|
||||
test_aggregate_functions(int16_t{7});
|
||||
test_aggregate_functions(int32_t{7});
|
||||
test_aggregate_functions(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_aggregate_functions(uint8_t{7});
|
||||
test_aggregate_functions(uint16_t{7});
|
||||
test_aggregate_functions(uint32_t{7});
|
||||
test_aggregate_functions(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_aggregate_functions(float{7.7});
|
||||
test_aggregate_functions(double{7.7});
|
||||
|
||||
// text
|
||||
test_aggregate_functions('7');
|
||||
test_aggregate_functions("seven");
|
||||
test_aggregate_functions(std::string("seven"));
|
||||
test_aggregate_functions(sqlpp::compat::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_aggregate_functions(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_aggregate_functions(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_aggregate_functions(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_aggregate_functions(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_aggregate_functions(std::chrono::microseconds{});
|
||||
}
|
||||
|
169
tests/core/types/comparison_expression.cpp
Normal file
169
tests/core/types/comparison_expression.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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 "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
auto db = MockDb{};
|
||||
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::compat::optional<sqlpp::boolean>>;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_comparison_expression(Value v)
|
||||
{
|
||||
using OptValue = sqlpp::compat::optional<Value>;
|
||||
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
|
||||
#warning : Should also implement like, is_null, is_distinct_from as member functions.
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(v_not_null < v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null <= v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null == v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null != v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null == v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null >= v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null > v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_not_null, v_not_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_not_null < v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null <= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null != v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null >= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null > v_maybe_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_not_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_not_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null < v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null <= v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null != v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null >= v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null > v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_maybe_null, v_not_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_maybe_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null < v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null <= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null != v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null >= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null > v_maybe_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_maybe_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_maybe_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare with null.
|
||||
static_assert(is_bool<decltype(is_null(v_not_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_null(v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_null(v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_null(v_not_null))>::value, "");
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
void test_like(Value v)
|
||||
{
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(like(v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_not_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_maybe_null))>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_comparison_expression(bool{true});
|
||||
|
||||
// integral
|
||||
test_comparison_expression(int8_t{7});
|
||||
test_comparison_expression(int16_t{7});
|
||||
test_comparison_expression(int32_t{7});
|
||||
test_comparison_expression(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_comparison_expression(uint8_t{7});
|
||||
test_comparison_expression(uint16_t{7});
|
||||
test_comparison_expression(uint32_t{7});
|
||||
test_comparison_expression(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_comparison_expression(float{7.7});
|
||||
test_comparison_expression(double{7.7});
|
||||
|
||||
// text
|
||||
test_comparison_expression('7');
|
||||
test_comparison_expression("seven");
|
||||
test_comparison_expression(std::string("seven"));
|
||||
test_comparison_expression(sqlpp::compat::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_comparison_expression(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_comparison_expression(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_comparison_expression(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_comparison_expression(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_comparison_expression(std::chrono::microseconds{});
|
||||
|
||||
// text
|
||||
test_like('7');
|
||||
test_like("seven");
|
||||
test_like(std::string("seven"));
|
||||
test_like(sqlpp::compat::string_view("seven"));
|
||||
|
||||
}
|
||||
|
136
tests/core/types/in_expression.cpp
Normal file
136
tests/core/types/in_expression.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
auto db = MockDb{};
|
||||
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::compat::optional<sqlpp::boolean>>;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_in_expression(Value v)
|
||||
{
|
||||
using OptValue = sqlpp::compat::optional<Value>;
|
||||
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
|
||||
#warning : Need to support in with select
|
||||
// in(v_not_null, select(v_not_null.as(sqlpp::alias::a)));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(in(v_not_null, std::make_tuple(v_not_null, v_not_null)))>::value, "");
|
||||
static_assert(is_bool<decltype(in(v_not_null, std::vector<Value>{}))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(in(v_not_null, std::make_tuple(v_not_null, v_maybe_null)))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_not_null, std::vector<OptValue>{}))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::make_tuple(v_not_null, v_not_null)))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::vector<Value>{}))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::make_tuple(v_not_null, v_maybe_null)))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
void test_like(Value v)
|
||||
{
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(like(v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_not_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_maybe_null))>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_in_expression(bool{true});
|
||||
|
||||
// integral
|
||||
test_in_expression(int8_t{7});
|
||||
test_in_expression(int16_t{7});
|
||||
test_in_expression(int32_t{7});
|
||||
test_in_expression(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_in_expression(uint8_t{7});
|
||||
test_in_expression(uint16_t{7});
|
||||
test_in_expression(uint32_t{7});
|
||||
test_in_expression(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_in_expression(float{7.7});
|
||||
test_in_expression(double{7.7});
|
||||
|
||||
// text
|
||||
test_in_expression('7');
|
||||
test_in_expression("seven");
|
||||
test_in_expression(std::string("seven"));
|
||||
test_in_expression(sqlpp::compat::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_in_expression(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_in_expression(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_in_expression(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_in_expression(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_in_expression(std::chrono::microseconds{});
|
||||
|
||||
// text
|
||||
test_like('7');
|
||||
test_like("seven");
|
||||
test_like(std::string("seven"));
|
||||
test_like(sqlpp::compat::string_view("seven"));
|
||||
|
||||
}
|
||||
|
73
tests/core/types/logical_expression.cpp
Normal file
73
tests/core/types/logical_expression.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
auto db = MockDb{};
|
||||
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::compat::optional<sqlpp::boolean>>;
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
void test_logical_expression(Value v)
|
||||
{
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(v_not_null and v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null or v_not_null)>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null and v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null or v_not_null)>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_not_null and v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null or v_maybe_null)>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null and v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null or v_maybe_null)>::value, "");
|
||||
|
||||
// not.
|
||||
static_assert(is_bool<decltype(not(v_not_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(not(v_maybe_null))>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_logical_expression(bool{true});
|
||||
}
|
||||
|
@ -42,193 +42,73 @@ namespace
|
||||
auto db = MockDb{};
|
||||
}
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(r_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_maybe_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_opt_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_opt_maybe_null);
|
||||
|
||||
template<typename ResultType, typename Value>
|
||||
void test_result_row(Value v)
|
||||
{
|
||||
using OptResultType = sqlpp::compat::optional<ResultType>;
|
||||
|
||||
// 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);
|
||||
|
||||
// Optional selectable values.
|
||||
const auto v_opt_not_null = sqlpp::value(v).as(r_opt_not_null).if_(true);
|
||||
const auto v_opt_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_opt_maybe_null).if_(true);
|
||||
|
||||
for (const auto& row : db(select(v_not_null, v_maybe_null, v_opt_not_null, v_opt_maybe_null)))
|
||||
{
|
||||
static_assert(std::is_same<decltype(row.r_not_null), ResultType>::value, "");
|
||||
static_assert(std::is_same<decltype(row.r_maybe_null), OptResultType>::value, "");
|
||||
static_assert(std::is_same<decltype(row.r_opt_not_null), OptResultType>::value, "");
|
||||
static_assert(std::is_same<decltype(row.r_opt_maybe_null), OptResultType>::value, "");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
static_assert(not sqlpp::can_be_null<decltype(bar.id)>::value, "");
|
||||
static_assert(sqlpp::can_be_null<decltype(foo.doubleN)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null<decltype(foo.textNnD)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null<decltype(bar.boolNn)>::value, "");
|
||||
const auto seven = sqlpp::value(7).as(sqlpp::alias::s);
|
||||
static_assert(not sqlpp::can_be_null<decltype(seven)>::value, "");
|
||||
// boolean
|
||||
test_result_row<bool>(bool{true});
|
||||
|
||||
// Select non-optional column or alias of it.
|
||||
for (const auto& row : db(select(foo.id, foo.id.as(sqlpp::alias::a), foo.textNnD, foo.textNnD.as(sqlpp::alias::b))
|
||||
.from(foo)
|
||||
.unconditionally()))
|
||||
{
|
||||
static_assert(is_same_type<decltype(row.id), int64_t>(), "");
|
||||
static_assert(is_same_type<decltype(row.a), int64_t>(), "");
|
||||
static_assert(is_same_type<decltype(row.textNnD), sqlpp::compat::string_view>(), "");
|
||||
static_assert(is_same_type<decltype(row.b), sqlpp::compat::string_view>(), "");
|
||||
}
|
||||
// integral
|
||||
test_result_row<int64_t>(int8_t{7});
|
||||
test_result_row<int64_t>(int16_t{7});
|
||||
test_result_row<int64_t>(int32_t{7});
|
||||
test_result_row<int64_t>(int64_t{7});
|
||||
|
||||
// Optionally select non-optional column or alias of it.
|
||||
for (const auto& row : db(select(foo.id.if_(true), foo.id.as(sqlpp::alias::a).if_(true), foo.textNnD.if_(true),
|
||||
foo.textNnD.as(sqlpp::alias::b).if_(true))
|
||||
.from(foo)
|
||||
.unconditionally()))
|
||||
{
|
||||
static_assert(is_same_type<decltype(row.id), sqlpp::compat::optional<int64_t>>(), "");
|
||||
static_assert(is_same_type<decltype(row.a), sqlpp::compat::optional<int64_t>>(), "");
|
||||
static_assert(is_same_type<decltype(row.textNnD), sqlpp::compat::optional<sqlpp::compat::string_view>>(), "");
|
||||
static_assert(is_same_type<decltype(row.b), sqlpp::compat::optional<sqlpp::compat::string_view>>(), "");
|
||||
}
|
||||
// unsigned integral
|
||||
test_result_row<uint64_t>(uint8_t{7});
|
||||
test_result_row<uint64_t>(uint16_t{7});
|
||||
test_result_row<uint64_t>(uint32_t{7});
|
||||
test_result_row<uint64_t>(uint64_t{7});
|
||||
|
||||
// Select optional column or alias of it.
|
||||
for (const auto& row : db(select(bar.intN, bar.intN.as(sqlpp::alias::a), bar.textN, bar.textN.as(sqlpp::alias::b))
|
||||
.from(bar)
|
||||
.unconditionally()))
|
||||
{
|
||||
static_assert(is_same_type<decltype(row.intN), sqlpp::compat::optional<int64_t>>(), "");
|
||||
static_assert(is_same_type<decltype(row.a), sqlpp::compat::optional<int64_t>>(), "");
|
||||
static_assert(is_same_type<decltype(row.textN), sqlpp::compat::optional<sqlpp::compat::string_view>>(), "");
|
||||
static_assert(is_same_type<decltype(row.b), sqlpp::compat::optional<sqlpp::compat::string_view>>(), "");
|
||||
}
|
||||
// floating point
|
||||
test_result_row<double>(float{7.7});
|
||||
test_result_row<double>(double{7.7});
|
||||
|
||||
// Optionally select optional column or alias of it.
|
||||
for (const auto& row : db(select(bar.intN.if_(true), bar.intN.as(sqlpp::alias::a).if_(true), bar.textN.if_(true),
|
||||
bar.textN.as(sqlpp::alias::b).if_(true))
|
||||
.from(bar)
|
||||
.unconditionally()))
|
||||
{
|
||||
// optional optional are still represented as one level of optional
|
||||
static_assert(is_same_type<decltype(row.intN), sqlpp::compat::optional<int64_t>>(), "");
|
||||
static_assert(is_same_type<decltype(row.a), sqlpp::compat::optional<int64_t>>(), "");
|
||||
static_assert(is_same_type<decltype(row.textN), sqlpp::compat::optional<sqlpp::compat::string_view>>(), "");
|
||||
static_assert(is_same_type<decltype(row.b), sqlpp::compat::optional<sqlpp::compat::string_view>>(), "");
|
||||
}
|
||||
// text
|
||||
test_result_row<sqlpp::compat::string_view>('7');
|
||||
test_result_row<sqlpp::compat::string_view>("seven");
|
||||
test_result_row<sqlpp::compat::string_view>(std::string("seven"));
|
||||
test_result_row<sqlpp::compat::string_view>(sqlpp::compat::string_view("seven"));
|
||||
|
||||
// Select value and optional value.
|
||||
for (const auto& row : db(select(sqlpp::value(7).as(sqlpp::alias::a),
|
||||
sqlpp::value(sqlpp::compat::optional<int>(7)).as(sqlpp::alias::b))))
|
||||
{
|
||||
static_assert(is_same_type<decltype(row.a), int64_t>(), "");
|
||||
static_assert(is_same_type<decltype(row.b), sqlpp::compat::optional<int64_t>>(), "");
|
||||
}
|
||||
// blob
|
||||
test_result_row<sqlpp::compat::span<uint8_t>>(std::vector<uint8_t>{});
|
||||
|
||||
#warning: also test with optional
|
||||
static_assert(sqlpp::is_boolean<bool>::value, "");
|
||||
static_assert(sqlpp::is_boolean<decltype(bar.boolNn)>::value, "");
|
||||
static_assert(sqlpp::has_text_value<decltype(bar.textN)>::value, "");
|
||||
static_assert(sqlpp::has_text_value<std::string>::value, "");
|
||||
static_assert(sqlpp::has_numeric_value<int>::value, "");
|
||||
static_assert(sqlpp::has_numeric_value<decltype(bar.intN)>::value, "");
|
||||
// date
|
||||
test_result_row<::sqlpp::chrono::day_point>(::sqlpp::chrono::day_point{});
|
||||
|
||||
#warning: These should be moved into comparison type requirement tests, etc.
|
||||
// Comparing optional value with non-optional value yields optional boolean.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.textN < "hansi")>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.textN <= "hansi")>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.textN == "hansi")>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.textN != "hansi")>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.textN >= "hansi")>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.textN < "hansi")>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
// timestamp
|
||||
test_result_row<::sqlpp::chrono::microsecond_point>(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_result_row<::sqlpp::chrono::microsecond_point>(minute_point{});
|
||||
|
||||
// Comparing non-optional value with non-optional value yields non-optional boolean.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(foo.textNnD < "hansi")>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(foo.textNnD <= "hansi")>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(foo.textNnD == "hansi")>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(foo.textNnD != "hansi")>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(foo.textNnD >= "hansi")>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(foo.textNnD < "hansi")>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
|
||||
// The first exceptions are the operators is_null and is_not_null which always yield non-optional boolean
|
||||
#warning: Still need to implement is_distinct_from as member function
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_null(bar.textN))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_null(foo.textNnD))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_not_null(bar.textN))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_not_null(foo.textNnD))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
|
||||
// The other exceptions are the operators is_distinct_from and is_not_distinct_from which always yield non-optional boolean
|
||||
#warning: Still need to implement is_distinct_from as member function
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_distinct_from(bar.textN, "hansi"))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_distinct_from(foo.textNnD, "hansi"))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_not_distinct_from(bar.textN, sqlpp::compat::make_optional("hansi")))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(is_not_distinct_from(foo.textNnD, sqlpp::compat::make_optional("hansi")))>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
|
||||
|
||||
// LIKE expressions can be NULL is one of their operands can be NULL.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(like(bar.textN, "hansi"))>, sqlpp::compat::optional<sqlpp::boolean>>::value, "");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(like(foo.textNnD, sqlpp::compat::make_optional("hansi")))>, sqlpp::compat::optional<sqlpp::boolean>>::value, "");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(like(foo.textNnD, "hansi"))>, sqlpp::boolean>::value, "");
|
||||
|
||||
#warning: These should be moved into logical type requirement tests, etc.
|
||||
// Logically combining optional value with non-optional value yields optional boolean.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(sqlpp::compat::make_optional(bar.boolNn) and true)>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(sqlpp::compat::make_optional(bar.boolNn) or true)>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(sqlpp::compat::make_optional(bar.boolNn) and
|
||||
sqlpp::compat::make_optional(true))>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(sqlpp::compat::make_optional(bar.boolNn) or
|
||||
sqlpp::compat::make_optional(true))>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.boolNn and sqlpp::compat::make_optional(true))>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.boolNn or sqlpp::compat::make_optional(true))>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(not sqlpp::compat::make_optional(bar.boolNn))>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
|
||||
// Logically combining non-optional value with non-optional value yields non-optional boolean.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.boolNn and true)>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.boolNn or true)>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(not bar.boolNn)>,
|
||||
sqlpp::boolean>::value,
|
||||
"");
|
||||
// time_of_day
|
||||
test_result_row<std::chrono::microseconds>(std::chrono::microseconds{});
|
||||
|
||||
// Arithmetically combining optional value with non-optional value yields optional boolean.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(sqlpp::value(sqlpp::compat::make_optional(7)) + 8)>,
|
||||
@ -282,6 +162,7 @@ int main()
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
|
||||
// in expression
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(in(sqlpp::value(7), sqlpp::compat::make_optional(7), 8, 9))>,
|
||||
sqlpp::compat::optional<sqlpp::boolean>>::value,
|
||||
"");
|
||||
|
113
tests/core/types/value.cpp
Normal file
113
tests/core/types/value.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
auto db = MockDb{};
|
||||
}
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(r_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_maybe_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_opt_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_opt_maybe_null);
|
||||
|
||||
template <typename T, typename ValueType>
|
||||
using is_value_type = std::is_same<sqlpp::value_type_of_t<T>, ValueType>;
|
||||
|
||||
template<typename Value>
|
||||
void test_value(Value v)
|
||||
{
|
||||
using ValueType = sqlpp::value_type_of_t<Value>;
|
||||
using OptValueType = sqlpp::compat::optional<ValueType>;
|
||||
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
|
||||
auto v_not_null_alias = sqlpp::value(v).as(r_not_null);
|
||||
auto v_maybe_null_alias = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null);
|
||||
auto v_opt_not_null_alias = sqlpp::value(v).as(r_opt_not_null).if_(true);
|
||||
auto v_opt_maybe_null_alias = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_opt_maybe_null).if_(true);
|
||||
|
||||
static_assert(is_value_type<decltype(v_not_null), ValueType>::value, "");
|
||||
static_assert(is_value_type<decltype(v_maybe_null), OptValueType>::value, "");
|
||||
static_assert(is_value_type<decltype(v_not_null_alias), ValueType>::value, "");
|
||||
static_assert(is_value_type<decltype(v_maybe_null_alias), OptValueType>::value, "");
|
||||
static_assert(is_value_type<decltype(v_opt_not_null_alias), OptValueType>::value, "");
|
||||
static_assert(is_value_type<decltype(v_opt_maybe_null_alias), OptValueType>::value, "");
|
||||
|
||||
static_assert(not sqlpp::can_be_null<decltype(v_not_null)>::value, "");
|
||||
static_assert(sqlpp::can_be_null<decltype(v_maybe_null)>::value, "");
|
||||
static_assert(not sqlpp::can_be_null<decltype(v_not_null_alias)>::value, "");
|
||||
static_assert(sqlpp::can_be_null<decltype(v_maybe_null_alias)>::value, "");
|
||||
static_assert(sqlpp::can_be_null<decltype(v_opt_not_null_alias)>::value, "");
|
||||
static_assert(sqlpp::can_be_null<decltype(v_opt_maybe_null_alias)>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_value(bool{true});
|
||||
|
||||
// integral
|
||||
test_value(int8_t{7});
|
||||
test_value(int16_t{7});
|
||||
test_value(int32_t{7});
|
||||
test_value(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_value(uint8_t{7});
|
||||
test_value(uint16_t{7});
|
||||
test_value(uint32_t{7});
|
||||
test_value(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_value(float{7.7});
|
||||
test_value(double{7.7});
|
||||
|
||||
// text
|
||||
test_value('7');
|
||||
test_value("seven");
|
||||
test_value(std::string("seven"));
|
||||
test_value(sqlpp::compat::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_value(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_value(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_value(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_value(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_value(std::chrono::microseconds{});
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user