From 25200ba4cbfb5aae31e7b378be8b0630a0e534b2 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Wed, 17 Jul 2024 07:43:19 +0200 Subject: [PATCH] (Only) allow comparison with ANY and introduce BETWEEN --- include/sqlpp11/alias_provider.h | 26 ++-- include/sqlpp11/column.h | 1 + include/sqlpp11/functions.h | 2 - include/sqlpp11/operator.h | 2 + include/sqlpp11/{ => operator}/any.h | 19 ++- include/sqlpp11/operator/between_expression.h | 143 ++++++++++++++++++ .../sqlpp11/operator/comparison_expression.h | 17 ++- include/sqlpp11/parameter.h | 2 +- include/sqlpp11/some.h | 76 ---------- include/sqlpp11/type_traits.h | 13 +- include/sqlpp11/value.h | 1 + tests/core/types/CMakeLists.txt | 1 + tests/core/types/any.cpp | 96 ++++++++++++ 13 files changed, 284 insertions(+), 115 deletions(-) rename include/sqlpp11/{ => operator}/any.h (85%) create mode 100644 include/sqlpp11/operator/between_expression.h delete mode 100644 include/sqlpp11/some.h create mode 100644 tests/core/types/any.cpp diff --git a/include/sqlpp11/alias_provider.h b/include/sqlpp11/alias_provider.h index d3e2535f..4aab041f 100644 --- a/include/sqlpp11/alias_provider.h +++ b/include/sqlpp11/alias_provider.h @@ -26,11 +26,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include +namespace sqlpp +{ + struct name_tag + { + }; +} + #define SQLPP_ALIAS_PROVIDER(name) \ - struct name##_t \ + struct name##_t : public sqlpp::name_tag \ { \ struct _alias_t \ { \ @@ -54,7 +60,7 @@ constexpr name##_t name = {}; #define SQLPP_QUOTED_ALIAS_PROVIDER(name) \ - struct name##_t \ + struct name##_t : public sqlpp::name_tag \ { \ struct _alias_t \ { \ @@ -79,20 +85,6 @@ namespace sqlpp { - template - struct is_alias_provider_t - { - static constexpr bool value = false; - }; - - template - struct is_alias_provider_t< - T, - typename std::enable_if>::value, void>::type> - { - static constexpr bool value = true; - }; - namespace alias { SQLPP_ALIAS_PROVIDER(a) diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index a0cf4e7b..63fdab93 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -71,6 +71,7 @@ namespace sqlpp return _table{}; } +#warning: Let's do if_(condition, expression) -> if_t, which can be used exclusively in SELECT, AND, OR, JOIN sqlpp::compat::optional if_(bool condition) const { return condition ? sqlpp::compat::make_optional(*this) : sqlpp::compat::nullopt; diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index a50d9f4e..5def9299 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include // Csaba Csoma suggests: unsafe_sql instead of verbatim #include diff --git a/include/sqlpp11/operator.h b/include/sqlpp11/operator.h index 78e9947e..f4812989 100644 --- a/include/sqlpp11/operator.h +++ b/include/sqlpp11/operator.h @@ -36,8 +36,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include // comparison +#include #include #include +#include // arithmetic #include diff --git a/include/sqlpp11/any.h b/include/sqlpp11/operator/any.h similarity index 85% rename from include/sqlpp11/any.h rename to include/sqlpp11/operator/any.h index 147d9fc1..762f1de7 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/operator/any.h @@ -51,11 +51,23 @@ namespace sqlpp Select _select; }; - template - struct value_type_of> : value_type_of& t, Context& context) { @@ -64,9 +76,8 @@ namespace sqlpp return context; } -#warning: Need tests template - using check_any_args = std::enable_if_t::value and has_value_type; - - some_t(Select select) : _select(select) - { - } - - some_t(const some_t&) = default; - some_t(some_t&&) = default; - some_t& operator=(const some_t&) = default; - some_t& operator=(some_t&&) = default; - ~some_t() = default; - - Select _select; - }; - - template - struct value_type_of> : value_type_of& t, Context& context) - { - context << "SOME"; - serialize_operand(t._select, context); - return context; - } - -#warning : Need tests - template - using check_some_args = std::enable_if_t::value>; - - template >> - auto some(statement_t t) -> some_t> - { - return {std::move(t)}; - } -} // namespace sqlpp diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 808df0eb..b4a5df1a 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -420,7 +420,6 @@ namespace sqlpp SQLPP_VALUE_TRAIT_GENERATOR(is_sql_null) SQLPP_VALUE_TRAIT_GENERATOR(is_value_type) - SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value) SQLPP_VALUE_TRAIT_GENERATOR(is_selectable) SQLPP_VALUE_TRAIT_GENERATOR(is_expression) SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression) @@ -481,9 +480,6 @@ namespace sqlpp using is_database = typename std::conditional::value, std::false_type, std::true_type>::type; - template - using cpp_value_type_of_t = typename value_type_of_t::_cpp_value_type; - namespace detail { template @@ -666,14 +662,15 @@ namespace sqlpp template using parameters_of = typename detail::parameters_of_impl::type; - template - using alias_of = typename T::_alias_t; - template using name_of = typename T::_alias_t::_name_t; + // Used by SQLPP_ALIAS_PROVIDER. + struct name_tag; + + // Override this for other classes like columns or tables. template - struct has_name : public std::false_type {}; + struct has_name : public std::integral_constant::value> {}; template struct make_traits diff --git a/include/sqlpp11/value.h b/include/sqlpp11/value.h index aece9054..f74eea04 100644 --- a/include/sqlpp11/value.h +++ b/include/sqlpp11/value.h @@ -26,6 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include diff --git a/tests/core/types/CMakeLists.txt b/tests/core/types/CMakeLists.txt index a4f431ad..d4da25f8 100644 --- a/tests/core/types/CMakeLists.txt +++ b/tests/core/types/CMakeLists.txt @@ -34,6 +34,7 @@ function(test_compile name) endif() endfunction() +test_compile(any) test_compile(aggregate_functions) test_compile(comparison_expression) test_compile(in_expression) diff --git a/tests/core/types/any.cpp b/tests/core/types/any.cpp new file mode 100644 index 00000000..72dafbe2 --- /dev/null +++ b/tests/core/types/any.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016-2016, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +SQLPP_ALIAS_PROVIDER(r_not_null); +SQLPP_ALIAS_PROVIDER(r_maybe_null); + +template +void test_any(Value v) +{ + using ValueType = sqlpp::value_type_of_t; + using OptValueType = sqlpp::value_type_of_t>; + + // Selectable values. + auto v_not_null = sqlpp::value(v).as(r_not_null); + const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); + + // ANY expression are not to be in most expressions and therefore have no value defined. + static_assert(std::is_same, sqlpp::no_value_t>::value, ""); + static_assert(std::is_same, sqlpp::no_value_t>::value, + ""); + + // ANY expression can be used in basic comparison expressions, which use remove_any_t to look inside. + static_assert( + std::is_same>, ValueType>::value, + ""); + static_assert(std::is_same>, + OptValueType>::value, + ""); +} + +int main() +{ + // boolean + test_any(bool{true}); + + // integral + test_any(int8_t{7}); + test_any(int16_t{7}); + test_any(int32_t{7}); + test_any(int64_t{7}); + + // unsigned integral + test_any(uint8_t{7}); + test_any(uint16_t{7}); + test_any(uint32_t{7}); + test_any(uint64_t{7}); + + // floating point + test_any(float{7.7}); + test_any(double{7.7}); + + // text + test_any('7'); + test_any("seven"); + test_any(std::string("seven")); + test_any(sqlpp::compat::string_view("seven")); + + // blob + test_any(std::vector{}); + + // date + test_any(::sqlpp::chrono::day_point{}); + + // timestamp + test_any(::sqlpp::chrono::microsecond_point{}); + using minute_point = std::chrono::time_point; + test_any(minute_point{}); + + // time_of_day + test_any(std::chrono::microseconds{}); +} +