diff --git a/include/sqlpp11/core/aggregate_function/avg.h b/include/sqlpp11/core/aggregate_function/avg.h index 1b6336d8..620a0981 100644 --- a/include/sqlpp11/core/aggregate_function/avg.h +++ b/include/sqlpp11/core/aggregate_function/avg.h @@ -63,7 +63,12 @@ namespace sqlpp }; template - struct contains_aggregate> : public std::true_type + struct contains_aggregate_function> : public std::true_type + { + }; + + template + struct contains_non_aggregate> : public std::false_type { }; @@ -92,7 +97,7 @@ namespace sqlpp template using check_avg_arg = - ::sqlpp::enable_if_t<(is_numeric::value or is_boolean::value) and not contains_aggregate::value>; + ::sqlpp::enable_if_t<(is_numeric::value or is_boolean::value) and not contains_aggregate_function::value>; template > auto avg(T t) -> avg_t diff --git a/include/sqlpp11/core/aggregate_function/count.h b/include/sqlpp11/core/aggregate_function/count.h index bffbf802..48561929 100644 --- a/include/sqlpp11/core/aggregate_function/count.h +++ b/include/sqlpp11/core/aggregate_function/count.h @@ -63,7 +63,12 @@ namespace sqlpp }; template - struct contains_aggregate> : public std::true_type + struct contains_aggregate_function> : public std::true_type + { + }; + + template + struct contains_non_aggregate> : public std::false_type { }; @@ -92,7 +97,7 @@ namespace sqlpp template using check_count_arg = - ::sqlpp::enable_if_t::value and not contains_aggregate::value>; + ::sqlpp::enable_if_t::value and not contains_aggregate_function::value>; template > auto count(T t) -> count_t diff --git a/include/sqlpp11/core/aggregate_function/max.h b/include/sqlpp11/core/aggregate_function/max.h index 2cd5ad8a..78efaf7a 100644 --- a/include/sqlpp11/core/aggregate_function/max.h +++ b/include/sqlpp11/core/aggregate_function/max.h @@ -62,7 +62,12 @@ namespace sqlpp }; template - struct contains_aggregate> : public std::true_type + struct contains_aggregate_function> : public std::true_type + { + }; + + template + struct contains_non_aggregate> : public std::false_type { }; @@ -91,7 +96,7 @@ namespace sqlpp template using check_max_arg = - ::sqlpp::enable_if_t::value and not contains_aggregate::value>; + ::sqlpp::enable_if_t::value and not contains_aggregate_function::value>; template > auto max(T t) -> max_t diff --git a/include/sqlpp11/core/aggregate_function/min.h b/include/sqlpp11/core/aggregate_function/min.h index 42b36032..b4b274f9 100644 --- a/include/sqlpp11/core/aggregate_function/min.h +++ b/include/sqlpp11/core/aggregate_function/min.h @@ -62,7 +62,12 @@ namespace sqlpp }; template - struct contains_aggregate> : public std::true_type + struct contains_aggregate_function> : public std::true_type + { + }; + + template + struct contains_non_aggregate> : public std::false_type { }; @@ -91,7 +96,7 @@ namespace sqlpp template using check_min_arg = - ::sqlpp::enable_if_t::value and not contains_aggregate::value>; + ::sqlpp::enable_if_t::value and not contains_aggregate_function::value>; template > auto min(T t) -> min_t diff --git a/include/sqlpp11/core/aggregate_function/over.h b/include/sqlpp11/core/aggregate_function/over.h index 0441cfd6..ea3a84e1 100644 --- a/include/sqlpp11/core/aggregate_function/over.h +++ b/include/sqlpp11/core/aggregate_function/over.h @@ -62,7 +62,7 @@ namespace sqlpp struct value_type_of>: public value_type_of {}; template - using check_over_args = ::sqlpp::enable_if_t::value>; + using check_over_args = ::sqlpp::enable_if_t::value>; template auto to_sql_string(Context& context, const over_t& t) -> std::string diff --git a/include/sqlpp11/core/aggregate_function/sum.h b/include/sqlpp11/core/aggregate_function/sum.h index b3fe1122..f08bfb56 100644 --- a/include/sqlpp11/core/aggregate_function/sum.h +++ b/include/sqlpp11/core/aggregate_function/sum.h @@ -62,7 +62,12 @@ namespace sqlpp }; template - struct contains_aggregate> : public std::true_type + struct contains_aggregate_function> : public std::true_type + { + }; + + template + struct contains_non_aggregate> : public std::false_type { }; @@ -92,7 +97,7 @@ namespace sqlpp template using check_sum_arg = - ::sqlpp::enable_if_t<(is_numeric::value or is_boolean::value) and not contains_aggregate::value>; + ::sqlpp::enable_if_t<(is_numeric::value or is_boolean::value) and not contains_aggregate_function::value>; template > auto sum(T t) -> sum_t diff --git a/include/sqlpp11/core/basic/column.h b/include/sqlpp11/core/basic/column.h index 684b638b..ca4a2cdc 100644 --- a/include/sqlpp11/core/basic/column.h +++ b/include/sqlpp11/core/basic/column.h @@ -85,6 +85,9 @@ namespace sqlpp } }; + template + struct contains_non_aggregate> : public std::true_type {}; + template struct value_type_of> { @@ -99,12 +102,6 @@ namespace sqlpp { }; -#warning: Do we need this? - template - struct has_name> : std::true_type - { - }; - template struct required_tables_of> { diff --git a/include/sqlpp11/core/clause/where.h b/include/sqlpp11/core/clause/where.h index 5e3a39e4..a88e75e2 100644 --- a/include/sqlpp11/core/clause/where.h +++ b/include/sqlpp11/core/clause/where.h @@ -119,14 +119,14 @@ namespace sqlpp // using check_where_t = static_combined_check_t< // static_check_t::value...>::value, // assert_where_arg_is_boolean_expression_t>, - // static_check_t::value)...>::value, + // static_check_t::value)...>::value, // assert_where_arg_contains_no_aggregate_t>>; template struct check_where { using type = static_combined_check_t< static_check_t::value, assert_where_arg_is_boolean_expression_t>, - static_check_t::value, + static_check_t::value, assert_where_arg_contains_no_aggregate_t>>; }; diff --git a/include/sqlpp11/core/type_traits/aggregates.h b/include/sqlpp11/core/type_traits/aggregates.h index 0fae846e..c20c1007 100644 --- a/include/sqlpp11/core/type_traits/aggregates.h +++ b/include/sqlpp11/core/type_traits/aggregates.h @@ -32,14 +32,45 @@ namespace sqlpp { + // Finds calls to aggregate functions (avg, count, max, min, sum). template - struct contains_aggregate : public std::integral_constant>::value> + struct contains_aggregate_function : public std::integral_constant>::value> { }; template - struct contains_aggregate> - : public std::integral_constant::value...>::value> + struct contains_aggregate_function> + : public std::integral_constant::value...>::value> + { + }; + + // Finds group_by expressions. + // @GroupByExpressions: type_vector + template + struct contains_aggregate_expressions + : public std::integral_constant, GroupByExpressions>::value> + { + }; + + template + struct contains_aggregate_expressions, GroupByExpressions> + : public std::integral_constant< + bool, + logic::any_t<(GroupByExpressions::template contains::value or + contains_aggregate_expressions::value)...>::value> + { + }; + + // Finds columns. + // Note that explicit values like `value(7)` are compatible with both aggregate and non-aggregate. + template + struct contains_non_aggregate : public std::integral_constant>::value> + { + }; + + template + struct contains_non_aggregate> + : public std::integral_constant::value...>::value> { }; diff --git a/tests/core/types/type_traits/aggregates.cpp b/tests/core/types/type_traits/aggregates.cpp index 376cad8c..66877d66 100644 --- a/tests/core/types/type_traits/aggregates.cpp +++ b/tests/core/types/type_traits/aggregates.cpp @@ -23,63 +23,46 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "MockDb.h" #include "Sample.h" #include -namespace +void test_contains_aggregate_function() { - auto db = MockDb{}; + auto v_not_null = sqlpp::value(17); + +#warning: Need to test contains_aggregate_function - template - using is_same_type = std::is_same, V>; } -template -void test_aggregates(Value v) +void test_contains_aggregate_expression() { - auto v_not_null = sqlpp::value(v); - auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v)); + auto v_not_null = sqlpp::value(17); - using OptFloat = sqlpp::value_type_of_t<::sqlpp::optional>; +#warning: Need to test contains_aggregate_expression -#warning: Need to test contains_aggregate +} + +void test_contains_non_aggregate() +{ + auto v = sqlpp::value(17); + auto col = test::TabFoo{}.id; + + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); + static_assert(not sqlpp::contains_non_aggregate::value, ""); +#warning: lets test some functions, too +#warning: lets test some clauses, too } int main() { - // boolean - test_avg(bool{true}); - - // integral - test_avg(int8_t{7}); - test_avg(int16_t{7}); - test_avg(int32_t{7}); - test_avg(int64_t{7}); - - // unsigned integral - test_avg(uint8_t{7}); - test_avg(uint16_t{7}); - test_avg(uint32_t{7}); - test_avg(uint64_t{7}); - - // floating point - test_avg(float{7.7}); - test_avg(double{7.7}); - -#warning: Should there be avg date time duration? -#if 0 - // date - test_avg(::sqlpp::chrono::day_point{}); - - // timestamp - test_avg(::sqlpp::chrono::microsecond_point{}); - using minute_point = std::chrono::time_point; - test_avg(minute_point{}); - - // time_of_day - test_avg(std::chrono::microseconds{}); -#endif + void test_contains_aggregate_function(); + void test_contains_aggregate_expression(); + void test_contains_non_aggregate(); }