diff --git a/include/sqlpp11/core/operator/arithmetic_expression.h b/include/sqlpp11/core/operator/arithmetic_expression.h index 5d2f7ea1..094643d1 100644 --- a/include/sqlpp11/core/operator/arithmetic_expression.h +++ b/include/sqlpp11/core/operator/arithmetic_expression.h @@ -89,7 +89,7 @@ namespace sqlpp }; template - struct requires_braces> : public std::true_type{}; + struct requires_parentheses> : public std::true_type{}; template auto serialize(Context& context, const arithmetic_expression& t) -> Context& diff --git a/include/sqlpp11/core/operator/between_expression.h b/include/sqlpp11/core/operator/between_expression.h index e0b47d42..c9e94451 100644 --- a/include/sqlpp11/core/operator/between_expression.h +++ b/include/sqlpp11/core/operator/between_expression.h @@ -68,7 +68,7 @@ namespace sqlpp }; template - struct requires_braces> : public std::true_type{}; + struct requires_parentheses> : public std::true_type{}; #warning: Need tests for between expressions template > diff --git a/include/sqlpp11/core/operator/bit_expression.h b/include/sqlpp11/core/operator/bit_expression.h index ef0fdcc9..f324e691 100644 --- a/include/sqlpp11/core/operator/bit_expression.h +++ b/include/sqlpp11/core/operator/bit_expression.h @@ -72,7 +72,7 @@ namespace sqlpp using check_bit_shift_expression_args = ::sqlpp::enable_if_t::value and (is_integral::value or is_unsigned_integral::value)>; template - struct requires_braces> : public std::true_type {}; + struct requires_parentheses> : public std::true_type {}; template auto serialize(Context& context, const bit_expression& t) -> Context& diff --git a/include/sqlpp11/core/operator/case.h b/include/sqlpp11/core/operator/case.h index a6aa31c1..3d171120 100644 --- a/include/sqlpp11/core/operator/case.h +++ b/include/sqlpp11/core/operator/case.h @@ -87,7 +87,7 @@ namespace sqlpp }; template - struct requires_braces> : public std::true_type{}; + struct requires_parentheses> : public std::true_type{}; template class case_then_t diff --git a/include/sqlpp11/core/operator/comparison_expression.h b/include/sqlpp11/core/operator/comparison_expression.h index 8c5e22d3..43854583 100644 --- a/include/sqlpp11/core/operator/comparison_expression.h +++ b/include/sqlpp11/core/operator/comparison_expression.h @@ -85,7 +85,7 @@ namespace sqlpp }; template - struct requires_braces> : public std::true_type{}; + struct requires_parentheses> : public std::true_type{}; template auto serialize(Context& context, const comparison_expression& t) -> Context& diff --git a/include/sqlpp11/core/operator/in_expression.h b/include/sqlpp11/core/operator/in_expression.h index 5b7de06e..eaa8bc37 100644 --- a/include/sqlpp11/core/operator/in_expression.h +++ b/include/sqlpp11/core/operator/in_expression.h @@ -96,7 +96,7 @@ namespace sqlpp }; template - struct requires_braces>> : public std::true_type{}; + struct requires_parentheses>> : public std::true_type{}; template struct nodes_of>> @@ -105,7 +105,7 @@ namespace sqlpp }; template - struct requires_braces>> : public std::true_type{}; + struct requires_parentheses>> : public std::true_type{}; template auto serialize(Context& context, const in_expression>& t) -> Context& diff --git a/include/sqlpp11/core/operator/logical_expression.h b/include/sqlpp11/core/operator/logical_expression.h index 2b6c102e..3b17a331 100644 --- a/include/sqlpp11/core/operator/logical_expression.h +++ b/include/sqlpp11/core/operator/logical_expression.h @@ -70,7 +70,7 @@ namespace sqlpp }; template - struct requires_braces> : public std::true_type{}; + struct requires_parentheses> : public std::true_type{}; template auto serialize_impl(Context& context, const logical_expression& t) -> Context& diff --git a/include/sqlpp11/core/query/statement.h b/include/sqlpp11/core/query/statement.h index 217f179d..47b6f7e2 100644 --- a/include/sqlpp11/core/query/statement.h +++ b/include/sqlpp11/core/query/statement.h @@ -204,8 +204,7 @@ namespace sqlpp tag_if::value...>::value>, tag_if::value>, tag_if::value>, - tag_if::value>::value>, - tag::requires_parens>; + tag_if::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; }; + template + struct requires_parentheses> : public std::true_type {}; + template Context& serialize(Context& context, const statement_t& t) { diff --git a/include/sqlpp11/core/serialize.h b/include/sqlpp11/core/serialize.h index 7a28704d..d9efe50a 100644 --- a/include/sqlpp11/core/serialize.h +++ b/include/sqlpp11/core/serialize.h @@ -220,7 +220,7 @@ namespace sqlpp template auto serialize_operand(Context& context, const T& t) -> Context& { - if (requires_parens_t::value) + if (requires_parentheses::value) { context << '('; serialize(context, t); diff --git a/include/sqlpp11/core/type_traits.h b/include/sqlpp11/core/type_traits.h index 14bbf159..904c58bf 100644 --- a/include/sqlpp11/core/type_traits.h +++ b/include/sqlpp11/core/type_traits.h @@ -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 @@ -843,9 +841,8 @@ namespace sqlpp template class Predicate> using has_policy_t = typename has_policy_impl::type; -#warning rename to requires_parentheses template - struct requires_braces : public std::false_type {}; + struct requires_parentheses : public std::false_type {}; struct no_context_t { diff --git a/tests/core/serialize/compare.h b/tests/core/serialize/compare.h index 88b25415..232d4f07 100644 --- a/tests/core/serialize/compare.h +++ b/tests/core/serialize/compare.h @@ -31,16 +31,17 @@ namespace { template - 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 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; \ + } \ + } } diff --git a/tests/core/serialize/operator/CMakeLists.txt b/tests/core/serialize/operator/CMakeLists.txt new file mode 100644 index 00000000..bff33737 --- /dev/null +++ b/tests/core/serialize/operator/CMakeLists.txt @@ -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) + diff --git a/tests/core/serialize/operator/any.cpp b/tests/core/serialize/operator/any.cpp new file mode 100644 index 00000000..89f4be1f --- /dev/null +++ b/tests/core/serialize/operator/any.cpp @@ -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 + +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; +} diff --git a/tests/core/serialize/operator/arithmetic_expression.cpp b/tests/core/serialize/operator/arithmetic_expression.cpp new file mode 100644 index 00000000..f83e26ba --- /dev/null +++ b/tests/core/serialize/operator/arithmetic_expression.cpp @@ -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 + +#include "../../include/test_helpers.h" + +namespace +{ + template + constexpr bool is_same_type() + { + return std::is_same::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 +void test_arithmetic_expressions(Value v) +{ + using ValueType = sqlpp::numeric; + using OptValueType = ::sqlpp::optional; + + auto value = sqlpp::value(v); + auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); + + // Arithmetically combining non-optional values + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, ValueType>(), ""); + + // Arithmetically combining non-optional with optional values + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetically combining optional with non-optional values + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetically combining optional with optional values + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Same with negate. + static_assert(is_same_type, ValueType>(), ""); + static_assert(is_same_type, OptValueType>(), ""); + + // Arithmetic expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + static_assert(sqlpp::has_enabled_as::value, ""); + + // Arithmetic expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Arithmetic expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +void test_modulus_expressions(Value v) +{ + using ValueType = sqlpp::numeric; + using OptValueType = ::sqlpp::optional; + + auto value = sqlpp::value(v); + auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); + + // Modulus combining non-optional values + static_assert(is_same_type, ValueType>(), ""); + + // Modulus combining non-optional with optional values + static_assert(is_same_type, OptValueType>(), ""); + + // Modulus combining optional with non-optional values + static_assert(is_same_type, OptValueType>(), ""); + + // Modulus combining optional with optional values + static_assert(is_same_type, OptValueType>(), ""); + + // Modulus expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Modulus expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Modulus expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +void test_concatenation_expressions(Value v) +{ + using ValueType = sqlpp::text; + using OptValueType = ::sqlpp::optional; + + auto value = sqlpp::value(v); + auto opt_value = sqlpp::value(::sqlpp::make_optional(v)); + + // Concatenating non-optional values + static_assert(is_same_type, ValueType>(), ""); + + // Concatenating non-optional with optional values + static_assert(is_same_type, OptValueType>(), ""); + + // Concatenating optional with non-optional values + static_assert(is_same_type, OptValueType>(), ""); + + // Concatenating optional with optional values + static_assert(is_same_type, OptValueType>(), ""); + + // Modulus expressions enable the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Modulus expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Modulus expressions have their arguments as nodes + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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")); +} diff --git a/tests/core/serialize/operator/as_expression.cpp b/tests/core/serialize/operator/as_expression.cpp new file mode 100644 index 00000000..2075549c --- /dev/null +++ b/tests/core/serialize/operator/as_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +SQLPP_ALIAS_PROVIDER(cheese); + +template +using is_select_column_value_type = std::is_same, ValueType>; + +template +void test_as_expression(Value v) +{ + using ValueType = sqlpp::value_type_of_t; + using OptValueType = ::sqlpp::optional; + + 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::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + + static_assert(is_select_column_value_type::value, ""); + static_assert(is_select_column_value_type::value, ""); + static_assert(is_select_column_value_type::value, ""); + static_assert(is_select_column_value_type::value, ""); + + static_assert(sqlpp::select_column_has_name::value, ""); + static_assert(sqlpp::select_column_has_name::value, ""); + static_assert(sqlpp::select_column_has_name::value, ""); + static_assert(sqlpp::select_column_has_name::value, ""); + + // AS expressions have do not enable the `as` member function. + static_assert(not sqlpp::has_enabled_as::value, ""); + + // AS expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // AS expressions have their arguments as nodes. + using L = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // date + test_as_expression(::sqlpp::chrono::day_point{}); + + // timestamp + test_as_expression(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_as_expression(minute_point{}); + + // time_of_day + test_as_expression(std::chrono::microseconds{}); + +} + diff --git a/tests/core/serialize/operator/assign_expression.cpp b/tests/core/serialize/operator/assign_expression.cpp new file mode 100644 index 00000000..044f4562 --- /dev/null +++ b/tests/core/serialize/operator/assign_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +namespace +{ + auto db = MockDb{}; + + template + using is_bool = std::is_same, sqlpp::boolean>; + + template + using is_maybe_bool = std::is_same, ::sqlpp::optional>; +} + +template +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::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + // Assignments have no name + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + + // Assignment nodes + static_assert(std::is_same, + sqlpp::detail::type_vector>::value, + ""); + static_assert(std::is_same, + sqlpp::detail::type_vector>::value, + ""); + static_assert(std::is_same, + sqlpp::detail::type_vector>::value, + ""); + + // Assign expressions do not have the `as` member function. + static_assert(not sqlpp::has_enabled_as::value, ""); + + // Assign expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Assign expressions have their arguments as nodes. + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // 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; + test_assign_expression(date_time.timePointN, minute_point{}); + + // time_of_day + test_assign_expression(date_time.timeOfDayN, std::chrono::microseconds{}); +} + diff --git a/tests/core/serialize/operator/between_expression.cpp b/tests/core/serialize/operator/between_expression.cpp new file mode 100644 index 00000000..2d33ea03 --- /dev/null +++ b/tests/core/serialize/operator/between_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +namespace +{ + auto db = MockDb{}; + + template + using is_bool = std::is_same, sqlpp::boolean>; + + template + using is_maybe_bool = std::is_same, ::sqlpp::optional>; +} + +template +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::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + // Between expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Between expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Between expressions have their arguments as nodes. + using L = typename std::decay::type; + using M = Value; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // date + test_between_expression(::sqlpp::chrono::day_point{}); + + // timestamp + test_between_expression(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_between_expression(minute_point{}); + + // time_of_day + test_between_expression(std::chrono::microseconds{}); + +} + diff --git a/tests/core/serialize/operator/bit_expression.cpp b/tests/core/serialize/operator/bit_expression.cpp new file mode 100644 index 00000000..470fc9a9 --- /dev/null +++ b/tests/core/serialize/operator/bit_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +namespace +{ + auto db = MockDb{}; + + template + using is_integral = std::is_same, sqlpp::integral>; + + template + using is_maybe_integral = std::is_same, ::sqlpp::optional>; +} + +template +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::value, ""); + static_assert(is_integral> v_not_null)>::value, ""); + static_assert(is_integral::value, ""); + static_assert(is_integral::value, ""); + static_assert(is_integral::value, ""); + + // Compare non-nullable with nullable. + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral> v_maybe_null)>::value, ""); + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + + // Compare nullable with non-nullable. + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral> v_not_null)>::value, ""); + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + + // Compare nullable with nullable. + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral> v_maybe_null)>::value, ""); + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + + // Compare with null. + static_assert(is_integral::value, ""); + static_assert(is_maybe_integral::value, ""); + + // Comparison expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + static_assert(sqlpp::has_enabled_as::value, ""); + + // Comparison expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Comparison expressions have their arguments as nodes. + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +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::value, ""); + static_assert(is_integral> r_not_null)>::value, ""); + + // Compare non-nullable with nullable. + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral> r_maybe_null)>::value, ""); + + // Compare nullable with non-nullable. + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral> r_not_null)>::value, ""); + + // Compare nullable with nullable. + static_assert(is_maybe_integral::value, ""); + static_assert(is_maybe_integral> r_maybe_null)>::value, ""); + + // Comparison expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Comparison expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Comparison expressions have their arguments as nodes. + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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}); +} + diff --git a/tests/core/serialize/operator/case_expression.cpp b/tests/core/serialize/operator/case_expression.cpp new file mode 100644 index 00000000..ff9f8d26 --- /dev/null +++ b/tests/core/serialize/operator/case_expression.cpp @@ -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 + + template + using is_same_type = std::is_same, sqlpp::value_type_of_t>; + +#warning: implement serialize instead of type tests here! +template +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; + using OptValueType = sqlpp::value_type_of_t; + + // Variations of nullable and non-nullable values + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + static_assert(is_same_type::value, ""); + + // Incomplete case expressions have no value. + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + // Case expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // Case expressions enable comparison member functions. + static_assert(sqlpp::has_enabled_comparison::value, ""); + + // Between expressions have their arguments as nodes. + using L = typename std::decay::type; + using M = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // date + test_case_expression(::sqlpp::chrono::day_point{}); + + // timestamp + test_case_expression(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_case_expression(minute_point{}); + + // time_of_day + test_case_expression(std::chrono::microseconds{}); +} + diff --git a/tests/core/serialize/operator/comparison_expression.cpp b/tests/core/serialize/operator/comparison_expression.cpp new file mode 100644 index 00000000..8d33571c --- /dev/null +++ b/tests/core/serialize/operator/comparison_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +namespace +{ + auto db = MockDb{}; + + template + using is_bool = std::is_same, sqlpp::boolean>; + + template + using is_maybe_bool = std::is_same, ::sqlpp::optional>; +} + +template +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::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool= v_not_null)>::value, ""); + static_assert(is_bool v_not_null)>::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + + // Compare non-nullable with nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool= v_maybe_null)>::value, ""); + static_assert(is_maybe_bool v_maybe_null)>::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + + // Compare nullable with non-nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool= v_not_null)>::value, ""); + static_assert(is_maybe_bool v_not_null)>::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + + // Compare nullable with nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool= v_maybe_null)>::value, ""); + static_assert(is_maybe_bool v_maybe_null)>::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + + // Compare with null. + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + + // Comparison expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + static_assert(sqlpp::has_enabled_as::value, ""); + + // Comparison expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Comparison expressions have their arguments as nodes. + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); +} + +template +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::value, ""); + + // Compare non-nullable with nullable. + static_assert(is_maybe_bool::value, ""); + + // Compare nullable with non-nullable. + static_assert(is_maybe_bool::value, ""); + + // Compare nullable with nullable. + static_assert(is_maybe_bool::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{}); + + // date + test_comparison_expression(::sqlpp::chrono::day_point{}); + + // timestamp + test_comparison_expression(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + 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")); + +} + diff --git a/tests/core/serialize/operator/exists_expression.cpp b/tests/core/serialize/operator/exists_expression.cpp new file mode 100644 index 00000000..5159afd8 --- /dev/null +++ b/tests/core/serialize/operator/exists_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +SQLPP_ALIAS_PROVIDER(r_not_null); +SQLPP_ALIAS_PROVIDER(r_maybe_null); + +template +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::boolean>::value, ""); + static_assert(std::is_same, sqlpp::boolean>::value, ""); + + // EXISTS expressions enable `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + + // EXISTS expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // EXISTS expressions have the SELECT as node. + using S = decltype(select(v_not_null)); + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // date + test_exists(::sqlpp::chrono::day_point{}); + + // timestamp + test_exists(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_exists(minute_point{}); + + // time_of_day + test_exists(std::chrono::microseconds{}); +} + diff --git a/tests/core/serialize/operator/in_expression.cpp b/tests/core/serialize/operator/in_expression.cpp new file mode 100644 index 00000000..f2013a0a --- /dev/null +++ b/tests/core/serialize/operator/in_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +namespace +{ + template + using is_bool = std::is_same, sqlpp::boolean>; + + template + using is_maybe_bool = std::is_same, ::sqlpp::optional>; +} + +template +void test_in_expression(Value v) +{ + using OptValue = ::sqlpp::optional; + + 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::value, ""); + static_assert(is_bool{}))>::value, ""); + static_assert(is_bool::value, ""); + + // Compare non-nullable with nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool{}))>::value, ""); + static_assert(is_maybe_bool::value, ""); + + // Compare nullable with non-nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool{}))>::value, ""); + static_assert(is_maybe_bool::value, ""); + + // Compare nullable with nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool{}))>::value, ""); + static_assert(is_maybe_bool::value, ""); + + // IN expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as{}))>::value, ""); + + // IN expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison{}))>::value, ""); + + // IN expressions have their arguments as nodes. + using L = typename std::decay::type; + using R1= Value; + using R2= OptValue; + static_assert(std::is_same{}))>, sqlpp::detail::type_vector>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // date + test_in_expression(::sqlpp::chrono::day_point{}); + + // timestamp + test_in_expression(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_in_expression(minute_point{}); + + // time_of_day + test_in_expression(std::chrono::microseconds{}); +#endif +} + diff --git a/tests/core/serialize/operator/logical_expression.cpp b/tests/core/serialize/operator/logical_expression.cpp new file mode 100644 index 00000000..4c5efa45 --- /dev/null +++ b/tests/core/serialize/operator/logical_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +namespace +{ + template + using is_bool = std::is_same, sqlpp::boolean>; + + template + using is_maybe_bool = std::is_same, ::sqlpp::optional>; +} + +template +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::value, ""); + static_assert(is_bool::value, ""); + + static_assert(is_bool::value, ""); + static_assert(is_bool::value, ""); + + // Combine nullable with non-nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + // Combine non-nullable with nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + // Combine nullable with nullable. + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + static_assert(is_maybe_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + // not. + static_assert(is_bool::value, ""); + static_assert(is_maybe_bool::value, ""); + + // Logical expressions have the `as` member function. + static_assert(sqlpp::has_enabled_as::value, ""); + static_assert(sqlpp::has_enabled_as::value, ""); + + // Logical expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Logical expressions have their arguments as nodes. + using L = typename std::decay::type; + using R = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::value, ""); + static_assert(std::is_same, sqlpp::detail::type_vector>>::value, ""); +} + +int main() +{ + // boolean + test_logical_expression(bool{true}); +} + diff --git a/tests/core/serialize/operator/sort_order_expression.cpp b/tests/core/serialize/operator/sort_order_expression.cpp new file mode 100644 index 00000000..d82d211c --- /dev/null +++ b/tests/core/serialize/operator/sort_order_expression.cpp @@ -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 + +#warning: implement serialize instead of type tests here! +template +void test_as_expression(Value v) +{ + using ValueType = sqlpp::value_type_of_t; + using OptValueType = ::sqlpp::optional; + + 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::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); + + // Sort order expressions have no name. + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + static_assert(not sqlpp::has_name::value, ""); + + // Sort order expression do not enable the `as` member function. + static_assert(not sqlpp::has_enabled_as::value, ""); + + // Sort order expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // Sort order expressions have their arguments as nodes. + using L = typename std::decay::type; + static_assert(std::is_same, sqlpp::detail::type_vector>::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{}); + + // date + test_as_expression(::sqlpp::chrono::day_point{}); + + // timestamp + test_as_expression(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_as_expression(minute_point{}); + + // time_of_day + test_as_expression(std::chrono::microseconds{}); +} + diff --git a/tests/core/types/operator/any.cpp b/tests/core/types/operator/any.cpp index c5a22207..d1d0a67b 100644 --- a/tests/core/types/operator/any.cpp +++ b/tests/core/types/operator/any.cpp @@ -61,6 +61,8 @@ void test_any(Value v) static_assert(std::is_same, sqlpp::detail::type_vector>::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()