0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 12:51:13 +08:00

Added placeholders for operator serialize tests

Added SQLPP_COMPARE helper function
This commit is contained in:
Roland Bock 2024-08-03 12:14:00 +02:00
parent dfa9924288
commit e3f95a8e69
25 changed files with 1544 additions and 17 deletions

View File

@ -89,7 +89,7 @@ namespace sqlpp
};
template <typename L, typename Operator, typename R>
struct requires_braces<arithmetic_expression<L, Operator, R>> : public std::true_type{};
struct requires_parentheses<arithmetic_expression<L, Operator, R>> : public std::true_type{};
template <typename Context, typename L, typename Operator, typename R>
auto serialize(Context& context, const arithmetic_expression<L, Operator, R>& t) -> Context&

View File

@ -68,7 +68,7 @@ namespace sqlpp
};
template <typename L, typename R1, typename R2>
struct requires_braces<between_expression<L, R1, R2>> : public std::true_type{};
struct requires_parentheses<between_expression<L, R1, R2>> : public std::true_type{};
#warning: Need tests for between expressions
template <typename L, typename R1, typename R2, typename = check_between_args<L, R1, R2>>

View File

@ -72,7 +72,7 @@ namespace sqlpp
using check_bit_shift_expression_args = ::sqlpp::enable_if_t<is_integral<L>::value and (is_integral<R>::value or is_unsigned_integral<R>::value)>;
template <typename L, typename Operator, typename R>
struct requires_braces<bit_expression<L, Operator, R>> : public std::true_type {};
struct requires_parentheses<bit_expression<L, Operator, R>> : public std::true_type {};
template <typename Context, typename L, typename Operator, typename R>
auto serialize(Context& context, const bit_expression<L, Operator, R>& t) -> Context&

View File

@ -87,7 +87,7 @@ namespace sqlpp
};
template <typename When, typename Then, typename Else>
struct requires_braces<case_t<When, Then, Else>> : public std::true_type{};
struct requires_parentheses<case_t<When, Then, Else>> : public std::true_type{};
template <typename When, typename Then>
class case_then_t

View File

@ -85,7 +85,7 @@ namespace sqlpp
};
template <typename L, typename Operator, typename R>
struct requires_braces<comparison_expression<L, Operator, R>> : public std::true_type{};
struct requires_parentheses<comparison_expression<L, Operator, R>> : public std::true_type{};
template <typename Context, typename L, typename Operator, typename R>
auto serialize(Context& context, const comparison_expression<L, Operator, R>& t) -> Context&

View File

@ -96,7 +96,7 @@ namespace sqlpp
};
template <typename L, typename Operator, typename R>
struct requires_braces<in_expression<L, Operator, std::vector<R>>> : public std::true_type{};
struct requires_parentheses<in_expression<L, Operator, std::vector<R>>> : public std::true_type{};
template <typename L, typename Operator, typename... Args>
struct nodes_of<in_expression<L, Operator, std::tuple<Args...>>>
@ -105,7 +105,7 @@ namespace sqlpp
};
template <typename L, typename Operator, typename... Args>
struct requires_braces<in_expression<L, Operator, std::tuple<Args...>>> : public std::true_type{};
struct requires_parentheses<in_expression<L, Operator, std::tuple<Args...>>> : public std::true_type{};
template <typename Context, typename L, typename Operator, typename... Args>
auto serialize(Context& context, const in_expression<L, Operator, std::tuple<Args...>>& t) -> Context&

View File

@ -70,7 +70,7 @@ namespace sqlpp
};
template <typename L, typename Operator, typename R>
struct requires_braces<logical_expression<L, Operator, R>> : public std::true_type{};
struct requires_parentheses<logical_expression<L, Operator, R>> : public std::true_type{};
template <typename Context, typename L, typename Operator, typename R>
auto serialize_impl(Context& context, const logical_expression<L, Operator, R>& t) -> Context&

View File

@ -204,8 +204,7 @@ namespace sqlpp
tag_if<tag::is_select, logic::any_t<is_select_t<Policies>::value...>::value>,
tag_if<tag::is_expression, is_expression_t<_policies_t>::value>,
tag_if<tag::is_selectable, is_expression_t<_policies_t>::value>,
tag_if<tag::is_return_value, logic::none_t<is_noop_t<_result_type_provider>::value>::value>,
tag::requires_parens>;
tag_if<tag::is_return_value, logic::none_t<is_noop_t<_result_type_provider>::value>::value>>;
using _name_tag_of = name_tag_of<_result_type_provider>;
using _nodes = detail::type_vector<_policies_t>;
using _used_outer_tables = typename _policies_t::_all_provided_outer_tables;
@ -274,6 +273,9 @@ namespace sqlpp
using type = typename detail::type_vector<Policies...>;
};
template <typename... Policies>
struct requires_parentheses<statement_t<Policies...>> : public std::true_type {};
template <typename Context, typename... Policies>
Context& serialize(Context& context, const statement_t<Policies...>& t)
{

View File

@ -220,7 +220,7 @@ namespace sqlpp
template <typename T, typename Context>
auto serialize_operand(Context& context, const T& t) -> Context&
{
if (requires_parens_t<T>::value)
if (requires_parentheses<T>::value)
{
context << '(';
serialize(context, t);

View File

@ -497,8 +497,6 @@ namespace sqlpp
SQLPP_VALUE_TRAIT_GENERATOR(is_insert_value_list)
SQLPP_VALUE_TRAIT_GENERATOR(is_parameter)
SQLPP_VALUE_TRAIT_GENERATOR(requires_parens)
SQLPP_VALUE_TRAIT_GENERATOR(enforce_null_result_treatment)
template <typename Tag, bool Condition>
@ -843,9 +841,8 @@ namespace sqlpp
template <typename Statement, template <typename> class Predicate>
using has_policy_t = typename has_policy_impl<Statement, Predicate>::type;
#warning rename to requires_parentheses
template<typename T>
struct requires_braces : public std::false_type {};
struct requires_parentheses : public std::false_type {};
struct no_context_t
{

View File

@ -31,16 +31,17 @@
namespace
{
template <typename Result, typename Expected>
void assert_equal(int lineNo, const Result& result, const Expected& expected)
void assert_equal(const std::string& file, int lineNo, const Result& result, const Expected& expected)
{
if (result != expected)
{
std::cerr << __FILE__ << " " << lineNo << '\n' << "Expected: -->|" << expected << "|<--\n"
std::cerr << file << " " << lineNo << '\n' << "Expected: -->|" << expected << "|<--\n"
<< "Received: -->|" << result << "|<--\n";
throw std::runtime_error("unexpected result");
}
}
#warning Drop compare and use SQLPP_COMPARE instead
template <typename Expression>
void compare(int lineNo, const Expression& expr, const std::string& expected)
{
@ -51,4 +52,21 @@ namespace
assert_equal(lineNo, result, expected);
}
#warning: Maybe move this into the library/test_support together with MockDb
#define SQLPP_COMPARE(expr, expected_string) \
{ \
MockDb::_serializer_context_t printer = {}; \
\
using sqlpp::serialize; \
const auto result = serialize(printer, expr).str(); \
\
if (result != expected_string) \
{ \
std::cerr << __FILE__ << " " << __LINE__ << '\n' \
<< "Expected: -->|" << expected_string << "|<--\n" \
<< "Received: -->|" << result << "|<--\n"; \
return -1; \
} \
}
}

View File

@ -0,0 +1,44 @@
# 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:
#
# 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.
function(create_test name)
set(target sqlpp11_core_serialize_operator_${name})
add_executable(${target} ${name}.cpp)
target_link_libraries(${target} PRIVATE sqlpp11::sqlpp11 sqlpp11_testing)
add_test(NAME ${target} COMMAND ${target})
endfunction()
create_test(any)
create_test(arithmetic_expression)
create_test(as_expression)
create_test(assign_expression)
create_test(between_expression)
create_test(bit_expression)
create_test(case_expression)
create_test(comparison_expression)
create_test(exists_expression)
create_test(in_expression)
create_test(logical_expression)
create_test(sort_order_expression)

View File

@ -0,0 +1,39 @@
/*
* 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:
*
* * 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 "../compare.h"
#include <sqlpp11/sqlpp11.h>
SQLPP_ALIAS_PROVIDER(v);
int main(int, char* [])
{
const auto val = sqlpp::value(17);
SQLPP_COMPARE(any(select(val.as(v))), "ANY(SELECT 17 AS v)");
SQLPP_COMPARE(val == any(select(val.as(v))), "17 = ANY(SELECT 17 AS v)");
return 0;
}

View File

@ -0,0 +1,195 @@
/*
* 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:
*
* * 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>
#include "../../include/test_helpers.h"
namespace
{
template<typename A, typename B>
constexpr bool is_same_type()
{
return std::is_same<A, B>::value;
}
}
#warning: implement serialize instead of type tests here!
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 Value>
void test_arithmetic_expressions(Value v)
{
using ValueType = sqlpp::numeric;
using OptValueType = ::sqlpp::optional<sqlpp::numeric>;
auto value = sqlpp::value(v);
auto opt_value = sqlpp::value(::sqlpp::make_optional(v));
// Arithmetically combining non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value - value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value * value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value / value)>, ValueType>(), "");
// Arithmetically combining non-optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value - opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value * opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value / opt_value)>, OptValueType>(), "");
// Arithmetically combining optional with non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value - value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value * value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value / value)>, OptValueType>(), "");
// Arithmetically combining optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value - opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value * opt_value)>, OptValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value / opt_value)>, OptValueType>(), "");
// Same with negate.
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-opt_value)>, OptValueType>(), "");
// Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value + opt_value)>::value, "");
static_assert(sqlpp::has_enabled_as<decltype(-opt_value)>::value, "");
// Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(-opt_value)>::value, "");
// Arithmetic expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type;
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value + opt_value)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(-opt_value)>, sqlpp::detail::type_vector<sqlpp::noop, R>>::value, "");
}
template<typename Value>
void test_modulus_expressions(Value v)
{
using ValueType = sqlpp::numeric;
using OptValueType = ::sqlpp::optional<sqlpp::numeric>;
auto value = sqlpp::value(v);
auto opt_value = sqlpp::value(::sqlpp::make_optional(v));
// Modulus combining non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value % value)>, ValueType>(), "");
// Modulus combining non-optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value % opt_value)>, OptValueType>(), "");
// Modulus combining optional with non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % value)>, OptValueType>(), "");
// Modulus combining optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % opt_value)>, OptValueType>(), "");
// Modulus expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value % opt_value)>::value, "");
// Modulus expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(value % opt_value)>::value, "");
// Modulus expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type;
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value % opt_value)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
template<typename Value>
void test_concatenation_expressions(Value v)
{
using ValueType = sqlpp::text;
using OptValueType = ::sqlpp::optional<sqlpp::text>;
auto value = sqlpp::value(v);
auto opt_value = sqlpp::value(::sqlpp::make_optional(v));
// Concatenating non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + value)>, ValueType>(), "");
// Concatenating non-optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + opt_value)>, OptValueType>(), "");
// Concatenating optional with non-optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + value)>, OptValueType>(), "");
// Concatenating optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + opt_value)>, OptValueType>(), "");
// Modulus expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value + opt_value)>::value, "");
// Modulus expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(value + opt_value)>::value, "");
// Modulus expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type;
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value + opt_value)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
int main()
{
// integral
test_arithmetic_expressions(int8_t{7});
test_arithmetic_expressions(int16_t{7});
test_arithmetic_expressions(int32_t{7});
test_arithmetic_expressions(int64_t{7});
test_modulus_expressions(int8_t{7});
test_modulus_expressions(int16_t{7});
test_modulus_expressions(int32_t{7});
test_modulus_expressions(int64_t{7});
// unsigned integral
test_arithmetic_expressions(uint8_t{7});
test_arithmetic_expressions(uint16_t{7});
test_arithmetic_expressions(uint32_t{7});
test_arithmetic_expressions(uint64_t{7});
test_modulus_expressions(uint8_t{7});
test_modulus_expressions(uint16_t{7});
test_modulus_expressions(uint32_t{7});
test_modulus_expressions(uint64_t{7});
// floating point
test_arithmetic_expressions(float{7.7});
test_arithmetic_expressions(double{7.7});
// text
test_concatenation_expressions('7');
test_concatenation_expressions("seven");
test_concatenation_expressions(std::string("seven"));
test_concatenation_expressions(::sqlpp::string_view("seven"));
}

View File

@ -0,0 +1,118 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
SQLPP_ALIAS_PROVIDER(cheese);
template <typename T, typename ValueType>
using is_select_column_value_type = std::is_same<sqlpp::select_column_value_type_of_t<T>, ValueType>;
template<typename Value>
void test_as_expression(Value v)
{
using ValueType = sqlpp::value_type_of_t<Value>;
using OptValueType = ::sqlpp::optional<ValueType>;
auto v_not_null= sqlpp::value(v);
auto v_maybe_null= sqlpp::value(::sqlpp::make_optional(v));
auto v_dynamic_not_null = dynamic(true, sqlpp::value(v));
auto v_dynamic_maybe_null = dynamic(true, sqlpp::value(::sqlpp::make_optional(v)));
static_assert(not sqlpp::has_value_type<decltype(v_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_dynamic_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_dynamic_maybe_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_maybe_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_dynamic_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_dynamic_maybe_null.as(cheese))>::value, "");
static_assert(is_select_column_value_type<decltype(v_not_null.as(cheese)), ValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_maybe_null.as(cheese)), OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_dynamic_not_null.as(cheese)), OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_dynamic_maybe_null.as(cheese)), OptValueType>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_not_null.as(cheese))>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_maybe_null.as(cheese))>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_dynamic_not_null.as(cheese))>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_dynamic_maybe_null.as(cheese))>::value, "");
// AS expressions have do not enable the `as` member function.
static_assert(not sqlpp::has_enabled_as<decltype(v_not_null.as(cheese))>::value, "");
// AS expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null.as(cheese))>::value, "");
// AS expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null.as(cheese))>, sqlpp::detail::type_vector<L>>::value, "");
}
int main()
{
// boolean
test_as_expression(bool{true});
// integral
test_as_expression(int8_t{7});
test_as_expression(int16_t{7});
test_as_expression(int32_t{7});
test_as_expression(int64_t{7});
// unsigned integral
test_as_expression(uint8_t{7});
test_as_expression(uint16_t{7});
test_as_expression(uint32_t{7});
test_as_expression(uint64_t{7});
// floating point
test_as_expression(float{7.7});
test_as_expression(double{7.7});
// text
test_as_expression('7');
test_as_expression("seven");
test_as_expression(std::string("seven"));
test_as_expression(::sqlpp::string_view("seven"));
// blob
test_as_expression(std::vector<uint8_t>{});
// date
test_as_expression(::sqlpp::chrono::day_point{});
// timestamp
test_as_expression(::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_as_expression(minute_point{});
// time_of_day
test_as_expression(std::chrono::microseconds{});
}

View File

@ -0,0 +1,132 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
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::optional<sqlpp::boolean>>;
}
template <typename Column, typename Value>
void test_assign_expression(const Column& col, const Value& v)
{
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
using ValueType = decltype(v_not_null);
using OptValueType = decltype(v_maybe_null);
// Assignments have no value
static_assert(not sqlpp::has_value_type<decltype(col = sqlpp::default_value)>::value, "");
static_assert(not sqlpp::has_value_type<decltype(col = v_not_null)>::value, "");
static_assert(not sqlpp::has_value_type<decltype(col = v_maybe_null)>::value, "");
// Assignments have no name
static_assert(not sqlpp::has_name<decltype(col = sqlpp::default_value)>::value, "");
static_assert(not sqlpp::has_name<decltype(col = v_not_null)>::value, "");
static_assert(not sqlpp::has_name<decltype(col = v_maybe_null)>::value, "");
// Assignment nodes
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = sqlpp::default_value)>,
sqlpp::detail::type_vector<Column, sqlpp::default_value_t>>::value,
"");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = v_not_null)>,
sqlpp::detail::type_vector<Column, ValueType>>::value,
"");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = v_maybe_null)>,
sqlpp::detail::type_vector<Column, OptValueType>>::value,
"");
// Assign expressions do not have the `as` member function.
static_assert(not sqlpp::has_enabled_as<decltype(col = v_not_null)>::value, "");
// Assign expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(col = v_not_null)>::value, "");
// Assign expressions have their arguments as nodes.
using L = typename std::decay<decltype(col)>::type;
using R = typename std::decay<decltype(v_not_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = v_not_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
#warning: test that non-nullable columns cannot be assigned optional values
#warning: test that non-default columns cannot be assigned to default_value
int main()
{
const auto bar = test::TabBar{};
const auto foo = test::TabFoo{};
const auto date_time = test::TabDateTime{};
// boolean
test_assign_expression(foo.boolN, bool{true});
// integral
test_assign_expression(foo.intN, int8_t{7});
test_assign_expression(foo.intN, int16_t{7});
test_assign_expression(foo.intN, int32_t{7});
test_assign_expression(foo.intN, int64_t{7});
// unsigned integral
test_assign_expression(foo.uIntN, uint8_t{7});
test_assign_expression(foo.uIntN, uint16_t{7});
test_assign_expression(foo.uIntN, uint32_t{7});
test_assign_expression(foo.uIntN, uint64_t{7});
// floating point
test_assign_expression(foo.doubleN, float{7.7});
test_assign_expression(foo.doubleN, double{7.7});
// text
test_assign_expression(bar.textN, '7');
test_assign_expression(bar.textN, "seven");
test_assign_expression(bar.textN, std::string("seven"));
test_assign_expression(bar.textN, ::sqlpp::string_view("seven"));
// blob
test_assign_expression(foo.blobN, std::vector<uint8_t>{});
// date
test_assign_expression(date_time.dayPointN, ::sqlpp::chrono::day_point{});
// timestamp
test_assign_expression(date_time.timePointN, ::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_assign_expression(date_time.timePointN, minute_point{});
// time_of_day
test_assign_expression(date_time.timeOfDayN, std::chrono::microseconds{});
}

View File

@ -0,0 +1,113 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
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::optional<sqlpp::boolean>>;
}
template <typename Value>
void test_between_expression(Value v)
{
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
// Variations of nullable and non-nullable values
static_assert(is_bool<decltype(between(v_not_null, v_not_null, v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_not_null, v_not_null, v_maybe_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_not_null, v_maybe_null, v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_not_null, v_maybe_null, v_maybe_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_not_null, v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_not_null, v_maybe_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_maybe_null, v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_maybe_null, v_maybe_null))>::value, "");
// Between expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(between(v_not_null, v_not_null, v_not_null))>::value, "");
// Between expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(between(v_not_null, v_not_null, v_not_null))>::value, "");
// Between expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
using M = Value;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(between(v_not_null, v, v_maybe_null))>, sqlpp::detail::type_vector<L, M, R>>::value, "");
}
int main()
{
// boolean
test_between_expression(bool{true});
// integral
test_between_expression(int8_t{7});
test_between_expression(int16_t{7});
test_between_expression(int32_t{7});
test_between_expression(int64_t{7});
// unsigned integral
test_between_expression(uint8_t{7});
test_between_expression(uint16_t{7});
test_between_expression(uint32_t{7});
test_between_expression(uint64_t{7});
// floating point
test_between_expression(float{7.7});
test_between_expression(double{7.7});
// text
test_between_expression('7');
test_between_expression("seven");
test_between_expression(std::string("seven"));
test_between_expression(::sqlpp::string_view("seven"));
// blob
test_between_expression(std::vector<uint8_t>{});
// date
test_between_expression(::sqlpp::chrono::day_point{});
// timestamp
test_between_expression(::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_between_expression(minute_point{});
// time_of_day
test_between_expression(std::chrono::microseconds{});
}

View File

@ -0,0 +1,145 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
namespace
{
auto db = MockDb{};
template <typename T>
using is_integral = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::integral>;
template <typename T>
using is_maybe_integral = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::integral>>;
}
template <typename Value>
void test_bit_expression(Value v)
{
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
// Compare non-nullable with non-nullable.
static_assert(is_integral<decltype(v_not_null << v_not_null)>::value, "");
static_assert(is_integral<decltype(v_not_null >> v_not_null)>::value, "");
static_assert(is_integral<decltype(v_not_null | v_not_null)>::value, "");
static_assert(is_integral<decltype(v_not_null & v_not_null)>::value, "");
static_assert(is_integral<decltype(v_not_null ^ v_not_null)>::value, "");
// Compare non-nullable with nullable.
static_assert(is_maybe_integral<decltype(v_not_null << v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_not_null >> v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_not_null | v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_not_null & v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_not_null ^ v_maybe_null)>::value, "");
// Compare nullable with non-nullable.
static_assert(is_maybe_integral<decltype(v_maybe_null << v_not_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null >> v_not_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null | v_not_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null & v_not_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null ^ v_not_null)>::value, "");
// Compare nullable with nullable.
static_assert(is_maybe_integral<decltype(v_maybe_null << v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null >> v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null | v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null & v_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(v_maybe_null ^ v_maybe_null)>::value, "");
// Compare with null.
static_assert(is_integral<decltype(~v_not_null)>::value, "");
static_assert(is_maybe_integral<decltype(~v_maybe_null)>::value, "");
// Comparison expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(v_not_null << v_maybe_null)>::value, "");
static_assert(sqlpp::has_enabled_as<decltype(~v_not_null)>::value, "");
// Comparison expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null << v_maybe_null)>::value, "");
// Comparison expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null << v_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(~v_not_null)>, sqlpp::detail::type_vector<sqlpp::noop, L>>::value, "");
}
template <typename Left, typename Right>
void test_bit_shift_expression(Left l, Right r)
{
auto l_not_null = sqlpp::value(l);
auto l_maybe_null = sqlpp::value(::sqlpp::make_optional(l));
auto r_not_null = sqlpp::value(r);
auto r_maybe_null = sqlpp::value(::sqlpp::make_optional(r));
// Compare non-nullable with non-nullable.
static_assert(is_integral<decltype(l_not_null << r_not_null)>::value, "");
static_assert(is_integral<decltype(l_not_null >> r_not_null)>::value, "");
// Compare non-nullable with nullable.
static_assert(is_maybe_integral<decltype(l_not_null << r_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(l_not_null >> r_maybe_null)>::value, "");
// Compare nullable with non-nullable.
static_assert(is_maybe_integral<decltype(l_maybe_null << r_not_null)>::value, "");
static_assert(is_maybe_integral<decltype(l_maybe_null >> r_not_null)>::value, "");
// Compare nullable with nullable.
static_assert(is_maybe_integral<decltype(l_maybe_null << r_maybe_null)>::value, "");
static_assert(is_maybe_integral<decltype(l_maybe_null >> r_maybe_null)>::value, "");
// Comparison expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(l_not_null << r_maybe_null)>::value, "");
// Comparison expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(l_not_null << r_maybe_null)>::value, "");
// Comparison expressions have their arguments as nodes.
using L = typename std::decay<decltype(l_not_null)>::type;
using R = typename std::decay<decltype(r_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l_not_null << r_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
}
int main()
{
// bit expression require integral operands
test_bit_expression(int8_t{7});
test_bit_expression(int16_t{7});
test_bit_expression(int32_t{7});
test_bit_expression(int64_t{7});
// bit shift operations can have unsigned rhs operands
test_bit_shift_expression(int8_t{7}, uint8_t{7});
test_bit_shift_expression(int8_t{7}, uint16_t{7});
test_bit_shift_expression(int8_t{7}, uint32_t{7});
test_bit_shift_expression(int8_t{7}, uint64_t{7});
}

View File

@ -0,0 +1,112 @@
/*
* 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:
*
* * 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>
template<typename T, typename Value>
using is_same_type = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::value_type_of_t<Value>>;
#warning: implement serialize instead of type tests here!
template <typename Value>
void test_case_expression(Value v)
{
auto c_not_null = sqlpp::value(true);
auto c_maybe_null = sqlpp::value(::sqlpp::make_optional(false));
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
using ValueType = sqlpp::value_type_of_t<decltype(v_not_null)>;
using OptValueType = sqlpp::value_type_of_t<decltype(v_maybe_null)>;
// Variations of nullable and non-nullable values
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_not_null).else_(v_not_null)), ValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_not_null).else_(v_maybe_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_maybe_null).else_(v_not_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_maybe_null).else_(v_maybe_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_not_null).else_(v_not_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_not_null).else_(v_maybe_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_maybe_null).else_(v_not_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_maybe_null).else_(v_maybe_null)), OptValueType>::value, "");
// Incomplete case expressions have no value.
static_assert(not sqlpp::has_value_type<decltype(case_when(c_not_null))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(case_when(c_not_null).then(v_not_null))>::value, "");
// Case expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(case_when(c_not_null).then(v_not_null).else_(v_not_null))>::value, "");
// Case expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(case_when(c_not_null).then(v_not_null).else_(v_not_null))>::value, "");
// Between expressions have their arguments as nodes.
using L = typename std::decay<decltype(c_not_null)>::type;
using M = typename std::decay<decltype(v_not_null)>::type;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(case_when(c_not_null).then(v_not_null).else_(v_maybe_null))>, sqlpp::detail::type_vector<L, M, R>>::value, "");
}
int main()
{
// boolean
test_case_expression(bool{true});
// integral
test_case_expression(int8_t{7});
test_case_expression(int16_t{7});
test_case_expression(int32_t{7});
test_case_expression(int64_t{7});
// unsigned integral
test_case_expression(uint8_t{7});
test_case_expression(uint16_t{7});
test_case_expression(uint32_t{7});
test_case_expression(uint64_t{7});
// floating point
test_case_expression(float{7.7});
test_case_expression(double{7.7});
// text
test_case_expression('7');
test_case_expression("seven");
test_case_expression(std::string("seven"));
test_case_expression(::sqlpp::string_view("seven"));
// blob
test_case_expression(std::vector<uint8_t>{});
// date
test_case_expression(::sqlpp::chrono::day_point{});
// timestamp
test_case_expression(::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_case_expression(minute_point{});
// time_of_day
test_case_expression(std::chrono::microseconds{});
}

View File

@ -0,0 +1,181 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
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::optional<sqlpp::boolean>>;
}
template <typename Value>
void test_comparison_expression(Value v)
{
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
#warning : Should also implement between 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, "");
// Comparison expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(v_not_null == v_maybe_null)>::value, "");
static_assert(sqlpp::has_enabled_as<decltype(is_null(v_not_null))>::value, "");
// Comparison expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null == v_maybe_null)>::value, "");
// Comparison expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null == v_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(is_null(v_not_null))>, sqlpp::detail::type_vector<L, ::sqlpp::nullopt_t>>::value, "");
}
template<typename Value>
void test_like(Value v)
{
auto v_not_null= sqlpp::value(v);
auto v_maybe_null= sqlpp::value(::sqlpp::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::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::string_view("seven"));
}

View File

@ -0,0 +1,97 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
SQLPP_ALIAS_PROVIDER(r_not_null);
SQLPP_ALIAS_PROVIDER(r_maybe_null);
template <typename Value>
void test_exists(Value v)
{
// Selectable values.
const auto v_not_null = sqlpp::value(v).as(r_not_null);
const auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v)).as(r_maybe_null);
// EXISTS expression can be used in basic comparison expressions, which use remove_exists_t to look inside.
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(exists(select(v_not_null)))>, sqlpp::boolean>::value, "");
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(exists(select(v_maybe_null)))>, sqlpp::boolean>::value, "");
// EXISTS expressions enable `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(exists(select(v_not_null)))>::value, "");
// EXISTS expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(exists(select(v_not_null)))>::value, "");
// EXISTS expressions have the SELECT as node.
using S = decltype(select(v_not_null));
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(exists(select(v_not_null)))>, sqlpp::detail::type_vector<S>>::value, "");
#warning: Note that a sub select may require tables from the enclosing select. This is currently not correctly implemented. We need to test that.
}
int main()
{
// boolean
test_exists(bool{true});
// integral
test_exists(int8_t{7});
test_exists(int16_t{7});
test_exists(int32_t{7});
test_exists(int64_t{7});
// unsigned integral
test_exists(uint8_t{7});
test_exists(uint16_t{7});
test_exists(uint32_t{7});
test_exists(uint64_t{7});
// floating point
test_exists(float{7.7});
test_exists(double{7.7});
// text
test_exists('7');
test_exists("seven");
test_exists(std::string("seven"));
test_exists(::sqlpp::string_view("seven"));
// blob
test_exists(std::vector<uint8_t>{});
// date
test_exists(::sqlpp::chrono::day_point{});
// timestamp
test_exists(::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_exists(minute_point{});
// time_of_day
test_exists(std::chrono::microseconds{});
}

View File

@ -0,0 +1,123 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
namespace
{
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::optional<sqlpp::boolean>>;
}
template <typename Value>
void test_in_expression(Value v)
{
using OptValue = ::sqlpp::optional<Value>;
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
// 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, "");
static_assert(is_bool<decltype(in(v_not_null, select(v_not_null.as(sqlpp::alias::a))))>::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, "");
static_assert(is_maybe_bool<decltype(in(v_not_null, select(v_maybe_null.as(sqlpp::alias::a))))>::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, "");
static_assert(is_maybe_bool<decltype(in(v_maybe_null, select(v_not_null.as(sqlpp::alias::a))))>::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, "");
static_assert(is_maybe_bool<decltype(in(v_maybe_null, select(v_maybe_null.as(sqlpp::alias::a))))>::value, "");
// IN expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
// IN expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
// IN expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_maybe_null)>::type;
using R1= Value;
using R2= OptValue;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(in(v_maybe_null, std::vector<Value>{}))>, sqlpp::detail::type_vector<L, R1>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(in(v_maybe_null, v, ::sqlpp::make_optional(v)))>, sqlpp::detail::type_vector<L, R1, R2>>::value, "");
}
int main()
{
// boolean
test_in_expression(bool{true});
#warning reactivate
#if 0
// 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::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{});
#endif
}

View File

@ -0,0 +1,96 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
namespace
{
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::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::make_optional(v));
// Combine 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, "");
static_assert(is_bool<decltype(v_not_null and dynamic(true, v_not_null))>::value, "");
static_assert(is_bool<decltype(v_not_null or dynamic(true, v_not_null))>::value, "");
// Combine nullable with non-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, "");
static_assert(is_maybe_bool<decltype(v_maybe_null and dynamic(true, v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(v_maybe_null or dynamic(true, v_not_null))>::value, "");
// Combine non-nullable with 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, "");
static_assert(is_maybe_bool<decltype(v_not_null and dynamic(true, v_maybe_null))>::value, "");
static_assert(is_maybe_bool<decltype(v_not_null or dynamic(true, v_maybe_null))>::value, "");
// Combine 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, "");
static_assert(is_maybe_bool<decltype(v_maybe_null and dynamic(true, v_maybe_null))>::value, "");
static_assert(is_maybe_bool<decltype(v_maybe_null or dynamic(true, 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, "");
// Logical expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(v_not_null and v_maybe_null)>::value, "");
static_assert(sqlpp::has_enabled_as<decltype(v_maybe_null or dynamic(true, v_maybe_null))>::value, "");
// Logical expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null == v_maybe_null)>::value, "");
static_assert(not sqlpp::has_enabled_comparison<decltype(v_maybe_null or dynamic(true, v_maybe_null))>::value, "");
// Logical expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null and v_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null and dynamic(true, v_maybe_null))>, sqlpp::detail::type_vector<L, sqlpp::dynamic_t<R>>>::value, "");
}
int main()
{
// boolean
test_logical_expression(bool{true});
}

View File

@ -0,0 +1,113 @@
/*
* 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:
*
* * 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>
#warning: implement serialize instead of type tests here!
template<typename Value>
void test_as_expression(Value v)
{
using ValueType = sqlpp::value_type_of_t<Value>;
using OptValueType = ::sqlpp::optional<ValueType>;
auto v_not_null= sqlpp::value(v);
auto v_maybe_null= sqlpp::value(::sqlpp::make_optional(v));
// Sort order expressions have no value.
static_assert(not sqlpp::has_value_type<decltype(v_not_null.asc())>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_not_null.desc())>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_not_null.order(sqlpp::sort_type::asc))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.asc())>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.desc())>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.order(sqlpp::sort_type::asc))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_not_null.asc()))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_not_null.desc()))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_not_null.order(sqlpp::sort_type::asc)))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_maybe_null.asc()))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_maybe_null.desc()))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_maybe_null.order(sqlpp::sort_type::asc)))>::value, "");
// Sort order expressions have no name.
static_assert(not sqlpp::has_name<decltype(v_not_null.asc())>::value, "");
static_assert(not sqlpp::has_name<decltype(v_maybe_null.asc())>::value, "");
static_assert(not sqlpp::has_name<decltype(dynamic(true, v_not_null.asc()))>::value, "");
static_assert(not sqlpp::has_name<decltype(dynamic(true, v_maybe_null.asc()))>::value, "");
// Sort order expression do not enable the `as` member function.
static_assert(not sqlpp::has_enabled_as<decltype(v_not_null.asc())>::value, "");
// Sort order expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null.asc())>::value, "");
// Sort order expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null.asc())>, sqlpp::detail::type_vector<L>>::value, "");
}
int main()
{
// boolean
test_as_expression(bool{true});
// integral
test_as_expression(int8_t{7});
test_as_expression(int16_t{7});
test_as_expression(int32_t{7});
test_as_expression(int64_t{7});
// unsigned integral
test_as_expression(uint8_t{7});
test_as_expression(uint16_t{7});
test_as_expression(uint32_t{7});
test_as_expression(uint64_t{7});
// floating point
test_as_expression(float{7.7});
test_as_expression(double{7.7});
// text
test_as_expression('7');
test_as_expression("seven");
test_as_expression(std::string("seven"));
test_as_expression(::sqlpp::string_view("seven"));
// blob
test_as_expression(std::vector<uint8_t>{});
// date
test_as_expression(::sqlpp::chrono::day_point{});
// timestamp
test_as_expression(::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_as_expression(minute_point{});
// time_of_day
test_as_expression(std::chrono::microseconds{});
}

View File

@ -61,6 +61,8 @@ void test_any(Value v)
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(any(select(v_not_null)))>, sqlpp::detail::type_vector<S>>::value, "");
#warning: Note that a sub select may require tables from the enclosing select. This is currently not correctly implemented. We need to test that.
#warning: here and in the other operator tests: test "requires_parentheses"
}
int main()