From a7ee6e5d3b1d099372e607368ee57dae18a51ef1 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Sat, 3 Aug 2024 08:31:16 +0200 Subject: [PATCH] More tests --- include/sqlpp11/core/basic/value.h | 18 +-- .../sqlpp11/core/operator/enable_comparison.h | 1 + include/sqlpp11/core/query/dynamic.h | 7 ++ include/sqlpp11/postgresql/on_conflict.h | 1 + tests/core/types/operator/CMakeLists.txt | 2 + tests/core/types/operator/as_expression.cpp | 5 - .../core/types/operator/exists_expression.cpp | 96 +++++++++++++++ .../types/operator/sort_order_expression.cpp | 112 ++++++++++++++++++ 8 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 tests/core/types/operator/exists_expression.cpp create mode 100644 tests/core/types/operator/sort_order_expression.cpp diff --git a/include/sqlpp11/core/basic/value.h b/include/sqlpp11/core/basic/value.h index 7ed5153a..f528e362 100644 --- a/include/sqlpp11/core/basic/value.h +++ b/include/sqlpp11/core/basic/value.h @@ -26,19 +26,23 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include +#include #include namespace sqlpp { template - struct value_t + struct value_t: + public enable_as>, + public enable_comparison> { - template - as_expression as(const alias_provider& /*unused*/) const - { - return {*this}; - } + value_t(T t): _value(std::move(t)) {} + value_t(const value_t&) = default; + value_t(value_t&&) = default; + value_t& operator=(const value_t&) = default; + value_t& operator=(value_t&&) = default; + ~value_t() = default; T _value; }; diff --git a/include/sqlpp11/core/operator/enable_comparison.h b/include/sqlpp11/core/operator/enable_comparison.h index 2f83cd09..470f6992 100644 --- a/include/sqlpp11/core/operator/enable_comparison.h +++ b/include/sqlpp11/core/operator/enable_comparison.h @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace sqlpp { // To be used as CRTP base for expressions that should offer the comparison member functions. + // This also enables sort order member functions template class enable_comparison { diff --git a/include/sqlpp11/core/query/dynamic.h b/include/sqlpp11/core/query/dynamic.h index 6a724e48..b2f9f8bb 100644 --- a/include/sqlpp11/core/query/dynamic.h +++ b/include/sqlpp11/core/query/dynamic.h @@ -27,6 +27,7 @@ */ #include +#include #include #include @@ -95,4 +96,10 @@ namespace sqlpp { return {condition, std::move(t)}; } + + template > + auto dynamic(bool condition, sort_order_expression t) -> dynamic_t> + { + return {condition, std::move(t)}; + } } // namespace sqlpp diff --git a/include/sqlpp11/postgresql/on_conflict.h b/include/sqlpp11/postgresql/on_conflict.h index d9f8c482..92a00df5 100644 --- a/include/sqlpp11/postgresql/on_conflict.h +++ b/include/sqlpp11/postgresql/on_conflict.h @@ -178,6 +178,7 @@ namespace sqlpp return {static_cast&>(*this), on_conflict_data_t{no_data_t{}}}; } +#warning: Allow for more than one column, see #586 template auto on_conflict(ConflictTarget column) const -> _new_statement_t> { diff --git a/tests/core/types/operator/CMakeLists.txt b/tests/core/types/operator/CMakeLists.txt index 69375f45..ff1c1a34 100644 --- a/tests/core/types/operator/CMakeLists.txt +++ b/tests/core/types/operator/CMakeLists.txt @@ -42,6 +42,8 @@ test_compile(between_expression) test_compile(bit_expression) test_compile(case_expression) test_compile(comparison_expression) +test_compile(exists_expression) test_compile(in_expression) test_compile(logical_expression) +test_compile(sort_order_expression) diff --git a/tests/core/types/operator/as_expression.cpp b/tests/core/types/operator/as_expression.cpp index 35892558..9a1ad3a7 100644 --- a/tests/core/types/operator/as_expression.cpp +++ b/tests/core/types/operator/as_expression.cpp @@ -23,13 +23,8 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "MockDb.h" -#include "Sample.h" #include -SQLPP_ALIAS_PROVIDER(r_not_null); -SQLPP_ALIAS_PROVIDER(r_maybe_null); - SQLPP_ALIAS_PROVIDER(cheese); template diff --git a/tests/core/types/operator/exists_expression.cpp b/tests/core/types/operator/exists_expression.cpp new file mode 100644 index 00000000..374ce417 --- /dev/null +++ b/tests/core/types/operator/exists_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 + +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/types/operator/sort_order_expression.cpp b/tests/core/types/operator/sort_order_expression.cpp new file mode 100644 index 00000000..4786b56a --- /dev/null +++ b/tests/core/types/operator/sort_order_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 +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{}); +} +