diff --git a/include/sqlpp11/detail/logic.h b/include/sqlpp11/detail/logic.h index a533a4ee..9fb26cb9 100644 --- a/include/sqlpp11/detail/logic.h +++ b/include/sqlpp11/detail/logic.h @@ -69,7 +69,7 @@ namespace sqlpp template struct any_impl { - using type = typename all_impl::type; + using type = typename any_impl::type; }; template diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index 04db6eb0..3d07eb1f 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -39,37 +39,60 @@ namespace sqlpp { + template + struct remove_t; + namespace detail { - template - struct check_remove_t + template + struct remove_policies_t { - static_assert(is_where_t::value, "cannot run remove without having a where condition, use .where(true) to remove all rows"); - static constexpr bool value = true; + using _database_t = Db; + using _table_t = Table; + using _using_t = Using; + using _where_t = Where; + + using _statement_t = remove_t; + + struct _methods_t: + public _using_t::template _methods_t, + public _where_t::template _methods_t + {}; + + template + struct _policies_update_impl + { + using type = remove_t...>; + }; + + template + using _policies_update_t = typename _policies_update_impl::type; + }; } // REMOVE - template - struct remove_t + struct remove_t: + public detail::remove_policies_t::_methods_t { - using _database_t = Database; - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + 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 _where_t = typename _policies_t::_where_t; - template - struct _policies_update_impl - { - using type = remove_t...>; - }; + using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - template - using _policies_update_t = typename _policies_update_impl::type; - - using _parameter_tuple_t = std::tuple; + using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; // Constructors @@ -78,9 +101,9 @@ namespace sqlpp template remove_t(Statement s, T t): - _table(detail::arg_selector::_(s._table, t)), - _using(detail::arg_selector::_(s._using, t)), - _where(detail::arg_selector::_(s._where, 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)) {} remove_t(const remove_t&) = default; @@ -89,58 +112,6 @@ namespace sqlpp remove_t& operator=(remove_t&&) = default; ~remove_t() = default; - // type update functions - template - auto using_(Args... args) - -> _policies_update_t> - { - static_assert(is_noop_t::value, "cannot call using_()/dynamic_using() twice"); - return { *this, vendor::using_t{args...} }; - } - - template - auto dynamic_using(Args... args) - -> _policies_update_t> - { - static_assert(is_noop_t::value, "cannot call using_()/dynamic_using() twice"); - static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement"); - return { *this, vendor::using_t<_database_t, Args...>{args...} }; - } - - template - auto where(Args... args) - -> _policies_update_t> - { - static_assert(is_noop_t::value, "cannot call where()/dynamic_where() twice"); - return { *this, vendor::where_t{args...} }; - } - - template - auto dynamic_where(Args... args) - -> _policies_update_t> - { - static_assert(is_noop_t::value, "cannot call where()/dynamic_where() twice"); - static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement"); - return { *this, vendor::where_t<_database_t, Args...>{args...} }; - } - - // value adding methods - template - void add_using(Args... args) - { - static_assert(is_using_t::value, "cannot call add_using() before dynamic_using()"); - static_assert(is_dynamic_t::value, "cannot call add_using() before dynamic_using()"); - return _using.add_using(args...); - } - - template - void add_where(Args... args) - { - static_assert(is_where_t::value, "cannot call add_where() before dynamic_where()"); - static_assert(is_dynamic_t::value, "cannot call add_where() before dynamic_where()"); - return _where.add_where(*this, args...); - } - // run and prepare static constexpr size_t _get_static_no_of_parameters() { @@ -152,25 +123,25 @@ namespace sqlpp return _parameter_list_t::size::value; } - template - std::size_t _run(Db& db) const + template + std::size_t _run(Database& db) const { static_assert(_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead"); - //static_assert(detail::check_remove_t::value, "Cannot run this remove expression"); + static_assert(is_where_t<_where_t>::value, "cannot run remove without having a where condition, use .where(true) to remove all rows"); return db.remove(*this); } - template - auto _prepare(Db& db) const - -> prepared_remove_t + template + auto _prepare(Database& db) const + -> prepared_remove_t { - //static_assert(detail::check_remove_t::value, "Cannot run this remove expression"); + static_assert(is_where_t<_where_t>::value, "cannot run remove without having a where condition, use .where(true) to remove all rows"); return {{}, db.prepare_remove(*this)}; } - Table _table; - Using _using; - Where _where; + _table_t _table; + _using_t _using; + _where_t _where; }; namespace vendor @@ -191,18 +162,21 @@ namespace sqlpp }; } + template + using make_remove_t = typename detail::remove_policies_t::_statement_t; + template constexpr auto remove_from(Table table) - -> remove_t> + -> make_remove_t> { - return { remove_t(), vendor::single_table_t{table} }; + return { make_remove_t(), vendor::single_table_t{table} }; } template constexpr auto dynamic_remove_from(const Database&, Table table) - -> remove_t> + -> make_remove_t> { - return { remove_t(), vendor::single_table_t{table} }; + return { make_remove_t(), vendor::single_table_t{table} }; } } diff --git a/include/sqlpp11/vendor/using.h b/include/sqlpp11/vendor/using.h index a52a479a..1a73bf6a 100644 --- a/include/sqlpp11/vendor/using.h +++ b/include/sqlpp11/vendor/using.h @@ -61,14 +61,31 @@ namespace sqlpp using_t& operator=(using_t&&) = default; ~using_t() = default; - - template - void add_using(Table table) + template + struct _methods_t { - static_assert(_is_dynamic::value, "add_using can only be called for dynamic_using"); - static_assert(is_table_t
::value, "using() arguments require to be tables"); - _dynamic_tables.emplace_back(table); - } + template + void add_using(Table table) + { + static_assert(_is_dynamic::value, "add_using must not be called for static using()"); + static_assert(is_table_t
::value, "invalid table argument in add_using()"); + + using ok = ::sqlpp::detail::all_t>; + + _add_using_impl(table, ok()); // dispatch to prevent compile messages after the static_assert + } + + private: + template + void _add_using_impl(Table table, const std::true_type&) + { + return static_cast(this)->_using._dynamic_tables.emplace_back(table); + } + + template + void _add_using_impl(Table table, const std::false_type&); + }; + _parameter_tuple_t _tables; vendor::interpretable_list_t _dynamic_tables; @@ -77,6 +94,30 @@ namespace sqlpp struct no_using_t { using _is_noop = std::true_type; + using _table_set = ::sqlpp::detail::type_set<>; + + template + struct _methods_t + { + using _database_t = typename Policies::_database_t; + template + using _new_select_t = typename Policies::template _policies_update_t; + + template + auto using_(Args... args) + -> _new_select_t> + { + return { *static_cast(this), using_t{args...} }; + } + + template + auto dynamic_using(Args... args) + -> _new_select_t> + { + static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement"); + return { *static_cast(this), vendor::using_t<_database_t, Args...>{args...} }; + } + }; }; // Interpreters