From bbe933f943b3171613122ac768987dfa2ca5ffac Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 5 Jul 2015 11:08:13 +0200 Subject: [PATCH 1/2] count is the first auto-aliased function If used in an expression, count does not have an alias. If used as a field in a select, it does have an alias. --- include/sqlpp11/count.h | 27 +++++++++++++---------- include/sqlpp11/detail/copy_tuple_args.h | 28 +++++++++++++++++++----- include/sqlpp11/multi_column.h | 4 ++-- include/sqlpp11/select_column_list.h | 27 ++++++++++++----------- tests/CMakeLists.txt | 26 +++++++++++----------- tests/Select.cpp | 1 + 6 files changed, 68 insertions(+), 45 deletions(-) diff --git a/include/sqlpp11/count.h b/include/sqlpp11/count.h index 7abda19f..c564c03e 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -33,18 +33,8 @@ namespace sqlpp { - template - struct count_t: - public expression_operators, integral>, - public alias_operators> + struct count_alias_t { - using _traits = make_traits; - - using _nodes = detail::type_vector; - using _can_be_null = std::false_type; - - static_assert(is_noop::value or std::is_same::value, "count() used with flag other than 'distinct'"); - struct _alias_t { static constexpr const char _literal[] = "count_"; @@ -57,6 +47,21 @@ namespace sqlpp const T& operator()() const { return count; } }; }; + }; + + template + struct count_t: + public expression_operators, integral>, + public alias_operators> + { + using _traits = make_traits; + + using _nodes = detail::type_vector; + using _can_be_null = std::false_type; + + static_assert(is_noop::value or std::is_same::value, "count() used with flag other than 'distinct'"); + + using _auto_alias_t = count_alias_t; count_t(const Expr expr): _expr(expr) diff --git a/include/sqlpp11/detail/copy_tuple_args.h b/include/sqlpp11/detail/copy_tuple_args.h index 4f6d483a..fe0c9f4a 100644 --- a/include/sqlpp11/detail/copy_tuple_args.h +++ b/include/sqlpp11/detail/copy_tuple_args.h @@ -28,6 +28,7 @@ #define SQLPP_DETAIL_COPY_TUPLE_ARGS_H #include +#include namespace sqlpp { @@ -36,22 +37,37 @@ namespace sqlpp namespace detail { - template - struct as_tuple + template + struct auto_alias_impl { - static std::tuple _(T t) { return std::tuple{ t }; } + using type = T; }; template - struct as_tuple> + struct auto_alias_impl::value>::type> + { + using type = expression_alias_t; + }; + + template + using auto_alias_t = typename detail::auto_alias_impl::type; + + template + struct as_column_tuple + { + static std::tuple> _(T t) { return std::tuple>{ auto_alias_t{t} }; } + }; + + template + struct as_column_tuple> { static typename all_of_t::_column_tuple_t _(all_of_t) { return { }; } }; template - struct as_tuple> + struct as_column_tuple> { - static std::tuple _(std::tuple t) { return t; } + static std::tuple...> _(std::tuple t) { return t; } }; template class Target, typename First, typename T> diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index 7e55cc97..c1a8704e 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -130,14 +130,14 @@ namespace sqlpp template using make_multi_column_t = detail::copy_tuple_args_t::_(std::declval())...))>; + decltype(std::tuple_cat(detail::as_column_tuple::_(std::declval())...))>; } template auto multi_column(Columns... columns) -> detail::make_multi_column_t { - return detail::make_multi_column_t(std::tuple_cat(detail::as_tuple::_(columns)...)); + return detail::make_multi_column_t(std::tuple_cat(detail::as_column_tuple::_(columns)...)); } diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index 3437f078..8389859e 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -188,17 +188,18 @@ namespace sqlpp template void add(NamedExpression namedExpression) { + using named_expression = detail::auto_alias_t; static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column"); - static_assert(is_selectable_t::value, "invalid named expression argument in selected_columns::add()"); - static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "named expression uses tables unknown to this statement in selected_columns::add()"); + static_assert(is_selectable_t::value, "invalid named expression argument in selected_columns::add()"); + static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables::value, "named expression uses tables unknown to this statement in selected_columns::add()"); using column_names = detail::make_type_set_t; - static_assert(not detail::is_element_of::value, "a column of this name is present in the select already"); - using _serialize_check = sqlpp::serialize_check_t; + static_assert(not detail::is_element_of::value, "a column of this name is present in the select already"); + using _serialize_check = sqlpp::serialize_check_t; _serialize_check::_(); using ok = logic::all_t< _is_dynamic::value, - is_selectable_t::value, + is_selectable_t::value, _serialize_check::type::value >; @@ -209,7 +210,7 @@ namespace sqlpp template void _add_impl(NamedExpression namedExpression, const std::true_type&) { - return _data._dynamic_columns.emplace_back(namedExpression); + return _data._dynamic_columns.emplace_back(detail::auto_alias_t{namedExpression}); } template @@ -338,15 +339,15 @@ namespace sqlpp namespace detail { template - auto tuple_merge(Columns... columns) -> decltype(std::tuple_cat(as_tuple::_(columns)...)) + auto column_tuple_merge(Columns... columns) -> decltype(std::tuple_cat(as_column_tuple::_(columns)...)) { - return std::tuple_cat(as_tuple::_(columns)...); + return std::tuple_cat(as_column_tuple::_(columns)...); } template using make_select_column_list_t = copy_tuple_args_t()...))>; + decltype(column_tuple_merge(std::declval()...))>; } @@ -395,9 +396,9 @@ namespace sqlpp } template - static constexpr auto _check_args(T... args) -> decltype(_check_tuple(detail::tuple_merge(args...))) + static constexpr auto _check_args(T... args) -> decltype(_check_tuple(detail::column_tuple_merge(args...))) { - return _check_tuple(detail::tuple_merge(args...)); + return _check_tuple(detail::column_tuple_merge(args...)); } template @@ -412,7 +413,7 @@ namespace sqlpp static_assert(sizeof...(Args), "at least one selectable expression (e.g. a column) required in columns()"); static_assert(decltype(_check_args(args...))::value, "at least one argument is not a selectable expression in columns()"); - return _columns_impl(_check_args(args...), detail::tuple_merge(args...)); + return _columns_impl(_check_args(args...), detail::column_tuple_merge(args...)); } template @@ -422,7 +423,7 @@ namespace sqlpp static_assert(not std::is_same<_database_t, void>::value, "dynamic_columns must not be called in a static statement"); static_assert(decltype(_check_args(args...))::value, "at least one argument is not a selectable expression in columns()"); - return _columns_impl<_database_t>(_check_args(args...), detail::tuple_merge(args...)); + return _columns_impl<_database_t>(_check_args(args...), detail::column_tuple_merge(args...)); } private: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 66ba4a0f..c2022160 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,20 +30,20 @@ target_compile_options(sqlpp11_testing INTERFACE -Wall -Wextra -pedantic) endif () set(test_names - BooleanExpression - CustomQuery - Interpret - Insert - Remove - Update + #BooleanExpression + #CustomQuery + #Interpret + #Insert + #Remove + #Update Select - SelectType - Function - Prepared - Minimalistic - Result - Union - With + #SelectType + #Function + #Prepared + #Minimalistic + #Result + #Union + #With ) create_test_sourcelist(test_sources test_main.cpp ${test_names}) diff --git a/tests/Select.cpp b/tests/Select.cpp index 42fe4393..7eddc76c 100644 --- a/tests/Select.cpp +++ b/tests/Select.cpp @@ -53,6 +53,7 @@ int Select(int, char**) const auto tab_a = f.as(sqlpp::alias::a); getColumn(db, t.alpha); + select(count(t.alpha)); for (const auto& row : db(select(sqlpp::value(false).as(sqlpp::alias::a)))) { From 864bd58effb3370259be7493c4023e7dde8d28f4 Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 5 Jul 2015 11:51:49 +0200 Subject: [PATCH 2/2] More functions are now auto-aliased --- include/sqlpp11/any.h | 13 ----- include/sqlpp11/auto_alias.h | 66 ++++++++++++++++++++++++ include/sqlpp11/avg.h | 25 +++++---- include/sqlpp11/concat.h | 19 ++++--- include/sqlpp11/detail/copy_tuple_args.h | 17 +----- include/sqlpp11/exists.h | 23 +++++---- include/sqlpp11/functions.h | 2 +- include/sqlpp11/in.h | 23 +++++---- include/sqlpp11/is_not_null.h | 19 ++++--- include/sqlpp11/is_null.h | 25 +++++---- include/sqlpp11/max.h | 19 ++++--- include/sqlpp11/min.h | 19 ++++--- include/sqlpp11/not_in.h | 25 +++++---- include/sqlpp11/select_column_list.h | 4 +- include/sqlpp11/some.h | 13 ----- include/sqlpp11/sum.h | 25 +++++---- tests/CMakeLists.txt | 26 +++++----- tests/Function.cpp | 21 ++++---- 18 files changed, 230 insertions(+), 154 deletions(-) create mode 100644 include/sqlpp11/auto_alias.h diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index 8585de1d..23ad6db0 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -39,19 +39,6 @@ namespace sqlpp using _traits = make_traits, tag::is_multi_expression>; using _nodes = detail::type_vector; - - static_assert(is_select_t; + + static_assert(is_select_t; - struct _alias_t - { - static constexpr const char _literal[] = "some_"; - using _name_t = sqlpp::make_char_sequence; - template - struct _member_t - { - T some; - T& operator()() { return some; } - const T& operator()() const { return some; } - }; - }; - some_t(Select select): _select(select) {} diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index b766d2e3..0211706b 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -32,17 +32,8 @@ namespace sqlpp { - template - struct sum_t: - public expression_operators, value_type_of>, - public alias_operators> + struct sum_alias_t { - using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _nodes = detail::type_vector; - - static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); - static_assert(is_numeric_t::value, "sum() requires a numeric expression as argument"); - struct _alias_t { static constexpr const char _literal[] = "sum_"; @@ -55,6 +46,20 @@ namespace sqlpp const T& operator()() const { return sum; } }; }; + }; + + template + struct sum_t: + public expression_operators, value_type_of>, + public alias_operators> + { + using _traits = make_traits, tag::is_expression, tag::is_selectable>; + using _nodes = detail::type_vector; + + static_assert(is_noop::value or std::is_same::value, "sum() used with flag other than 'distinct'"); + static_assert(is_numeric_t::value, "sum() requires a numeric expression as argument"); + + using _auto_alias_t = sum_alias_t; sum_t(Expr expr): _expr(expr) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c2022160..66ba4a0f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,20 +30,20 @@ target_compile_options(sqlpp11_testing INTERFACE -Wall -Wextra -pedantic) endif () set(test_names - #BooleanExpression - #CustomQuery - #Interpret - #Insert - #Remove - #Update + BooleanExpression + CustomQuery + Interpret + Insert + Remove + Update Select - #SelectType - #Function - #Prepared - #Minimalistic - #Result - #Union - #With + SelectType + Function + Prepared + Minimalistic + Result + Union + With ) create_test_sourcelist(test_sources test_main.cpp ${test_names}) diff --git a/tests/Function.cpp b/tests/Function.cpp index ac62a789..1956257a 100644 --- a/tests/Function.cpp +++ b/tests/Function.cpp @@ -25,6 +25,7 @@ #include "Sample.h" #include "MockDb.h" +#include #include #include #include @@ -256,11 +257,11 @@ int Function(int, char**) { using TI = decltype(avg(t.alpha)); using TF = decltype(avg(f.omega)); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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"); @@ -271,15 +272,15 @@ int Function(int, char**) using TI = decltype(count(t.alpha)); using TT = decltype(count(t.beta)); using TF = decltype(count(f.omega)); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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"); @@ -292,15 +293,15 @@ int Function(int, char**) using TI = decltype(max(t.alpha)); using TF = decltype(max(f.omega)); using TT = decltype(max(t.beta)); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); static_assert(not sqlpp::is_numeric_t::value, "type requirement"); static_assert(sqlpp::is_text_t::value, "type requirement"); } @@ -310,7 +311,7 @@ int Function(int, char**) using TI = decltype(min(t.alpha)); using TF = decltype(min(f.omega)); using TT = decltype(min(t.beta)); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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"); @@ -327,7 +328,7 @@ int Function(int, char**) { using TI = decltype(sum(t.alpha)); using TF = decltype(sum(f.omega)); - static_assert(sqlpp::is_selectable_t::value, "type requirement"); + static_assert(sqlpp::has_auto_alias_t::value, "type requirement"); 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");