diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index 5f565ea1..013d2e6f 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -36,7 +36,7 @@ namespace sqlpp struct expression_alias_t { using _traits = make_traits, tag::is_selectable, tag::is_alias>; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(is_expression_t::value, "invalid argument for an expression alias"); static_assert(not is_alias_t::value, "cannot create an alias of an alias"); diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index a180835f..8585de1d 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -37,7 +37,7 @@ namespace sqlpp struct any_t { using _traits = make_traits, tag::is_multi_expression>; - using _recursive_traits = make_recursive_traits; struct _alias_t { diff --git a/include/sqlpp11/assignment.h b/include/sqlpp11/assignment.h index 2677bd00..4c405d6b 100644 --- a/include/sqlpp11/assignment.h +++ b/include/sqlpp11/assignment.h @@ -41,7 +41,7 @@ namespace sqlpp struct assignment_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _lhs_t = Lhs; using _rhs_t = rhs_wrap_t, trivial_value_is_null_t<_lhs_t>::value>; diff --git a/include/sqlpp11/avg.h b/include/sqlpp11/avg.h index d7827abd..d332cf33 100644 --- a/include/sqlpp11/avg.h +++ b/include/sqlpp11/avg.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(is_noop::value or std::is_same::value, "avg() used with flag other than 'distinct'"); static_assert(is_numeric_t::value, "avg() requires a value expression as argument"); diff --git a/include/sqlpp11/boolean_expression.h b/include/sqlpp11/boolean_expression.h index f60a610b..73ee01ff 100644 --- a/include/sqlpp11/boolean_expression.h +++ b/include/sqlpp11/boolean_expression.h @@ -36,7 +36,7 @@ namespace sqlpp struct boolean_expression_t: public expression_operators, boolean> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; template boolean_expression_t(Expr expr): diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index 08d1a0f7..8a6911bc 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -52,19 +52,9 @@ namespace sqlpp using _tags = detail::make_joined_set_t, typename ColumnSpec::_traits::_tags>; }; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = typename std::conditional::value, - detail::type_set, - detail::type_set<>>::type; - }; + using _nodes = detail::type_vector<>; + using _required_tables = detail::type_set
; + using _can_be_null = column_spec_can_be_null_t; using _spec_t = ColumnSpec; using _table = Table; diff --git a/include/sqlpp11/concat.h b/include/sqlpp11/concat.h index 57f113dd..bc0ac76b 100644 --- a/include/sqlpp11/concat.h +++ b/include/sqlpp11/concat.h @@ -42,7 +42,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); static_assert(logic::all_t::value, is_text_t::value...>::value, "at least one non-text argument detected in concat()"); diff --git a/include/sqlpp11/count.h b/include/sqlpp11/count.h index ceff0393..7abda19f 100644 --- a/include/sqlpp11/count.h +++ b/include/sqlpp11/count.h @@ -39,19 +39,9 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = required_ctes_of; - using _provided_ctes = detail::type_set<>; - using _required_tables = required_tables_of; - using _provided_tables = provided_tables_of; - using _provided_outer_tables = provided_outer_tables_of; - using _extra_tables = extra_tables_of; - using _parameters = parameters_of; - using _tags = detail::make_difference_set_t, recursive_tags_of>, - detail::type_set>; - }; + 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'"); @@ -108,6 +98,7 @@ namespace sqlpp template auto count(T t) -> count_t> { + static_assert(not contains_aggregate_function_t>::value, "count() cannot be used on an aggregate function"); static_assert(is_expression_t>::value, "count() requires an expression as argument"); return { t }; } @@ -115,6 +106,7 @@ namespace sqlpp template auto count(const distinct_t&, T t) -> count_t> { + static_assert(not contains_aggregate_function_t>::value, "count() cannot be used on an aggregate function"); static_assert(is_expression_t>::value, "count() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/cte.h b/include/sqlpp11/cte.h index c37f26d9..520d353f 100644 --- a/include/sqlpp11/cte.h +++ b/include/sqlpp11/cte.h @@ -43,17 +43,9 @@ namespace sqlpp template struct cte_union_t { - struct _recursive_traits - { - using _required_ctes = detail::make_joined_set_t, required_ctes_of>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = detail::make_parameter_tuple_t, parameters_of>; - using _tags = detail::type_set<>; - }; + using _nodes = detail::type_vector<>; + using _required_ctes = detail::make_joined_set_t, required_ctes_of>; + using _parameters = detail::type_vector_cat_t, parameters_of>; cte_union_t(Lhs lhs, Rhs rhs): _lhs(lhs), @@ -140,17 +132,10 @@ namespace sqlpp struct cte_t: public member_t, column_t>>... { using _traits = make_traits; // FIXME: is table? really? - struct _recursive_traits - { - using _required_ctes = detail::make_joined_set_t, detail::type_set>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = parameters_of; - using _tags = detail::type_set<>; - }; + using _nodes = detail::type_vector<>; + using _required_ctes = detail::make_joined_set_t, detail::type_set>; + using _parameters = parameters_of; + using _alias_t = typename AliasProvider::_alias_t; constexpr static bool _is_recursive = detail::is_element_of>::value; @@ -235,17 +220,9 @@ namespace sqlpp struct cte_ref_t { using _traits = make_traits; // FIXME: is table? really? - struct _recursive_traits - { - using _required_ctes = detail::make_type_set_t; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set<>; - }; + using _nodes = detail::type_vector<>; + using _required_ctes = detail::make_type_set_t; + using _provided_tables = detail::type_set; using _alias_t = typename AliasProvider::_alias_t; diff --git a/include/sqlpp11/custom_query.h b/include/sqlpp11/custom_query.h index ce332688..1868073b 100644 --- a/include/sqlpp11/custom_query.h +++ b/include/sqlpp11/custom_query.h @@ -54,9 +54,9 @@ namespace sqlpp { using _methods_t = typename detail::custom_parts_t::_result_methods_t; using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; - using _parameter_check = typename std::conditional::value == 0, + using _parameter_check = typename std::conditional>::value == 0, consistent_t, assert_no_parameters_t>::type; using _run_check = detail::get_first_if; diff --git a/include/sqlpp11/default_value.h b/include/sqlpp11/default_value.h index ede6bb87..1a71442a 100644 --- a/include/sqlpp11/default_value.h +++ b/include/sqlpp11/default_value.h @@ -34,7 +34,7 @@ namespace sqlpp struct default_value_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; static constexpr bool _is_trivial() { return false; } }; diff --git a/include/sqlpp11/detail/type_vector.h b/include/sqlpp11/detail/type_vector.h new file mode 100644 index 00000000..7b23b8c8 --- /dev/null +++ b/include/sqlpp11/detail/type_vector.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2015, 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. + */ + +#ifndef SQLPP_DETAIL_TYPE_VECTOR_H +#define SQLPP_DETAIL_TYPE_VECTOR_H + +#include + +namespace sqlpp +{ + namespace detail + { + template + struct type_vector + {}; + + template + struct type_vector_cat_impl + { + static_assert(wrong_t::value, "type_vector_cat must be called with type_vector arguments"); + }; + + template<> + struct type_vector_cat_impl<> + { + using type = type_vector<>; + }; + + template + struct type_vector_cat_impl> + { + using type = type_vector; + }; + + template + struct type_vector_cat_impl, type_vector> + { + using type = type_vector; + }; + + template + struct type_vector_cat_impl, Rest...> + { + using type = typename type_vector_cat_impl, typename type_vector_cat_impl::type>::type; + }; + + template + using type_vector_cat_t = typename type_vector_cat_impl::type; + + template + struct type_vector_size + { + static_assert(wrong_t::value, "type_vector_size needs to be called with a type_vector argument"); + }; + + template + struct type_vector_size> + { + static constexpr std::size_t value = sizeof...(T); + }; + } +} + + +#endif diff --git a/include/sqlpp11/exists.h b/include/sqlpp11/exists.h index ad1df80f..be72191f 100644 --- a/include/sqlpp11/exists.h +++ b/include/sqlpp11/exists.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; static_assert(is_select_t
; + using _nodes = detail::type_vector
; using _data_t = into_data_t; @@ -108,7 +108,7 @@ namespace sqlpp struct no_into_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/is_not_null.h b/include/sqlpp11/is_not_null.h index f6467b18..78e49123 100644 --- a/include/sqlpp11/is_not_null.h +++ b/include/sqlpp11/is_not_null.h @@ -40,7 +40,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; struct _alias_t { diff --git a/include/sqlpp11/is_null.h b/include/sqlpp11/is_null.h index 8bdc0196..0a798067 100644 --- a/include/sqlpp11/is_null.h +++ b/include/sqlpp11/is_null.h @@ -40,7 +40,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; struct _alias_t { diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index 160d1472..8e2578d6 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -66,18 +66,8 @@ namespace sqlpp struct join_t { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::make_joined_set_t, required_ctes_of>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::make_joined_set_t, required_tables_of>; - using _provided_tables = detail::make_joined_set_t, provided_tables_of>; - using _provided_outer_tables = typename JoinType::template _provided_outer_tables; - using _extra_tables = detail::make_joined_set_t, extra_tables_of>; - using _parameters = detail::make_parameter_tuple_t, parameters_of>; - using _tags = detail::type_set<>; - }; - + using _nodes = detail::type_vector; + using _can_be_null = std::false_type; static_assert(is_table_t::value, "lhs argument for join() has to be a table or join"); static_assert(is_table_t::value, "rhs argument for join() has to be a table"); @@ -86,7 +76,7 @@ namespace sqlpp static_assert(detail::is_disjunct_from, provided_tables_of>::value, "joined tables must not be identical"); - static_assert(_recursive_traits::_required_tables::size::value == 0, "joined tables must not depend on other tables"); + static_assert(required_tables_of::size::value == 0, "joined tables must not depend on other tables"); template using set_on_t = join_t; diff --git a/include/sqlpp11/like.h b/include/sqlpp11/like.h index 95d1e2b0..02adeba0 100644 --- a/include/sqlpp11/like.h +++ b/include/sqlpp11/like.h @@ -40,7 +40,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; struct _alias_t { diff --git a/include/sqlpp11/limit.h b/include/sqlpp11/limit.h index 4b5dc564..c740c8dc 100644 --- a/include/sqlpp11/limit.h +++ b/include/sqlpp11/limit.h @@ -55,7 +55,7 @@ namespace sqlpp struct limit_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; // Data using _data_t = limit_data_t; @@ -118,7 +118,7 @@ namespace sqlpp struct dynamic_limit_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = dynamic_limit_data_t; @@ -163,7 +163,7 @@ namespace sqlpp struct no_limit_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/max.h b/include/sqlpp11/max.h index cfa43036..f2011988 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; struct _alias_t { @@ -84,6 +84,7 @@ namespace sqlpp template auto max(T t) -> max_t> { + static_assert(not contains_aggregate_function_t>::value, "max() cannot be used on an aggregate function"); static_assert(is_expression_t>::value, "max() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index e6d97348..7f885c07 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; struct _alias_t { @@ -84,6 +84,7 @@ namespace sqlpp template auto min(T t) -> min_t> { + static_assert(not contains_aggregate_function_t>::value, "min() cannot be used on an aggregate function"); static_assert(is_expression_t>::value, "min() requires an expression as argument"); return { t }; } diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index c5c169b1..8147d3c2 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -42,7 +42,7 @@ namespace sqlpp struct multi_column_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(logic::all_t::value...>::value, "multi_column parameters need to be named expressions"); @@ -73,7 +73,7 @@ namespace sqlpp struct multi_column_alias_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(logic::all_t::value...>::value, "multi_column parameters need to be named expressions"); diff --git a/include/sqlpp11/noop.h b/include/sqlpp11/noop.h index eb4315fb..0a023b80 100644 --- a/include/sqlpp11/noop.h +++ b/include/sqlpp11/noop.h @@ -37,7 +37,7 @@ namespace sqlpp struct noop { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; struct _alias_t {}; diff --git a/include/sqlpp11/not_in.h b/include/sqlpp11/not_in.h index a3b212de..cddfc119 100644 --- a/include/sqlpp11/not_in.h +++ b/include/sqlpp11/not_in.h @@ -41,7 +41,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(sizeof...(Args) > 0, "not_in() requires at least one argument"); diff --git a/include/sqlpp11/null.h b/include/sqlpp11/null.h index 167da605..9b01b69e 100644 --- a/include/sqlpp11/null.h +++ b/include/sqlpp11/null.h @@ -34,7 +34,7 @@ namespace sqlpp struct null_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; }; template diff --git a/include/sqlpp11/offset.h b/include/sqlpp11/offset.h index d78d77b1..bb9b1406 100644 --- a/include/sqlpp11/offset.h +++ b/include/sqlpp11/offset.h @@ -55,7 +55,7 @@ namespace sqlpp struct offset_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; static_assert(is_integral_t::value, "offset requires an integral value or integral parameter"); @@ -120,7 +120,7 @@ namespace sqlpp struct dynamic_offset_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = dynamic_offset_data_t; @@ -177,7 +177,7 @@ namespace sqlpp struct no_offset_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index 785e0a4f..81cff460 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -38,7 +38,7 @@ namespace sqlpp struct on_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _is_dynamic = is_database; diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h index 467930e5..bc85d708 100644 --- a/include/sqlpp11/order_by.h +++ b/include/sqlpp11/order_by.h @@ -71,7 +71,7 @@ namespace sqlpp struct order_by_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _is_dynamic = is_database; @@ -141,7 +141,7 @@ namespace sqlpp struct no_order_by_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 813f0b91..13447233 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -38,17 +38,10 @@ namespace sqlpp public expression_operators, ValueType> { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple; - using _tags = detail::type_set; - }; + + using _nodes = detail::type_vector<>; + using _parameters = detail::type_vector; + using _can_be_null = std::true_type; using _instance_t = member_t>; diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index b185bf73..eaace254 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -37,11 +37,11 @@ namespace sqlpp template struct parameter_list_t { - static_assert(wrong_t::value, "Template parameter for parameter_list_t has to be a tuple"); + static_assert(wrong_t::value, "Template parameter for parameter_list_t has to be a type_vector"); }; template - struct parameter_list_t>: public Parameter::_instance_t... + struct parameter_list_t>: public Parameter::_instance_t... { using _member_tuple_t = std::tuple; using size = std::integral_constant; diff --git a/include/sqlpp11/prepared_execute.h b/include/sqlpp11/prepared_execute.h index a82287c8..7027bbc0 100644 --- a/include/sqlpp11/prepared_execute.h +++ b/include/sqlpp11/prepared_execute.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_execute_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/prepared_insert.h b/include/sqlpp11/prepared_insert.h index da87b5bf..416b46de 100644 --- a/include/sqlpp11/prepared_insert.h +++ b/include/sqlpp11/prepared_insert.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_insert_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/prepared_remove.h b/include/sqlpp11/prepared_remove.h index 1b488106..3d75c9e0 100644 --- a/include/sqlpp11/prepared_remove.h +++ b/include/sqlpp11/prepared_remove.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_remove_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/prepared_select.h b/include/sqlpp11/prepared_select.h index 3ee9eb26..5d5893f5 100644 --- a/include/sqlpp11/prepared_select.h +++ b/include/sqlpp11/prepared_select.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_select_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _result_row_t = typename Statement::template _result_row_t; using _parameter_list_t = make_parameter_list_t; diff --git a/include/sqlpp11/prepared_update.h b/include/sqlpp11/prepared_update.h index ee9ff791..cac4af4b 100644 --- a/include/sqlpp11/prepared_update.h +++ b/include/sqlpp11/prepared_update.h @@ -37,7 +37,7 @@ namespace sqlpp struct prepared_update_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _parameter_list_t = make_parameter_list_t; using _prepared_statement_t = typename Db::_prepared_statement_t; diff --git a/include/sqlpp11/result_field_methods.h b/include/sqlpp11/result_field_methods.h index e3231e05..850d1f43 100644 --- a/include/sqlpp11/result_field_methods.h +++ b/include/sqlpp11/result_field_methods.h @@ -81,20 +81,8 @@ namespace sqlpp tag::is_expression, tag_if>; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = typename std::conditional::value, - detail::type_set, - detail::type_set<>>::type; - }; - + using _nodes = detail::type_vector<>; + using _can_be_null = column_spec_can_be_null_t<_field_spec_t>; }; } diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 32c4ad36..02924a01 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -185,7 +185,7 @@ namespace sqlpp struct _field_spec_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; struct _alias_t {}; }; diff --git a/include/sqlpp11/rhs_wrap.h b/include/sqlpp11/rhs_wrap.h index e9a0bad5..d48f6c22 100644 --- a/include/sqlpp11/rhs_wrap.h +++ b/include/sqlpp11/rhs_wrap.h @@ -118,7 +118,7 @@ namespace sqlpp struct rhs_wrap_t { using _traits = typename Expr::_traits; - using _recursive_traits = typename Expr::_recursive_traits; + using _nodes = detail::type_vector; rhs_wrap_t(Expr expr): _expr(expr) diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index 86e14466..0a5b5e74 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -164,7 +164,7 @@ namespace sqlpp struct select_column_list_t { using _traits = typename detail::select_traits::_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _alias_t = typename detail::select_traits::_alias_t; @@ -353,7 +353,7 @@ namespace sqlpp struct no_select_column_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; struct _alias_t {}; diff --git a/include/sqlpp11/select_flag_list.h b/include/sqlpp11/select_flag_list.h index db66ea6f..1cd4fc5f 100644 --- a/include/sqlpp11/select_flag_list.h +++ b/include/sqlpp11/select_flag_list.h @@ -60,7 +60,7 @@ namespace sqlpp struct select_flag_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _is_dynamic = is_database; @@ -128,7 +128,7 @@ namespace sqlpp struct no_select_flag_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/select_flags.h b/include/sqlpp11/select_flags.h index 5db6a0b6..c9210486 100644 --- a/include/sqlpp11/select_flags.h +++ b/include/sqlpp11/select_flags.h @@ -38,7 +38,7 @@ namespace sqlpp struct all_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; }; static constexpr all_t all = {}; @@ -57,7 +57,7 @@ namespace sqlpp struct distinct_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; }; static constexpr distinct_t distinct = {}; @@ -76,7 +76,7 @@ namespace sqlpp struct straight_join_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; }; static constexpr straight_join_t straight_join = {}; diff --git a/include/sqlpp11/select_pseudo_table.h b/include/sqlpp11/select_pseudo_table.h index 44ef4be7..2f027dd0 100644 --- a/include/sqlpp11/select_pseudo_table.h +++ b/include/sqlpp11/select_pseudo_table.h @@ -58,7 +58,7 @@ namespace sqlpp NamedExpr...>, select_column_spec_t...> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; select_pseudo_table_t(Select select): _select(select) diff --git a/include/sqlpp11/simple_column.h b/include/sqlpp11/simple_column.h index d90f93be..c5442a61 100644 --- a/include/sqlpp11/simple_column.h +++ b/include/sqlpp11/simple_column.h @@ -39,7 +39,7 @@ namespace sqlpp _column_t _column; using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; }; template diff --git a/include/sqlpp11/single_table.h b/include/sqlpp11/single_table.h index 72f05877..dc9b7798 100644 --- a/include/sqlpp11/single_table.h +++ b/include/sqlpp11/single_table.h @@ -58,7 +58,7 @@ namespace sqlpp struct single_table_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits
; + using _nodes = detail::type_vector
; static_assert(is_table_t
::value, "argument has to be a table"); static_assert(required_tables_of
::size::value == 0, "table depends on another table"); @@ -99,7 +99,7 @@ namespace sqlpp struct no_single_table_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/some.h b/include/sqlpp11/some.h index 6ad8bf40..1800e974 100644 --- a/include/sqlpp11/some.h +++ b/include/sqlpp11/some.h @@ -37,7 +37,7 @@ namespace sqlpp struct some_t { using _traits = make_traits, tag::is_multi_expression>; - using _recursive_traits = make_recursive_traits; struct _alias_t { diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h index cd0d6357..1dea7449 100644 --- a/include/sqlpp11/sort_order.h +++ b/include/sqlpp11/sort_order.h @@ -42,7 +42,7 @@ namespace sqlpp struct sort_order_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; Expression _expression; }; diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index d6acbbbf..863ef6ed 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -130,14 +130,12 @@ namespace sqlpp // A select can be used as a pseudo table if // - at least one column is selected - // - the select is complete (leaks no table requirements) + // - the select is complete (leaks no table requirements or cte requirements) static constexpr bool _can_be_used_as_table() { return has_result_row_t<_statement_t>::value and _required_tables::size::value == 0 - and _all_provided_ctes::size::value == 0 // a sub-select must not contain a WITH - ? true - : false; + and _required_ctes::size::value == 0; } using _value_type = typename std::conditional< @@ -146,34 +144,23 @@ namespace sqlpp no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value >::type; + using _traits = make_traits<_value_type, tag_if::value>>; + + using _nodes = detail::type_vector<>; using _can_be_null = logic::any_t< can_be_null_t<_result_type_provider>::value, detail::make_intersect_set_t< required_tables_of<_result_type_provider>, _all_provided_outer_tables >::size::value != 0>; - - using _traits = make_traits<_value_type, tag_if::value>>; - - struct _recursive_traits - { - using _required_ctes = statement_policies_t::_required_ctes; - using _provided_ctes = detail::type_set<>; - using _required_tables = statement_policies_t::_required_tables; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = detail::make_parameter_tuple_t...>; - using _tags = typename std::conditional<_can_be_null::value, - detail::type_set, - detail::type_set<>>::type; - }; + using _parameters = detail::type_vector_cat_t...>; + // required_tables and _required_ctes are defined above using _cte_check = typename std::conditional<_required_ctes::size::value == 0, consistent_t, assert_no_unknown_ctes_t>::type; using _table_check = typename std::conditional<_required_tables::size::value == 0, consistent_t, assert_no_unknown_tables_t>::type; - using _parameter_check = typename std::conditional::value == 0, + using _parameter_check = typename std::conditional::value == 0, consistent_t, assert_no_parameters_t>::type; }; } @@ -212,7 +199,7 @@ namespace sqlpp tag_if::value>, tag_if::value>::value>, tag::requires_braces>; - using _recursive_traits = typename _policies_t::_recursive_traits; + using _nodes = detail::type_vector<_policies_t>; using _used_outer_tables = typename _policies_t::_all_provided_outer_tables; using _alias_t = typename _result_type_provider::_alias_t; @@ -237,7 +224,7 @@ namespace sqlpp static constexpr size_t _get_static_no_of_parameters() { - return std::tuple_size>::value; + return detail::type_vector_size>::value; } size_t _get_no_of_parameters() const @@ -286,7 +273,7 @@ namespace sqlpp struct statement_name_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = NameData; diff --git a/include/sqlpp11/sum.h b/include/sqlpp11/sum.h index 91970f9a..b766d2e3 100644 --- a/include/sqlpp11/sum.h +++ b/include/sqlpp11/sum.h @@ -38,7 +38,7 @@ namespace sqlpp public alias_operators> { using _traits = make_traits, tag::is_expression, tag::is_selectable>; - using _recursive_traits = make_recursive_traits; + 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"); diff --git a/include/sqlpp11/table.h b/include/sqlpp11/table.h index 06724089..a7a22b65 100644 --- a/include/sqlpp11/table.h +++ b/include/sqlpp11/table.h @@ -46,17 +46,8 @@ namespace sqlpp { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set
; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set<>; - }; + using _nodes = detail::type_vector<>; + using _provided_tables = detail::type_set
; static_assert(sizeof...(ColumnSpec), "at least one column required per table"); using _required_insert_columns = typename detail::make_type_set_if...>::type; diff --git a/include/sqlpp11/table_alias.h b/include/sqlpp11/table_alias.h index 32324b71..2452ec6c 100644 --- a/include/sqlpp11/table_alias.h +++ b/include/sqlpp11/table_alias.h @@ -42,17 +42,9 @@ namespace sqlpp //FIXME: Need to add join functionality using _traits = make_traits, tag::is_table, tag::is_alias, tag_if::value>>; - struct _recursive_traits - { - using _required_ctes = required_ctes_of
; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set<>; - }; + using _nodes = detail::type_vector<>; + using _required_ctes = required_ctes_of
; + using _provided_tables = detail::type_set; static_assert(required_tables_of
::size::value == 0, "table aliases must not depend on external tables"); diff --git a/include/sqlpp11/tvin.h b/include/sqlpp11/tvin.h index ca2af06b..9c4b3c1a 100644 --- a/include/sqlpp11/tvin.h +++ b/include/sqlpp11/tvin.h @@ -40,7 +40,7 @@ namespace sqlpp struct tvin_arg_t { using _traits = make_traits, tag::is_expression>; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _operand_t = Operand; @@ -102,7 +102,7 @@ namespace sqlpp struct tvin_t { using _traits = make_traits, tag::is_expression>; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _operand_t = Operand; diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 322b655f..74cad854 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -38,29 +39,8 @@ namespace sqlpp namespace tag { struct can_be_null{}; - struct contains_aggregate_function{}; } - namespace detail - { - template - struct can_be_null_impl { using type = std::false_type; }; - template - struct can_be_null_impl::value>::type> { using type = std::true_type; }; - } - template - using can_be_null_t = typename detail::can_be_null_impl::type; - - namespace detail - { - template - struct contains_aggregate_function_impl { using type = std::false_type; }; - template - struct contains_aggregate_function_impl::value>::type> { using type = std::true_type; }; - } - template - using contains_aggregate_function_t = typename detail::contains_aggregate_function_impl::type; - namespace detail { template @@ -71,23 +51,6 @@ namespace sqlpp template using column_spec_can_be_null_t = typename detail::column_spec_can_be_null_impl::type; - namespace tag - { - struct is_expression{}; - } - namespace detail - { - template - struct is_expression_impl { using type = std::false_type; }; - template - struct is_expression_impl::value - and not detail::is_element_of::value - >::type> { using type = std::true_type; }; - } - template - using is_expression_t = typename detail::is_expression_impl::type; - #define SQLPP_VALUE_TRAIT_GENERATOR(name) \ namespace tag\ {\ @@ -116,6 +79,7 @@ namespace sqlpp SQLPP_VALUE_TRAIT_GENERATOR(is_text) SQLPP_VALUE_TRAIT_GENERATOR(is_wrapped_value) SQLPP_VALUE_TRAIT_GENERATOR(is_selectable) + SQLPP_VALUE_TRAIT_GENERATOR(is_expression) SQLPP_VALUE_TRAIT_GENERATOR(is_multi_expression) SQLPP_VALUE_TRAIT_GENERATOR(is_alias) SQLPP_VALUE_TRAIT_GENERATOR(is_select_flag) @@ -175,40 +139,86 @@ namespace sqlpp template using is_database = typename std::conditional::value, std::false_type, std::true_type>::type; - namespace detail - { - template - using make_parameter_tuple_t = decltype(std::tuple_cat(std::declval()...)); - } template using value_type_of = typename T::_traits::_value_type; template using cpp_value_type_of = typename value_type_of::_cpp_value_type; - template - using required_ctes_of = typename T::_recursive_traits::_required_ctes; +#define SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(trait) \ + namespace detail\ + {\ + template\ + struct trait##_of_impl\ + {\ + using type = typename trait##_of_impl::type;\ + };\ + template\ + struct trait##_of_impl::value>::type>\ + {\ + using type = typename T::_##trait;\ + };\ + template\ + struct trait##_of_impl, void>\ + {\ + using type = detail::make_joined_set_t::type...>;\ + };\ + }\ + template\ + using trait##_of = typename detail::trait##_of_impl::type; - template - using provided_ctes_of = typename T::_recursive_traits::_provided_ctes; + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(required_ctes) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_ctes) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(required_tables) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_tables) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(provided_outer_tables) + SQLPP_RECURSIVE_TRAIT_SET_GENERATOR(extra_tables) - template - using required_tables_of = typename T::_recursive_traits::_required_tables; +#define SQLPP_RECURSIVE_TRAIT_GENERATOR(trait) \ + namespace detail\ + {\ + template\ + struct trait##_impl\ + {\ + using type = typename trait##_impl::type;\ + };\ + template\ + struct trait##_impl::value>::type>\ + {\ + using type = typename T::_##trait;\ + };\ + template\ + struct trait##_impl, void>\ + {\ + using type = logic::any_t::type::value...>;\ + };\ + }\ + template\ + using trait##_t = typename detail::trait##_impl::type; - template - using provided_tables_of = typename T::_recursive_traits::_provided_tables; + SQLPP_RECURSIVE_TRAIT_GENERATOR(can_be_null) + SQLPP_RECURSIVE_TRAIT_GENERATOR(contains_aggregate_function) - template - using provided_outer_tables_of = typename T::_recursive_traits::_provided_outer_tables; - - template - using extra_tables_of = typename T::_recursive_traits::_extra_tables; - - template - using parameters_of = typename T::_recursive_traits::_parameters; - - template - using recursive_tags_of = typename T::_recursive_traits::_tags; + namespace detail + { + template + struct parameters_of_impl + { + using type = typename parameters_of_impl::type; + }; + template + struct parameters_of_impl::value>::type> + { + using type = typename T::_parameters; + }; + template + struct parameters_of_impl, void> + { + using type = detail::type_vector_cat_t::type...>; + }; + } + template\ + using parameters_of = typename detail::parameters_of_impl::type; template using alias_of = typename T::_alias_t; @@ -223,36 +233,10 @@ namespace sqlpp using _tags = detail::make_type_set_t; }; - template - struct make_recursive_traits - { - using _required_ctes = detail::make_joined_set_t...>; - using _provided_ctes = detail::make_joined_set_t...>; - using _required_tables = detail::make_joined_set_t...>; - using _provided_tables = detail::make_joined_set_t...>; - using _provided_outer_tables = detail::make_joined_set_t...>; - using _extra_tables = detail::make_joined_set_t...>; - using _parameters = detail::make_parameter_tuple_t...>; - using _tags = detail::make_joined_set_t...>; - }; - - template - struct recursive_tags - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::type_set<>; - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = std::tuple<>; - using _tags = detail::type_set; - }; - struct aggregate_function { - struct _traits { using _value_type = void; using _tags = detail::type_set<>; }; - using _recursive_traits = recursive_tags; + using _nodes = detail::type_vector<>; + using _contains_aggregate_function = std::true_type; }; template diff --git a/include/sqlpp11/union.h b/include/sqlpp11/union.h index d0860c54..199c0aa8 100644 --- a/include/sqlpp11/union.h +++ b/include/sqlpp11/union.h @@ -66,7 +66,7 @@ namespace sqlpp struct union_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _alias_t = struct{}; @@ -114,7 +114,7 @@ namespace sqlpp struct no_union_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/update_list.h b/include/sqlpp11/update_list.h index 28df9045..d2e3cd9e 100644 --- a/include/sqlpp11/update_list.h +++ b/include/sqlpp11/update_list.h @@ -68,7 +68,7 @@ namespace sqlpp struct update_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _is_dynamic = is_database; // Data @@ -153,7 +153,7 @@ namespace sqlpp struct no_update_list_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/using.h b/include/sqlpp11/using.h index 16fd6875..10018e14 100644 --- a/include/sqlpp11/using.h +++ b/include/sqlpp11/using.h @@ -58,7 +58,7 @@ namespace sqlpp struct using_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _is_dynamic = is_database; @@ -121,7 +121,7 @@ namespace sqlpp struct no_using_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/value_or_null.h b/include/sqlpp11/value_or_null.h index 9cb2f9b2..ab8fb6a7 100644 --- a/include/sqlpp11/value_or_null.h +++ b/include/sqlpp11/value_or_null.h @@ -51,7 +51,7 @@ namespace sqlpp using _cpp_value_type = typename ValueType::_cpp_value_type; using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; value_or_null_t(_cpp_value_type value): _value(value), diff --git a/include/sqlpp11/verbatim.h b/include/sqlpp11/verbatim.h index 5cae04b4..63ef533e 100644 --- a/include/sqlpp11/verbatim.h +++ b/include/sqlpp11/verbatim.h @@ -39,10 +39,8 @@ namespace sqlpp public alias_operators> { using _traits = make_traits; - struct _recursive_traits : public make_recursive_traits<> - { - using _tags = detail::type_set; // since we do not know what's going on inside the verbatim, we assume it can be null - }; + using _nodes = detail::type_vector<>; + using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null verbatim_t(std::string verbatim): _verbatim(verbatim) {} verbatim_t(const verbatim_t&) = default; diff --git a/include/sqlpp11/verbatim_table.h b/include/sqlpp11/verbatim_table.h index 0eb63ce4..9247d3a6 100644 --- a/include/sqlpp11/verbatim_table.h +++ b/include/sqlpp11/verbatim_table.h @@ -50,10 +50,7 @@ namespace sqlpp struct verbatim_table_t: public table_t { - struct _recursive_traits: public table_t::_recursive_traits - { - using _provided_outer_tables = detail::type_set; - }; + using _nodes = detail::type_vector<>; struct _alias_t { diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index d37519cb..e3828696 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -71,7 +71,7 @@ namespace sqlpp struct where_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits; + using _nodes = detail::type_vector; using _is_dynamic = is_database; @@ -149,7 +149,7 @@ namespace sqlpp struct where_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = where_data_t; @@ -198,7 +198,7 @@ namespace sqlpp struct no_where_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/with.h b/include/sqlpp11/with.h index 10d881bb..c2e0a725 100644 --- a/include/sqlpp11/with.h +++ b/include/sqlpp11/with.h @@ -66,17 +66,9 @@ namespace sqlpp struct with_t { using _traits = make_traits; - struct _recursive_traits - { - using _required_ctes = detail::type_set<>; - using _provided_ctes = detail::make_joined_set_t...>; // with provides common table expressions - using _required_tables = detail::type_set<>; - using _provided_tables = detail::type_set<>; - using _provided_outer_tables = detail::type_set<>; - using _extra_tables = detail::type_set<>; - using _parameters = detail::make_parameter_tuple_t...>; - using _tags = detail::type_set<>; - }; + using _nodes = detail::type_vector<>; + using _provided_ctes = detail::make_joined_set_t...>; // WITH provides common table expressions + using _parameters = detail::type_vector_cat_t...>; using _is_dynamic = is_database; @@ -116,7 +108,7 @@ namespace sqlpp struct no_with_t { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; // Data using _data_t = no_data_t; diff --git a/include/sqlpp11/wrap_operand.h b/include/sqlpp11/wrap_operand.h index 8728197d..f8a4fc77 100644 --- a/include/sqlpp11/wrap_operand.h +++ b/include/sqlpp11/wrap_operand.h @@ -43,7 +43,7 @@ namespace sqlpp struct boolean_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _value_t = bool; @@ -82,7 +82,7 @@ namespace sqlpp struct integral_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _value_t = int64_t; @@ -122,7 +122,7 @@ namespace sqlpp struct floating_point_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _value_t = double; @@ -161,7 +161,7 @@ namespace sqlpp struct text_operand: public alias_operators { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + using _nodes = detail::type_vector<>; using _value_t = std::string; diff --git a/test_constraints/CMakeLists.txt b/test_constraints/CMakeLists.txt index 2281b371..d36c597f 100644 --- a/test_constraints/CMakeLists.txt +++ b/test_constraints/CMakeLists.txt @@ -24,8 +24,8 @@ function(test_constraint name pattern) endfunction(test_constraint) -test_constraint(count_of_count "requires an expression as argument") -test_constraint(max_of_max "requires an expression as argument") +test_constraint(count_of_count "count() cannot be used on an aggregate function") +test_constraint(max_of_max "max() cannot be used on an aggregate function") test_constraint(no_conversion_operator_if_null_not_trivial "int i = row.alpha") test_constraint(require_insert "required column is missing") test_constraint(must_not_insert "one assignment is prohibited") diff --git a/tests/PreparedTest.cpp b/tests/PreparedTest.cpp index 87b47311..8e4c79df 100644 --- a/tests/PreparedTest.cpp +++ b/tests/PreparedTest.cpp @@ -40,40 +40,48 @@ int main() // empty parameter lists { - using T = sqlpp::parameters_of; - static_assert(std::is_same>::value, "type requirement"); + using T = sqlpp::make_parameter_list_t; + static_assert(T::size::value == 0, "type requirement"); } // single parameter { - using T = sqlpp::parameters_of; - static_assert(std::is_same>::value, "type requirement"); + using T = sqlpp::make_parameter_list_t; + static_assert(T::size::value == 1, "type requirement"); + auto t = T{}; + t.alpha = 7; } // single parameter { - using T = sqlpp::parameters_of; - static_assert(std::is_same>::value, "type requirement"); + using T = sqlpp::make_parameter_list_t; + static_assert(T::size::value == 1, "type requirement"); + auto t = T{}; + t.beta = "cheesecake"; } // single parameter in expression { - using T = sqlpp::parameters_of; - static_assert(std::is_same>::value, "type requirement"); + using T = sqlpp::make_parameter_list_t; + static_assert(T::size::value == 1, "type requirement"); + auto t = T{}; + t.alpha = 7; } // single parameter in larger expression { - using T = sqlpp::parameters_of; - static_assert(std::is_same>::value, "type requirement"); + using T = sqlpp::make_parameter_list_t; + static_assert(T::size::value == 1, "type requirement"); + auto t = T{}; + t.alpha = 7; } // three parameters in expression { using T = sqlpp::parameters_of; - static_assert(std::tuple_size::value == 3, "type requirement"); - static_assert(std::is_same>::value, "type requirement"); + // FIXME: make some test, that does not depend on detail namespace, but still checks the correct order of the parameters + static_assert(std::is_same>::value, "type requirement"); } // OK, fine, now create a named parameter list from an expression