From 2a215905fd24ab22a094a72387bfdc3fd4d0e8ec Mon Sep 17 00:00:00 2001 From: rbock Date: Fri, 23 May 2014 20:36:13 +0200 Subject: [PATCH] Migrated remove to being variadic --- include/sqlpp11/basic_expression_operators.h | 7 +- include/sqlpp11/insert.h | 21 +++- include/sqlpp11/remove.h | 124 ++++++++++--------- include/sqlpp11/vendor/expression_fwd.h | 7 ++ include/sqlpp11/vendor/noop.h | 2 + include/sqlpp11/vendor/single_table.h | 8 ++ include/sqlpp11/vendor/using.h | 17 ++- tests/CMakeLists.txt | 4 +- 8 files changed, 111 insertions(+), 79 deletions(-) diff --git a/include/sqlpp11/basic_expression_operators.h b/include/sqlpp11/basic_expression_operators.h index 9e97a044..e306542d 100644 --- a/include/sqlpp11/basic_expression_operators.h +++ b/include/sqlpp11/basic_expression_operators.h @@ -32,16 +32,11 @@ #include #include #include +#include #include namespace sqlpp { - - namespace detail - { - struct boolean; - } - // basic operators template class IsCorrectValueType> struct basic_expression_operators diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index 78e5d0f9..b1141ae8 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -104,16 +104,14 @@ namespace sqlpp using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; - // Constructors - insert_t() + constexpr insert_t() {} - template - insert_t(Statement statement, T term): + template + insert_t(Statement statement, Term term): Policies(detail::pick_arg(statement, term))... {} @@ -181,6 +179,12 @@ namespace sqlpp vendor::no_single_table_t, vendor::no_insert_value_list_t>; + constexpr auto insert() + -> blank_insert_t + { + return { blank_insert_t() }; + } + template constexpr auto insert_into(Table table) -> decltype(blank_insert_t().into(table)) @@ -188,6 +192,13 @@ namespace sqlpp return { blank_insert_t().into(table) }; } + template + constexpr auto dynamic_insert(const Database&) + -> decltype(blank_insert_t()) + { + return { blank_insert_t() }; + } + template constexpr auto dynamic_insert_into(const Database&, Table table) -> decltype(blank_insert_t().into(table)) diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index ed12718f..77349668 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -31,88 +31,90 @@ #include #include #include +#warning: need to use another table provider, since delete can be used with several tables #include #include #include #include #include -#include + +#include +#include namespace sqlpp { - template + template struct remove_t; namespace detail { - template + template struct remove_policies_t { using _database_t = Db; - using _table_t = Table; - using _using_t = Using; - using _extra_tables_t = ExtraTables; - using _where_t = Where; - using _statement_t = remove_t; + using _statement_t = remove_t; - struct _methods_t: - public _using_t::template _methods_t, - public _extra_tables_t::template _methods_t, - public _where_t::template _methods_t + struct _methods_t: public Policies::template _methods_t... {}; - template + template struct _policies_update_t { + static_assert(detail::is_element_of>::value, "policies update for non-policy class detected"); using type = remove_t...>; }; template - using _new_statement_t = typename _policies_update_t::type; + using _new_statement_t = typename _policies_update_t::type; - using _known_tables = detail::make_joined_set_t; + using _all_required_tables = detail::make_joined_set_t...>; + using _all_provided_tables = detail::make_joined_set_t...>; + using _all_extra_tables = detail::make_joined_set_t...>; + + using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>; template - using _no_unknown_tables = detail::is_subset_of; + using _no_unknown_tables = detail::is_subset_of, _known_tables>; + + // The tables not covered by the from. + using _required_tables = detail::make_difference_set_t< + _all_required_tables, + _all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*() + >; + + using _traits = make_traits; // FIXME + + struct _recursive_traits + { + using _parameters = std::tuple<>; // FIXME + using _required_tables = _required_tables; + using _provided_tables = detail::type_set<>; + using _extra_tables = detail::type_set<>; + }; }; } // REMOVE - template + template struct remove_t: + public Policies..., public detail::remove_policies_t::_methods_t { using _policies_t = typename detail::remove_policies_t; using _database_t = typename _policies_t::_database_t; - using _table_t = typename _policies_t::_table_t; - using _using_t = typename _policies_t::_using_t; - using _extra_tables_t = typename _policies_t::_extra_tables_t; - using _where_t = typename _policies_t::_where_t; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; // Constructors - remove_t() + constexpr remove_t() {} - template - remove_t(Statement s, T t): - _table(detail::arg_selector<_table_t>::_(s._table, t)), - _using(detail::arg_selector<_using_t>::_(s._using, t)), - _where(detail::arg_selector<_where_t>::_(s._where, t)) + template + remove_t(Statement statement, Term term): + Policies(detail::pick_arg(statement, term))... {} remove_t(const remove_t&) = default; @@ -132,18 +134,15 @@ namespace sqlpp return _parameter_list_t::size::value; } - template - struct is_table_subset_of_table - { - static constexpr bool value = ::sqlpp::detail::is_subset_of::value; - }; - void _check_consistency() const { +#warning reactivate checks +#if 0 static_assert(is_where_t<_where_t>::value, "cannot run update without having a where condition, use .where(true) to update all rows"); // FIXME: Read more details about what is allowed and what not in SQL DELETE static_assert(is_table_subset_of_table<_where_t>::value, "where requires additional tables"); +#endif } template @@ -163,10 +162,6 @@ namespace sqlpp return {{}, db.prepare_remove(*this)}; } - - _table_t _table; - _using_t _using; - _where_t _where; }; namespace vendor @@ -179,31 +174,46 @@ namespace sqlpp static Context& _(const T& t, Context& context) { context << "DELETE FROM "; - serialize(t._table, context); - serialize(t._using, context); - serialize(t._where, context); + using swallow = int[]; + (void) swallow{(serialize(static_cast(t), context), 0)...}; return context; } }; } - template - using make_remove_t = typename detail::remove_policies_t::_statement_t; + template + using blank_remove_t = remove_t; + + constexpr auto remove() + -> blank_remove_t + { + return { blank_remove_t() }; + } template constexpr auto remove_from(Table table) - -> make_remove_t> + -> decltype(blank_remove_t().from(table)) { - return { make_remove_t(), vendor::single_table_t{table} }; + return { blank_remove_t().from(table) }; + } + + template + constexpr auto dynamic_remove(const Database&) + -> decltype(blank_remove_t()) + { + return { blank_remove_t() }; } template constexpr auto dynamic_remove_from(const Database&, Table table) - -> make_remove_t> + -> decltype(blank_remove_t().from(table)) { - return { make_remove_t(), vendor::single_table_t{table} }; + return { blank_remove_t().from(table) }; } - } #endif diff --git a/include/sqlpp11/vendor/expression_fwd.h b/include/sqlpp11/vendor/expression_fwd.h index 374a4265..796596e5 100644 --- a/include/sqlpp11/vendor/expression_fwd.h +++ b/include/sqlpp11/vendor/expression_fwd.h @@ -29,6 +29,13 @@ namespace sqlpp { + namespace detail + { + struct boolean; + struct integral; + struct floating_point; + } + namespace vendor { namespace op diff --git a/include/sqlpp11/vendor/noop.h b/include/sqlpp11/vendor/noop.h index 1a7bcfe5..05df9dd9 100644 --- a/include/sqlpp11/vendor/noop.h +++ b/include/sqlpp11/vendor/noop.h @@ -28,6 +28,8 @@ #define SQLPP_NOOP_H #include +#include +#include namespace sqlpp { diff --git a/include/sqlpp11/vendor/single_table.h b/include/sqlpp11/vendor/single_table.h index ddf55c72..57dc7fc0 100644 --- a/include/sqlpp11/vendor/single_table.h +++ b/include/sqlpp11/vendor/single_table.h @@ -80,6 +80,14 @@ namespace sqlpp { return { *static_cast(this), single_table_t{args...} }; } + +#warning: remove can operate on several tables at once, so it should not use single_table anyway + template + auto from(Args... args) + -> _new_statement_t> + { + return { *static_cast(this), single_table_t{args...} }; + } }; }; diff --git a/include/sqlpp11/vendor/using.h b/include/sqlpp11/vendor/using.h index f9094408..7a7d7ccf 100644 --- a/include/sqlpp11/vendor/using.h +++ b/include/sqlpp11/vendor/using.h @@ -41,9 +41,10 @@ namespace sqlpp template struct using_t { - using _is_using = std::true_type; + using _traits = make_traits; + using _recursive_traits = make_recursive_traits; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - using _parameter_tuple_t = std::tuple; static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table argument required in using()"); @@ -51,8 +52,7 @@ namespace sqlpp static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an table in using()"); - using _provided_tables = detail::type_set<>; - using _required_tables = ::sqlpp::detail::make_joined_set_t; + using_t& _using() { return *this; } using_t(Tables... tables): _tables(tables...) @@ -82,7 +82,7 @@ namespace sqlpp template void _add_using_impl(Table table, const std::true_type&) { - return static_cast(this)->_using._dynamic_tables.emplace_back(table); + return static_cast(this)->_using()._dynamic_tables.emplace_back(table); } template @@ -90,15 +90,14 @@ namespace sqlpp }; - _parameter_tuple_t _tables; + std::tuple _tables; vendor::interpretable_list_t _dynamic_tables; }; struct no_using_t { - using _is_noop = std::true_type; - using _provided_tables = detail::type_set<>; - using _required_tables = ::sqlpp::detail::type_set<>; + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; template struct _methods_t diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9de5e4e2..d7fcb902 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,8 +7,8 @@ macro (build_and_run arg) endmacro () #build_and_run(InterpretTest) -build_and_run(InsertTest) -#build_and_run(RemoveTest) +#build_and_run(InsertTest) +build_and_run(RemoveTest) #build_and_run(UpdateTest) #build_and_run(SelectTest) #build_and_run(SelectTypeTest)