From 6a92f139b7fbe903d0862a729ea44748dffc81a7 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Sat, 27 Jul 2024 19:25:38 +0200 Subject: [PATCH] More tests fixed Make as_expression usable in select only --- include/sqlpp11/dynamic.h | 11 +- include/sqlpp11/enable_as.h | 6 +- include/sqlpp11/enable_comparison.h | 3 + .../{alias_operators.h => enable_join.h} | 51 ++- include/sqlpp11/field_spec.h | 15 +- include/sqlpp11/from.h | 8 +- include/sqlpp11/group_by.h | 6 +- include/sqlpp11/noop.h | 1 + include/sqlpp11/operator/as_expression.h | 28 +- include/sqlpp11/parameterized_verbatim.h | 5 +- include/sqlpp11/select_as.h | 5 +- include/sqlpp11/select_column_list.h | 32 +- include/sqlpp11/select_column_traits.h | 91 ++++++ include/sqlpp11/single_table.h | 8 +- include/sqlpp11/table.h | 39 +-- include/sqlpp11/table_alias.h | 49 +-- include/sqlpp11/trim.h | 11 +- include/sqlpp11/verbatim_table.h | 81 +---- include/sqlpp11/where.h | 9 +- scripts/ddl2cpp | 2 +- tests/core/types/CMakeLists.txt | 7 +- tests/core/types/case_when.cpp | 4 +- tests/core/types/dynamic.cpp | 21 +- tests/core/types/operator/CMakeLists.txt | 44 +++ tests/core/types/{ => operator}/any.cpp | 23 +- .../{ => operator}/arithmetic_expression.cpp | 39 ++- tests/core/types/operator/as_expression.cpp | 122 +++++++ .../{ => operator}/assign_expression.cpp | 14 +- .../{ => operator}/comparison_expression.cpp | 23 +- .../types/{ => operator}/in_expression.cpp | 25 +- .../{ => operator}/logical_expression.cpp | 26 +- tests/core/types/result_row.cpp | 5 +- tests/core/types/select_as.cpp | 14 +- tests/core/types/value.cpp | 13 - tests/core/usage/Sample.h | 2 +- tests/core/usage/Select.cpp | 36 ++- tests/core/usage/SelectType.cpp | 299 +++++------------- 37 files changed, 621 insertions(+), 557 deletions(-) rename include/sqlpp11/{alias_operators.h => enable_join.h} (51%) create mode 100644 include/sqlpp11/select_column_traits.h create mode 100644 tests/core/types/operator/CMakeLists.txt rename tests/core/types/{ => operator}/any.cpp (76%) rename tests/core/types/{ => operator}/arithmetic_expression.cpp (77%) create mode 100644 tests/core/types/operator/as_expression.cpp rename tests/core/types/{ => operator}/assign_expression.cpp (88%) rename tests/core/types/{ => operator}/comparison_expression.cpp (88%) rename tests/core/types/{ => operator}/in_expression.cpp (83%) rename tests/core/types/{ => operator}/logical_expression.cpp (73%) diff --git a/include/sqlpp11/dynamic.h b/include/sqlpp11/dynamic.h index 5763f7f2..8d6c49b6 100644 --- a/include/sqlpp11/dynamic.h +++ b/include/sqlpp11/dynamic.h @@ -27,12 +27,13 @@ */ #include +#include #include namespace sqlpp { template - struct dynamic_t + struct dynamic_t: public enable_as> { using _traits = make_traits, tag::is_multi_expression>; @@ -50,13 +51,7 @@ namespace sqlpp Expr _expr; }; - // No value_type_of defined for dynamic_t, because it is to be used in very specific contexts in which _expr may be - // used depending on the value of _condition. - - template - struct name_tag_of> : public name_tag_of - { - }; + // No value_type_of or name_tag_of defined for dynamic_t, to prevent its usage outside of select columns. template struct nodes_of> : public nodes_of diff --git a/include/sqlpp11/enable_as.h b/include/sqlpp11/enable_as.h index 419f17ce..e3a33de0 100644 --- a/include/sqlpp11/enable_as.h +++ b/include/sqlpp11/enable_as.h @@ -42,10 +42,14 @@ namespace sqlpp public: template - constexpr auto as(const AliasProvider& alias) const + constexpr auto as(const AliasProvider& alias) const -> decltype(::sqlpp::as(this->derived(), alias)) { return ::sqlpp::as(this->derived(), alias); } }; +#warning: columns and tables should also use enable_as with specialized as_expression functions. + template + struct has_enabled_as : public std::is_base_of, T>{}; + } // namespace sqlpp diff --git a/include/sqlpp11/enable_comparison.h b/include/sqlpp11/enable_comparison.h index 5cd8573a..4edfb7c8 100644 --- a/include/sqlpp11/enable_comparison.h +++ b/include/sqlpp11/enable_comparison.h @@ -123,4 +123,7 @@ namespace sqlpp } }; + template + struct has_enabled_comparison : public std::is_base_of, T>{}; + } // namespace sqlpp diff --git a/include/sqlpp11/alias_operators.h b/include/sqlpp11/enable_join.h similarity index 51% rename from include/sqlpp11/alias_operators.h rename to include/sqlpp11/enable_join.h index dc37f6e5..9da33a41 100644 --- a/include/sqlpp11/alias_operators.h +++ b/include/sqlpp11/enable_join.h @@ -1,7 +1,7 @@ #pragma once /* - * Copyright (c) 2013-2015, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -26,17 +26,54 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include +#include namespace sqlpp { - template - struct alias_operators + template + struct enable_join { - template - as_expression as(const alias_provider& /*unused*/) const + constexpr auto derived() const -> const Joinable& { - return {*static_cast(this)}; + return static_cast(*this); + } + + public: + template + auto join(T t) const -> decltype(::sqlpp::join(this->derived(), t)) + { + return ::sqlpp::join(this->derived(), t); + } + + template + auto inner_join(T t) const -> decltype(::sqlpp::inner_join(this->derived(), t)) + { + return ::sqlpp::inner_join(this->derived(), t); + } + + template + auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(this->derived(), t)) + { + return ::sqlpp::left_outer_join(this->derived(), t); + } + + template + auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(this->derived(), t)) + { + return ::sqlpp::right_outer_join(this->derived(), t); + } + + template + auto outer_join(T t) const -> decltype(::sqlpp::outer_join(this->derived(), t)) + { + return ::sqlpp::outer_join(this->derived(), t); + } + + template + auto cross_join(T t) const -> decltype(::sqlpp::cross_join(this->derived(), t)) + { + return ::sqlpp::cross_join(this->derived(), t); } }; } // namespace sqlpp diff --git a/include/sqlpp11/field_spec.h b/include/sqlpp11/field_spec.h index 7fc269b9..3bf3dbe7 100644 --- a/include/sqlpp11/field_spec.h +++ b/include/sqlpp11/field_spec.h @@ -29,7 +29,7 @@ #include #include -#include +#include namespace sqlpp { @@ -76,24 +76,15 @@ namespace sqlpp template struct make_field_spec_impl { - using ValueType = value_type_of_t; + using ValueType = select_column_value_type_of_t; static constexpr bool _depends_on_outer_table = detail::make_intersect_set_t, typename Select::_used_outer_tables>::size::value > 0; using type = field_spec_t< - name_tag_of_t, + select_column_name_tag_of_t, typename std::conditional<_depends_on_outer_table, sqlpp::force_optional_t, ValueType>::type>; }; - - template - struct make_field_spec_impl> - { - using ValueType = force_optional_t>; - - using type = field_spec_t, - ValueType>; - }; } // namespace detail template diff --git a/include/sqlpp11/from.h b/include/sqlpp11/from.h index 633247e1..2cd390c3 100644 --- a/include/sqlpp11/from.h +++ b/include/sqlpp11/from.h @@ -47,7 +47,6 @@ namespace sqlpp struct from_t { using _traits = make_traits; - using _nodes = detail::type_vector; using _data_t = from_data_t
; @@ -66,6 +65,12 @@ namespace sqlpp }; }; + template + struct nodes_of> + { + using type = detail::type_vector
; + }; + SQLPP_PORTABLE_STATIC_ASSERT( assert_from_not_pre_join_t, "from() argument is a pre join, please use an explicit on() condition or unconditionally()"); @@ -94,7 +99,6 @@ namespace sqlpp struct no_from_t { using _traits = make_traits; - using _nodes = detail::type_vector<>; using _data_t = no_data_t; diff --git a/include/sqlpp11/group_by.h b/include/sqlpp11/group_by.h index 7d93d2c8..205bc0dd 100644 --- a/include/sqlpp11/group_by.h +++ b/include/sqlpp11/group_by.h @@ -82,13 +82,13 @@ namespace sqlpp }; }; - SQLPP_PORTABLE_STATIC_ASSERT(assert_group_by_args_are_expressions_t, - "arguments for group_by() must be valid expressions"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_group_by_args_have_values_t, + "all arguments for group_by() must have values"); template struct check_group_by { using type = static_combined_check_t< - static_check_t::value...>::value, assert_group_by_args_are_expressions_t>>; + static_check_t::value...>::value, assert_group_by_args_have_values_t>>; }; template using check_group_by_t = typename check_group_by::type; diff --git a/include/sqlpp11/noop.h b/include/sqlpp11/noop.h index 95e2de7b..b17227a0 100644 --- a/include/sqlpp11/noop.h +++ b/include/sqlpp11/noop.h @@ -33,6 +33,7 @@ namespace sqlpp { struct noop { +#warning: All this should go away using _traits = make_traits; using _nodes = detail::type_vector<>; diff --git a/include/sqlpp11/operator/as_expression.h b/include/sqlpp11/operator/as_expression.h index d30990a2..4099202c 100644 --- a/include/sqlpp11/operator/as_expression.h +++ b/include/sqlpp11/operator/as_expression.h @@ -1,7 +1,7 @@ #pragma once /* -Copyright (c) 2017, Roland Bock +Copyright (c) 2024, Roland Bock All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace sqlpp { +#warning: need type tests template struct as_expression { @@ -55,17 +56,7 @@ namespace sqlpp Expression _expression; }; - template - struct value_type_of> - { - using type = value_type_of_t; - }; - - template - struct name_tag_of> - { - using type = name_tag_of_t; - }; + // No value_type_of or name_tag_of defined for as_expression, to prevent its usage outside of select columns. template struct nodes_of> @@ -73,11 +64,6 @@ namespace sqlpp using type = detail::type_vector; }; - template - struct has_name> : std::true_type - { - }; - template Context& serialize(Context& context, const as_expression& t) { @@ -97,4 +83,12 @@ namespace sqlpp return {std::move(expr)}; } + template + struct dynamic_t; + template > + constexpr auto as(dynamic_t expr, const AliasProvider&) -> as_expression, AliasProvider> + { + return {std::move(expr)}; + } + } // namespace sqlpp diff --git a/include/sqlpp11/parameterized_verbatim.h b/include/sqlpp11/parameterized_verbatim.h index a0b96739..b630108a 100644 --- a/include/sqlpp11/parameterized_verbatim.h +++ b/include/sqlpp11/parameterized_verbatim.h @@ -63,7 +63,10 @@ namespace sqlpp }; template - struct nodes_of> : public nodes_of{}; + struct nodes_of> + { + using type = detail::type_vector; + }; template Context& serialize(Context& context, const parameterized_verbatim_t& t) diff --git a/include/sqlpp11/select_as.h b/include/sqlpp11/select_as.h index e69b0571..4a925e8e 100644 --- a/include/sqlpp11/select_as.h +++ b/include/sqlpp11/select_as.h @@ -28,6 +28,7 @@ #include #include +#include namespace sqlpp { @@ -59,8 +60,8 @@ namespace sqlpp } template - struct select_as_t - : public ColumnSpecs::_alias_t::template _member_t>... + struct select_as_t : public ColumnSpecs::_alias_t::template _member_t>..., + public enable_join> { select_as_t(Select select) : _select(select) { diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index 340ece40..8d3135c0 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -27,12 +27,14 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include @@ -84,7 +86,7 @@ namespace sqlpp template struct select_column_spec_t: public name_tag_base { - using _alias_t = name_tag_of_t; + using _alias_t = select_column_name_tag_of_t; #warning: Need to test this! static constexpr bool _depends_on_outer_table = @@ -92,7 +94,7 @@ namespace sqlpp 0; }; template - struct value_type_of> : public value_type_of {}; + struct value_type_of> : public select_column_value_type_of {}; SQLPP_PORTABLE_STATIC_ASSERT( assert_no_unknown_tables_in_selected_columns_t, @@ -108,7 +110,6 @@ namespace sqlpp struct select_column_list_t { using _traits = typename detail::select_traits::_traits; - using _nodes = detail::type_vector; using _data_t = std::tuple; @@ -215,30 +216,22 @@ namespace sqlpp }; }; template - struct value_type_of> : public value_type_of + struct value_type_of> : public select_column_value_type_of { }; - template - struct value_type_of>> - { - using type = force_optional_t>; - }; template struct name_tag_of> : public name_tag_of { }; - SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable"); + template + struct nodes_of> + { + using type = detail::type_vector; + }; - template - struct check_selected_column : std::integral_constant::value and has_name::value> - { - }; - template - struct check_selected_column> : check_selected_column - { - }; + SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable"); template struct check_selected_tuple; @@ -246,7 +239,7 @@ namespace sqlpp struct check_selected_tuple> { using type = static_combined_check_t< - static_check_t::value...>::value, + static_check_t::value and select_column_has_name::value)...>::value, assert_selected_colums_are_selectable_t>>; }; template @@ -265,7 +258,6 @@ namespace sqlpp struct no_select_column_list_t { using _traits = make_traits; - using _nodes = detail::type_vector<>; struct _alias_t { diff --git a/include/sqlpp11/select_column_traits.h b/include/sqlpp11/select_column_traits.h new file mode 100644 index 00000000..c7063bb8 --- /dev/null +++ b/include/sqlpp11/select_column_traits.h @@ -0,0 +1,91 @@ +#pragma once + +/* + * 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 +#include +#include + +// Select columns require a value type and a name. +// They can be dynamic values and they can be as_expressions. +// These type traits consider `dynamic_t` and `as_expression` + +namespace sqlpp +{ + // Get value type + template + struct select_column_value_type_of : public value_type_of + { + }; + template + using select_column_value_type_of_t = typename select_column_value_type_of::type; + + template + struct select_column_value_type_of> + { + using type = sqlpp::force_optional_t>; + }; + + template + struct select_column_value_type_of> : public select_column_value_type_of + { + }; + + // Get name tag + template + struct select_column_name_tag_of : public name_tag_of + { + }; + + template + using select_column_name_tag_of_t = typename select_column_name_tag_of::type; + + template + struct select_column_name_tag_of> : public select_column_name_tag_of + { + }; + + template + struct select_column_name_tag_of> : public name_tag_of + { + }; + + // Test for value + template + struct select_column_has_value_type + : public std::integral_constant, no_value_t>::value> + { + }; + + // Test for name + template + struct select_column_has_name + : public std::integral_constant, no_name_t>::value> + { + }; + +} // namespace sqlpp diff --git a/include/sqlpp11/single_table.h b/include/sqlpp11/single_table.h index fabd0763..5c0a6ecd 100644 --- a/include/sqlpp11/single_table.h +++ b/include/sqlpp11/single_table.h @@ -55,7 +55,6 @@ namespace sqlpp struct single_table_t { using _traits = make_traits; - using _nodes = detail::type_vector
; #warning: can't we do this with a table_t<> specialization static_assert(is_table
::value, "argument has to be a table"); @@ -81,6 +80,12 @@ namespace sqlpp }; }; + template + struct nodes_of> + { + using type = detail::type_vector
; + }; + SQLPP_PORTABLE_STATIC_ASSERT(assert_update_table_arg_is_table_t, "argument for update() must be a table"); template struct check_update_table @@ -94,7 +99,6 @@ namespace sqlpp struct no_single_table_t { using _traits = make_traits; - using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index d0bdd4bb..06164f5f 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -26,6 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -36,7 +37,7 @@ namespace sqlpp { template - struct table_t : public TableSpec::_table_columns + struct table_t : public TableSpec::_table_columns, public enable_join> { using _traits = make_traits; @@ -51,42 +52,6 @@ namespace sqlpp template using _alias_t = table_alias_t; - template - auto join(T t) const -> decltype(::sqlpp::join(*this, t)) - { - return ::sqlpp::join(*this, t); - } - - template - auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t)) - { - return ::sqlpp::inner_join(*this, t); - } - - template - auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t)) - { - return ::sqlpp::left_outer_join(*this, t); - } - - template - auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t)) - { - return ::sqlpp::right_outer_join(*this, t); - } - - template - auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t)) - { - return ::sqlpp::outer_join(*this, t); - } - - template - auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t)) - { - return ::sqlpp::cross_join(*this, t); - } - template _alias_t as(const AliasProvider& /*unused*/) const { diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index ad013cb8..324de99e 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -26,8 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +#include #include #include #include @@ -37,15 +36,9 @@ namespace sqlpp { template - struct table_alias_t : public TableSpec::_table_columns + struct table_alias_t : public TableSpec::_table_columns, + public enable_join> { -#warning: Need to declare this an alias? - /* - using _traits = make_traits, - tag::is_alias, - tag_if::value>>; - */ - using _nodes = detail::type_vector<>; using _required_ctes = required_ctes_of; using _provided_tables = detail::type_set; @@ -54,42 +47,6 @@ namespace sqlpp #warning: need to inherit? //using _column_tuple_t = std::tuple...>; - - template - auto join(T t) const -> decltype(::sqlpp::join(*this, t)) - { - return ::sqlpp::join(*this, t); - } - - template - auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t)) - { - return ::sqlpp::inner_join(*this, t); - } - - template - auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t)) - { - return ::sqlpp::left_outer_join(*this, t); - } - - template - auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t)) - { - return ::sqlpp::right_outer_join(*this, t); - } - - template - auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t)) - { - return ::sqlpp::outer_join(*this, t); - } - - template - auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t)) - { - return ::sqlpp::cross_join(*this, t); - } }; template diff --git a/include/sqlpp11/trim.h b/include/sqlpp11/trim.h index 47b76c5f..68087b6c 100644 --- a/include/sqlpp11/trim.h +++ b/include/sqlpp11/trim.h @@ -37,8 +37,6 @@ namespace sqlpp { using _traits = make_traits; - using _nodes = detail::type_vector; - trim_t(const Expr expr) : _expr(expr) { } @@ -52,6 +50,15 @@ namespace sqlpp Expr _expr; }; + template + struct value_type_of> : public value_type_of {}; + + template + struct nodes_of> + { + using type = detail::type_vector; + }; + template Context& serialize(Context& context, const trim_t& t) { diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index 6dcb8e60..a6125cbc 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -28,14 +28,13 @@ #include -#include -#include +#include #include namespace sqlpp { template - struct verbatim_table_alias_t + struct verbatim_table_alias_t : public enable_join> { verbatim_table_alias_t(std::string representation) : _representation(std::move(representation)) { @@ -47,43 +46,6 @@ namespace sqlpp verbatim_table_alias_t& operator=(verbatim_table_alias_t&& rhs) = default; ~verbatim_table_alias_t() = default; -#warning: We should have enable_join CRTP - - template - auto join(T t) const -> decltype(::sqlpp::join(*this, t)) - { - return ::sqlpp::join(*this, t); - } - - template - auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t)) - { - return ::sqlpp::inner_join(*this, t); - } - - template - auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t)) - { - return ::sqlpp::left_outer_join(*this, t); - } - - template - auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t)) - { - return ::sqlpp::right_outer_join(*this, t); - } - - template - auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t)) - { - return ::sqlpp::outer_join(*this, t); - } - - template - auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t)) - { - return ::sqlpp::cross_join(*this, t); - } std::string _representation; }; @@ -100,7 +62,7 @@ namespace sqlpp return context; } - struct verbatim_table_t + struct verbatim_table_t: public enable_join { verbatim_table_t(std::string representation) : _representation(std::move(representation)) { @@ -118,43 +80,6 @@ namespace sqlpp return {_representation}; } -#warning: We should have enable_join CRTP - - template - auto join(T t) const -> decltype(::sqlpp::join(*this, t)) - { - return ::sqlpp::join(*this, t); - } - - template - auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t)) - { - return ::sqlpp::inner_join(*this, t); - } - - template - auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t)) - { - return ::sqlpp::left_outer_join(*this, t); - } - - template - auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t)) - { - return ::sqlpp::right_outer_join(*this, t); - } - - template - auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t)) - { - return ::sqlpp::outer_join(*this, t); - } - - template - auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t)) - { - return ::sqlpp::cross_join(*this, t); - } std::string _representation; }; diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index e52bc0d5..7683ba88 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -52,7 +52,6 @@ namespace sqlpp struct where_t { using _traits = make_traits; - using _nodes = detail::type_vector; using _data_t = where_data_t; @@ -73,6 +72,12 @@ namespace sqlpp }; }; + template + struct nodes_of> + { + using type = detail::type_vector; + }; + template <> struct where_data_t { @@ -83,7 +88,6 @@ namespace sqlpp struct where_t { using _traits = make_traits; - using _nodes = detail::type_vector<>; using _data_t = where_data_t; @@ -138,7 +142,6 @@ namespace sqlpp struct no_where_t { using _traits = make_traits; - using _nodes = detail::type_vector<>; using _data_t = no_data_t; diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 208206f5..13f6dcbf 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -691,7 +691,7 @@ def createHeader(): % (sqlTableName, sqlColumnName) ) DataTypeError = True - if columnType == "integer" and column.isUnsigned: + if columnType == "integral" and column.isUnsigned: columnType = "unsigned_" + columnType if columnType == "time_point" and not noTimestampWarning: print( diff --git a/tests/core/types/CMakeLists.txt b/tests/core/types/CMakeLists.txt index 7a20b4a4..73f12ce1 100644 --- a/tests/core/types/CMakeLists.txt +++ b/tests/core/types/CMakeLists.txt @@ -34,15 +34,10 @@ function(test_compile name) endif() endfunction() -test_compile(any) +add_subdirectory(operator) test_compile(aggregate_functions) -test_compile(arithmetic_expression) -test_compile(assign_expression) test_compile(case_when) -test_compile(comparison_expression) test_compile(dynamic) -test_compile(in_expression) -test_compile(logical_expression) test_compile(result_row) test_compile(select_as) test_compile(value) diff --git a/tests/core/types/case_when.cpp b/tests/core/types/case_when.cpp index 7d28c2f9..09a6de29 100644 --- a/tests/core/types/case_when.cpp +++ b/tests/core/types/case_when.cpp @@ -41,8 +41,8 @@ void test_case_when(Value v) 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); + auto v_not_null = sqlpp::value(v); + const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)); // No value types for incomplete clauses static_assert(is_same_type::value, ""); diff --git a/tests/core/types/dynamic.cpp b/tests/core/types/dynamic.cpp index 9a21c939..bd87fd6b 100644 --- a/tests/core/types/dynamic.cpp +++ b/tests/core/types/dynamic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -36,7 +36,7 @@ SQLPP_ALIAS_PROVIDER(r_not_null); SQLPP_ALIAS_PROVIDER(r_maybe_null); template -using is_value_type = std::is_same, ValueType>; +using is_select_column_value_type = std::is_same, ValueType>; template void test_dynamic(Value v) @@ -46,8 +46,8 @@ void test_dynamic(Value v) auto v_not_null= dynamic(true, sqlpp::value(v)); auto v_maybe_null= dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))); - auto v_not_null_alias = dynamic(true, sqlpp::value(v).as(r_not_null)); - auto v_maybe_null_alias = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null)); + auto v_not_null_alias = dynamic(true, sqlpp::value(v)).as(r_not_null); + auto v_maybe_null_alias = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))).as(r_maybe_null); static_assert(not sqlpp::has_value_type::value, ""); static_assert(not sqlpp::has_value_type::value, ""); @@ -59,10 +59,15 @@ void test_dynamic(Value v) static_assert(sqlpp::has_name::value, ""); static_assert(sqlpp::has_name::value, ""); - static_assert(is_value_type, ValueType>::value, ""); - static_assert(is_value_type, OptValueType>::value, ""); - static_assert(is_value_type, ValueType>::value, ""); - static_assert(is_value_type, OptValueType>::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(not sqlpp::select_column_has_name::value, ""); + static_assert(not sqlpp::select_column_has_name::value, ""); + static_assert(sqlpp::select_column_has_name::value, ""); + static_assert(sqlpp::select_column_has_name::value, ""); #warning: test can be aliased #warning: test has comparison operators diff --git a/tests/core/types/operator/CMakeLists.txt b/tests/core/types/operator/CMakeLists.txt new file mode 100644 index 00000000..be038df5 --- /dev/null +++ b/tests/core/types/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(test_compile name) + set(target sqlpp11_${name}) + add_executable(${target} ${name}.cpp) + target_link_libraries(${target} PRIVATE sqlpp11::sqlpp11 sqlpp11_testing) + # conditionally bump to a higher C++ standard to test compatibility + if (SQLPP11_TESTS_CXX_STD) + set_property(TARGET sqlpp11_${name} PROPERTY CXX_STANDARD ${SQLPP11_TESTS_CXX_STD}) + set_property(TARGET sqlpp11_${name} PROPERTY CXX_STANDARD_REQUIRED yes) + set_property(TARGET sqlpp11_${name} PROPERTY CXX_EXTENSIONS no) + endif() +endfunction() + +test_compile(any) +test_compile(arithmetic_expression) +test_compile(as_expression) +test_compile(assign_expression) +test_compile(comparison_expression) +test_compile(in_expression) +test_compile(logical_expression) + diff --git a/tests/core/types/any.cpp b/tests/core/types/operator/any.cpp similarity index 76% rename from tests/core/types/any.cpp rename to tests/core/types/operator/any.cpp index ecafbac5..d622a60b 100644 --- a/tests/core/types/any.cpp +++ b/tests/core/types/operator/any.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -35,13 +35,12 @@ void test_any(Value v) using OptValueType = sqlpp::value_type_of_t>; // Selectable values. - auto v_not_null = sqlpp::value(v).as(r_not_null); + const 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, - ""); + static_assert(not sqlpp::has_value_type::value, ""); + static_assert(not sqlpp::has_value_type::value, ""); // ANY expression can be used in basic comparison expressions, which use remove_any_t to look inside. static_assert( @@ -51,9 +50,17 @@ void test_any(Value v) OptValueType>::value, ""); -#warning: test can be aliased -#warning: test has comparison operators -#warning: test nodes + // ANY expressions do not have `as` member function. + static_assert(not sqlpp::has_enabled_as::value, ""); + + // ANY expressions do not enable comparison member functions. + static_assert(not sqlpp::has_enabled_comparison::value, ""); + + // ANY 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() diff --git a/tests/core/types/arithmetic_expression.cpp b/tests/core/types/operator/arithmetic_expression.cpp similarity index 77% rename from tests/core/types/arithmetic_expression.cpp rename to tests/core/types/operator/arithmetic_expression.cpp index 63a10606..01e4d7be 100644 --- a/tests/core/types/arithmetic_expression.cpp +++ b/tests/core/types/operator/arithmetic_expression.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -80,9 +80,18 @@ void test_arithmetic_expressions(Value v) static_assert(is_same_type, ValueType>(), ""); static_assert(is_same_type, OptValueType>(), ""); -#warning: test can be aliased -#warning: test has comparison operators -#warning: test nodes + // 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 @@ -105,6 +114,17 @@ void test_modulus_expressions(Value v) // 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 @@ -127,6 +147,17 @@ void test_concatenation_expressions(Value v) // 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() diff --git a/tests/core/types/operator/as_expression.cpp b/tests/core/types/operator/as_expression.cpp new file mode 100644 index 00000000..87d2daec --- /dev/null +++ b/tests/core/types/operator/as_expression.cpp @@ -0,0 +1,122 @@ +/* + * 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 + +SQLPP_ALIAS_PROVIDER(r_not_null); +SQLPP_ALIAS_PROVIDER(r_maybe_null); + +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::compat::optional; + + auto v_not_null= sqlpp::value(v); + auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v)); + auto v_dynamic_not_null = dynamic(true, sqlpp::value(v)); + auto v_dynamic_maybe_null = dynamic(true, sqlpp::value(sqlpp::compat::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::compat::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/assign_expression.cpp b/tests/core/types/operator/assign_expression.cpp similarity index 88% rename from tests/core/types/assign_expression.cpp rename to tests/core/types/operator/assign_expression.cpp index 12e9616b..1c9dff2c 100644 --- a/tests/core/types/assign_expression.cpp +++ b/tests/core/types/operator/assign_expression.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -68,8 +68,16 @@ void test_assign_expression(const Column& col, const Value& v) sqlpp::detail::type_vector>::value, ""); -#warning: test can be aliased -#warning: test has comparison operators + // 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 diff --git a/tests/core/types/comparison_expression.cpp b/tests/core/types/operator/comparison_expression.cpp similarity index 88% rename from tests/core/types/comparison_expression.cpp rename to tests/core/types/operator/comparison_expression.cpp index f48dd5b1..949c0aa3 100644 --- a/tests/core/types/comparison_expression.cpp +++ b/tests/core/types/operator/comparison_expression.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -44,7 +44,7 @@ void test_comparison_expression(Value v) auto v_not_null = sqlpp::value(v); auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)); -#warning : Should also implement like, is_null, is_distinct_from as member functions. +#warning : Should also implement between as member functions? // Compare non-nullable with non-nullable. static_assert(is_bool::value, ""); @@ -96,9 +96,18 @@ void test_comparison_expression(Value v) static_assert(is_bool::value, ""); static_assert(is_bool::value, ""); -#warning: test can be aliased -#warning: test has comparison operators -#warning: test nodes + // 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 @@ -118,10 +127,6 @@ void test_like(Value v) // Compare nullable with nullable. static_assert(is_maybe_bool::value, ""); - -#warning: test can be aliased -#warning: test has comparison operators -#warning: test nodes } int main() diff --git a/tests/core/types/in_expression.cpp b/tests/core/types/operator/in_expression.cpp similarity index 83% rename from tests/core/types/in_expression.cpp rename to tests/core/types/operator/in_expression.cpp index 1287598f..197870ed 100644 --- a/tests/core/types/in_expression.cpp +++ b/tests/core/types/operator/in_expression.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -23,14 +23,10 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "MockDb.h" -#include "Sample.h" #include namespace { - auto db = MockDb{}; - template using is_bool = std::is_same, sqlpp::boolean>; @@ -66,16 +62,26 @@ void test_in_expression(Value v) static_assert(is_maybe_bool{}))>::value, ""); static_assert(is_maybe_bool::value, ""); -#warning: test can be aliased -#warning: test has comparison operators -#warning: test nodes + // 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}); @@ -111,5 +117,6 @@ int main() // time_of_day test_in_expression(std::chrono::microseconds{}); +#endif } diff --git a/tests/core/types/logical_expression.cpp b/tests/core/types/operator/logical_expression.cpp similarity index 73% rename from tests/core/types/logical_expression.cpp rename to tests/core/types/operator/logical_expression.cpp index 5a365a2d..79b9744a 100644 --- a/tests/core/types/logical_expression.cpp +++ b/tests/core/types/operator/logical_expression.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -40,28 +40,28 @@ void test_logical_expression(Value v) auto v_not_null= sqlpp::value(v); auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v)); - // Compare non-nullable with non-nullable. + // 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, ""); - // Compare nullable with non-nullable. + // 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, ""); - // Compare non-nullable with nullable. + // 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, ""); - // Compare nullable with nullable. + // Combine nullable with nullable. static_assert(is_maybe_bool::value, ""); static_assert(is_maybe_bool::value, ""); @@ -72,9 +72,19 @@ void test_logical_expression(Value v) static_assert(is_bool::value, ""); static_assert(is_maybe_bool::value, ""); -#warning: test can be aliased -#warning: test has comparison operators -#warning: test nodes + // 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() diff --git a/tests/core/types/result_row.cpp b/tests/core/types/result_row.cpp index 5c828a1b..ab230c8a 100644 --- a/tests/core/types/result_row.cpp +++ b/tests/core/types/result_row.cpp @@ -57,8 +57,8 @@ void test_result_row(Value v) const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); // Optional selectable values. - const auto v_opt_not_null = dynamic(true, sqlpp::value(v).as(r_opt_not_null)); - const auto v_opt_maybe_null = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)).as(r_opt_maybe_null)); + const auto v_opt_not_null = dynamic(true, sqlpp::value(v)).as(r_opt_not_null); + const auto v_opt_maybe_null = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))).as(r_opt_maybe_null); for (const auto& row : db(select(v_not_null, v_maybe_null, v_opt_not_null, v_opt_maybe_null))) { @@ -126,7 +126,6 @@ int main() // as expressions retain the value type of the real thing static_assert(sqlpp::has_name::value, ""); sqlpp::as(bar.intN, bar.textN); - static_assert(std::is_same, sqlpp::value_type_of_t>::value, ""); #if 0 diff --git a/tests/core/types/select_as.cpp b/tests/core/types/select_as.cpp index bad40ec9..c7f5b958 100644 --- a/tests/core/types/select_as.cpp +++ b/tests/core/types/select_as.cpp @@ -32,6 +32,9 @@ namespace template using is_same_type = std::is_same, V>; + template + using is_select_column_same_type = std::is_same, V>; + SQLPP_ALIAS_PROVIDER(always); SQLPP_ALIAS_PROVIDER(sometimes); SQLPP_ALIAS_PROVIDER(column) @@ -76,8 +79,8 @@ void test_select_as(Value v) static_assert(sqlpp::has_name::value, ""); static_assert(sqlpp::has_name::value, ""); - static_assert(is_same_type(), ""); - static_assert(is_same_type(), ""); + static_assert(is_select_column_same_type(), ""); + static_assert(is_select_column_same_type(), ""); // MULTIPLE VALUES @@ -102,8 +105,8 @@ void test_select_as(Value v) static_assert(sqlpp::has_name::value, ""); static_assert(sqlpp::has_name::value, ""); - static_assert(is_same_type(), ""); - static_assert(is_same_type(), ""); + static_assert(is_select_column_same_type(), ""); + static_assert(is_select_column_same_type(), ""); #warning: test can be aliased @@ -117,6 +120,8 @@ int main() // boolean test_select_as(bool{true}); +#warning: reactivate +#if 0 // integral test_select_as(int8_t{7}); test_select_as(int16_t{7}); @@ -152,5 +157,6 @@ int main() // time_of_day test_select_as(std::chrono::microseconds{}); +#endif } diff --git a/tests/core/types/value.cpp b/tests/core/types/value.cpp index 9d7c2918..ac218109 100644 --- a/tests/core/types/value.cpp +++ b/tests/core/types/value.cpp @@ -23,15 +23,8 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "MockDb.h" -#include "Sample.h" #include -namespace -{ - auto db = MockDb{}; -} - SQLPP_ALIAS_PROVIDER(r_not_null); SQLPP_ALIAS_PROVIDER(r_maybe_null); SQLPP_ALIAS_PROVIDER(r_opt_not_null); @@ -48,18 +41,12 @@ void test_value(Value v) auto v_not_null= sqlpp::value(v); auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v)); - auto v_not_null_alias = sqlpp::value(v).as(r_not_null); - auto v_maybe_null_alias = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); static_assert(is_value_type::value, ""); static_assert(is_value_type::value, ""); - static_assert(is_value_type::value, ""); - static_assert(is_value_type::value, ""); static_assert(not sqlpp::can_be_null::value, ""); static_assert(sqlpp::can_be_null::value, ""); - static_assert(not sqlpp::can_be_null::value, ""); - static_assert(sqlpp::can_be_null::value, ""); #warning: test can be aliased #warning: test has comparison operators diff --git a/tests/core/usage/Sample.h b/tests/core/usage/Sample.h index f06807da..6e7225ac 100644 --- a/tests/core/usage/Sample.h +++ b/tests/core/usage/Sample.h @@ -93,7 +93,7 @@ namespace test const T& operator()() const { return uIntN; } }; }; - using value_type = ::sqlpp::compat::optional<::sqlpp::integral>; + using value_type = ::sqlpp::compat::optional<::sqlpp::unsigned_integral>; using has_default = std::true_type; }; struct BlobN : public ::sqlpp::name_tag_base diff --git a/tests/core/usage/Select.cpp b/tests/core/usage/Select.cpp index 8fecd95a..ac166b79 100644 --- a/tests/core/usage/Select.cpp +++ b/tests/core/usage/Select.cpp @@ -52,7 +52,11 @@ void print_row(Row const& row) std::cout << a << ", " << b << std::endl; } -SQLPP_ALIAS_PROVIDER(cheese) +SQLPP_ALIAS_PROVIDER(param2); +SQLPP_ALIAS_PROVIDER(cheese); +SQLPP_ALIAS_PROVIDER(average); +SQLPP_ALIAS_PROVIDER(N); + int Select(int, char*[]) { @@ -63,11 +67,11 @@ int Select(int, char*[]) const auto t = test::TabBar{}; const auto tab_a = f.as(sqlpp::alias::a); - select(count(t.id)); - select(sqlpp::count(1)); - select(count(sqlpp::value(1))); + select(count(t.id).as(N)); + select(sqlpp::count(1).as(N)); + select(count(sqlpp::value(1)).as(N)); - std::cerr << serialize(select(sqlpp::value(false).as(sqlpp::alias::a)), printer).str() << std::endl; + std::cerr << serialize(printer, select(sqlpp::value(false).as(sqlpp::alias::a))).str() << std::endl; for (const auto& row : db(select(sqlpp::value(false).as(sqlpp::alias::a)))) { std::cout << row.a << std::endl; @@ -109,14 +113,14 @@ int Select(int, char*[]) std::cout << row.id << std::endl; } - for (const auto& row : db(select(sqlpp::count(1), avg(t.id)).from(t).unconditionally())) + for (const auto& row : db(select(sqlpp::count(1).as(N), avg(t.id).as(average)).from(t).unconditionally())) { - std::cout << row.count << std::endl; + std::cout << row.N << std::endl; } - for (const auto& row : db(select(count(t.id), avg(t.id)).from(t).where(t.id == 0))) + for (const auto& row : db(select(count(t.id).as(N), avg(t.id).as(average)).from(t).where(t.id == 0))) { - std::cout << row.count << std::endl; + std::cout << row.N << std::endl; } auto stat = sqlpp::select() @@ -130,7 +134,7 @@ int Select(int, char*[]) .offset(19u) .limit(7u); printer.reset(); - std::cerr << serialize(stat, printer).str() << std::endl; + std::cerr << serialize(printer, stat).str() << std::endl; auto s = sqlpp::select() .columns(t.id) @@ -150,12 +154,12 @@ int Select(int, char*[]) } printer.reset(); - std::cerr << serialize(s, printer).str() << std::endl; + std::cerr << serialize(printer, s).str() << std::endl; select(sqlpp::value(7).as(t.id)); for (const auto& row : - db(select(sqlpp::case_when(true).then(t.textN).else_(sqlpp::null).as(t.textN)).from(t).unconditionally())) + db(select(sqlpp::case_when(true).then(t.textN).else_(sqlpp::compat::nullopt).as(t.textN)).from(t).unconditionally())) { std::cerr << row.textN << std::endl; } @@ -182,16 +186,16 @@ int Select(int, char*[]) } for (const auto& row : - db(select(f.doubleN, select(count(t.id)).from(t).unconditionally().as(cheese)).from(f).unconditionally())) + db(select(f.doubleN, select(count(t.id).as(N)).from(t).unconditionally().as(cheese)).from(f).unconditionally())) { std::cout << row.doubleN << " " << row.cheese << std::endl; } // checking #584 - auto abs = db.prepare(select(t.alpha).from(t).where(sqlpp::parameterized_verbatim( - "ABS(field1 -", sqlpp::parameter(t.alpha), ")") <= + auto abs = db.prepare(select(t.id).from(t).where(sqlpp::parameterized_verbatim( + "ABS(field1 -", sqlpp::parameter(t.id), ")") <= sqlpp::parameter(sqlpp::unsigned_integral(), param2))); - abs.params.alpha = 7; + abs.params.id = 7; abs.params.param2 = 7; return 0; diff --git a/tests/core/usage/SelectType.cpp b/tests/core/usage/SelectType.cpp index ecb56ca3..fa4d8cfa 100644 --- a/tests/core/usage/SelectType.cpp +++ b/tests/core/usage/SelectType.cpp @@ -25,7 +25,6 @@ #include "MockDb.h" #include "Sample.h" -#include "is_regular.h" #include #include #include @@ -53,175 +52,85 @@ int SelectType(int, char*[]) // Test a table { using T = typename std::decay::type; - static_assert(not sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(not sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(not sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_integral::value, "type requirement"); + static_assert(not sqlpp::is_floating_point::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(sqlpp::is_table::value, "type requirement"); } // Test an alias of table { using T = decltype(t.as(alias::a)); - static_assert(not sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(not sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_alias_t::value, "type requirement"); - static_assert(sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(not sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_integral::value, "type requirement"); + static_assert(not sqlpp::is_floating_point::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(sqlpp::is_table::value, "type requirement"); } // Test an integral column of an alias of table { using T = decltype(t.as(alias::a).id); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(sqlpp::is_integral::value, "type requirement"); + static_assert(not sqlpp::is_floating_point::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test an integral table column { using T = decltype(t.id); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_unsigned_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(sqlpp::is_integral::value, "type requirement"); + static_assert(not sqlpp::is_unsigned_integral::value, "type requirement"); + static_assert(not sqlpp::is_floating_point::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test an unsigned integral table column { using T = decltype(f.uIntN); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_integral_t::value, "type requirement"); - static_assert(sqlpp::is_unsigned_integral_t::value, "type requirement"); - static_assert(not sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); - // subtraction on unsigned makes it signed - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - // any operation on float makes it float - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - // signed operation on unsigned makes it signed - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); - static_assert(sqlpp::is_floating_point_t>::value, - "type requirement"); - static_assert(sqlpp::is_integral_t>::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_integral::value, "type requirement"); + static_assert(sqlpp::is_unsigned_integral::value, "type requirement"); + static_assert(not sqlpp::is_floating_point::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test a floating point table column { using T = decltype(f.doubleN); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_integral_t::value, "type requirement"); - static_assert(sqlpp::is_floating_point_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_integral::value, "type requirement"); + static_assert(sqlpp::is_floating_point::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test a an alias of a numeric table column { using T = decltype(t.id.as(alias::a)); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test a select of a single column without a from { using T = decltype(select(t.id)); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test a select of a single numeric table column @@ -229,97 +138,55 @@ int SelectType(int, char*[]) using T = decltype(select(t.id).from(t)); // static_assert(sqlpp::is_select_column_list_t::value, "Must not be noop"); // static_assert(sqlpp::is_from_t::value, "Must not be noop"); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test a select of an alias of a single numeric table column { using T = decltype(select(t.id.as(alias::a)).from(t)); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test an alias of a select of a single numeric table column { using T = decltype(select(t.id).from(t).as(alias::b)); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "red to not be boolean"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_alias_t::value, "type requirement"); - static_assert(sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "red to not be boolean"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(sqlpp::is_table::value, "type requirement"); } // Test the column of an alias of a select of an alias of a single numeric table column { using T = decltype(select(t.id.as(alias::a)).from(t).as(alias::b)); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(not sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(not sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(sqlpp::is_alias_t::value, "type requirement"); - static_assert(sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(sqlpp::is_table::value, "type requirement"); } // Test the column of an alias of a select of a single numeric table column { using T = decltype(select(t.id).from(t).as(alias::b).id); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test an alias of a select of an alias of a single numeric table column { using T = decltype(select(t.id.as(alias::a)).from(t).as(alias::b).a); - static_assert(sqlpp::is_numeric_t::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "type requirement"); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); - static_assert(not sqlpp::require_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_insert_t::value, "type requirement"); - static_assert(sqlpp::must_not_update_t::value, "type requirement"); - static_assert(not sqlpp::is_boolean_t::value, "type requirement"); - static_assert(not sqlpp::is_text_t::value, "type requirement"); - static_assert(not sqlpp::is_alias_t::value, "type requirement"); - static_assert(not sqlpp::is_table_t::value, "type requirement"); - static_assert(sqlpp::is_regular::value, "type requirement"); + static_assert(sqlpp::is_numeric::value, "type requirement"); + static_assert(not sqlpp::is_boolean::value, "type requirement"); + static_assert(not sqlpp::is_text::value, "type requirement"); + static_assert(not sqlpp::is_table::value, "type requirement"); } // Test that all_of(tab) is expanded in select @@ -362,17 +229,16 @@ int SelectType(int, char*[]) s.limit.set(30u); s.limit.set(3u); std::cerr << "------------------------\n"; - serialize(s, printer).str(); + serialize(printer, s).str(); std::cerr << "------------------------\n"; using T = decltype(s); - static_assert(sqlpp::is_regular::value, "type requirement"); } // Test that select can be called with zero columns if it is used with dynamic columns. { auto s = dynamic_select(db).dynamic_columns(); s.selected_columns.add(without_table_check(t.id)); - serialize(s, printer).str(); + serialize(printer, s).str(); } { @@ -385,33 +251,24 @@ int SelectType(int, char*[]) // Test that verbatim_table compiles { auto s = select(t.id).from(sqlpp::verbatim_table("my_unknown_table")); - serialize(s, printer).str(); + serialize(printer, s).str(); } static_assert(sqlpp::is_select_flag_t::value, "sqlpp::all has to be a select_flag"); - using T = sqlpp::wrap_operand::type; - static_assert(sqlpp::is_regular::value, "type requirement"); - static_assert(sqlpp::is_expression_t::value, "T has to be an expression"); - static_assert(sqlpp::is_numeric_t::value, "T has to be numeric"); - static_assert(sqlpp::is_numeric_t::value, "TabBar.id has to be a numeric"); + static_assert(sqlpp::is_numeric::value, "TabBar.id has to be a numeric"); ((t.id + 7) + 4).asc(); - static_assert(sqlpp::is_boolean_t::value, + static_assert(sqlpp::is_boolean::value, "Comparison expression have to be boolean"); !t.boolNn; - serialize(t.textN < "kaesekuchen", printer).str(); - serialize(t.textN + "hallenhalma", printer).str(); - static_assert(sqlpp::must_not_insert_t::value, "id must not be inserted"); - serialize(t.id, printer).str(); + serialize(printer, t.textN < "kaesekuchen").str(); + serialize(printer, t.textN + "hallenhalma").str(); + serialize(printer, t.id).str(); std::cerr << "\n" << sizeof(test::TabBar) << std::endl; - static_assert(sqlpp::is_selectable_t::value, "id should be a named expression"); - static_assert(sqlpp::is_selectable_t::value, - "an alias of id should be a named expression"); - static_assert(sqlpp::is_alias_t::value, "an alias of id should be an alias"); auto l = t.as(alias::left); auto r = select(t.boolNn.as(alias::a)).from(t).where(t.boolNn == true).as(alias::right); - static_assert(sqlpp::is_boolean_t::value, "select(bool) has to be a bool"); - static_assert(sqlpp::is_boolean_t::value, "select(bool) has to be a bool"); + static_assert(sqlpp::is_boolean::value, "select(bool) has to be a bool"); + static_assert(sqlpp::is_boolean::value, "select(bool) has to be a bool"); auto s1 = sqlpp::select() .flags(sqlpp::distinct, sqlpp::straight_join) .columns(l.boolNn, r.a)