From c866f31ea5edff8559d353cbc3627723adb96416 Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 3 Jun 2014 09:12:27 +0200 Subject: [PATCH] Turned remove into a generic statement --- include/sqlpp11/insert.h | 102 --------------------- include/sqlpp11/parameter_list.h | 1 + include/sqlpp11/remove.h | 153 ++----------------------------- include/sqlpp11/statement.h | 2 + include/sqlpp11/vendor/using.h | 123 +++++++++++++++++-------- tests/CMakeLists.txt | 4 +- tests/RemoveTest.cpp | 4 +- 7 files changed, 100 insertions(+), 289 deletions(-) diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index 587906e2..7ed0e7e2 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -38,108 +38,6 @@ namespace sqlpp { -#if 0 - template - struct insert_t; - - namespace detail - { - template - struct insert_policies_t - { - using _database_t = Db; - - using _statement_t = insert_t; - - struct _methods_t: public Policies::template _methods_t... - {}; - - template - struct _policies_update_t - { - static_assert(detail::is_element_of>::value, "policies update for non-policy class detected"); - using type = insert_t...>; - }; - - template - using _new_statement_t = typename _policies_update_t::type; - - 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, _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<>; - }; - }; - } - - // INSERT - template - struct insert_t: - public Policies..., - public detail::insert_policies_t::_methods_t - { - using _policies_t = typename detail::insert_policies_t; - using _database_t = typename _policies_t::_database_t; - - using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - - using _parameter_list_t = typename make_parameter_list_t::type; - - // Constructors - constexpr insert_t() - {} - - template - insert_t(Statement statement, Term term): - Policies(detail::pick_arg(statement, term))... - {} - - insert_t(const insert_t&) = default; - insert_t(insert_t&&) = default; - insert_t& operator=(const insert_t&) = default; - insert_t& operator=(insert_t&&) = default; - ~insert_t() = default; - - }; - - namespace vendor - { - template - struct serializer_t> - { - using T = insert_t; - - static Context& _(const T& t, Context& context) - { - context << "INSERT INTO "; - - using swallow = int[]; - (void) swallow{(serialize(static_cast(t), context), 0)...}; - return context; - } - }; - } -#endif - template using blank_insert_t = statement_t +#include #include #include diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index 2204212b..305af315 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -27,6 +27,7 @@ #ifndef SQLPP_REMOVE_H #define SQLPP_REMOVE_H +#include #include #include #include @@ -36,179 +37,39 @@ #include #include #include -#include - -#include -#include namespace sqlpp { - template - struct remove_t; - - namespace detail - { - template - struct remove_policies_t - { - using _database_t = Db; - using _statement_t = remove_t; - - struct _methods_t: public Policies::template _methods_t... - {}; - - 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 _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, _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 - 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 _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; - - using _parameter_list_t = typename make_parameter_list_t::type; - - // Constructors - constexpr remove_t() - {} - - template - remove_t(Statement statement, Term term): - Policies(detail::pick_arg(statement, term))... - {} - - remove_t(const remove_t&) = default; - remove_t(remove_t&&) = default; - remove_t& operator=(const remove_t&) = default; - remove_t& operator=(remove_t&&) = default; - ~remove_t() = default; - - // run and prepare - static constexpr size_t _get_static_no_of_parameters() - { - return _parameter_list_t::size::value; - } - - size_t _get_no_of_parameters() const - { - return _parameter_list_t::size::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 - std::size_t _run(Database& db) const - { - _check_consistency(); - - static_assert(_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead"); - return db.remove(*this); - } - - template - auto _prepare(Database& db) const - -> prepared_remove_t - { - _check_consistency(); - - return {{}, db.prepare_remove(*this)}; - } - }; - - namespace vendor - { - template - struct serializer_t> - { - using T = remove_t; - - static Context& _(const T& t, Context& context) - { - context << "DELETE FROM "; - using swallow = int[]; - (void) swallow{(serialize(static_cast(t), context), 0)...}; - return context; - } - }; - } - template - using blank_remove_t = remove_t; - constexpr auto remove() + auto remove() -> blank_remove_t { return { blank_remove_t() }; } template - constexpr auto remove_from(Table table) + auto remove_from(Table table) -> decltype(blank_remove_t().from(table)) { return { blank_remove_t().from(table) }; } template - constexpr auto dynamic_remove(const Database&) + auto dynamic_remove(const Database&) -> decltype(blank_remove_t()) { return { blank_remove_t() }; } template - constexpr auto dynamic_remove_from(const Database&, Table table) + auto dynamic_remove_from(const Database&, Table table) -> decltype(blank_remove_t().from(table)) { return { blank_remove_t().from(table) }; diff --git a/include/sqlpp11/statement.h b/include/sqlpp11/statement.h index db442faa..d6f87d84 100644 --- a/include/sqlpp11/statement.h +++ b/include/sqlpp11/statement.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include diff --git a/include/sqlpp11/vendor/using.h b/include/sqlpp11/vendor/using.h index 7a7d7ccf..3731c3c0 100644 --- a/include/sqlpp11/vendor/using.h +++ b/include/sqlpp11/vendor/using.h @@ -37,6 +37,24 @@ namespace sqlpp { namespace vendor { + // USING DATA + template + struct using_data_t + { + using_data_t(Tables... tables): + _tables(tables...) + {} + + using_data_t(const using_data_t&) = default; + using_data_t(using_data_t&&) = default; + using_data_t& operator=(const using_data_t&) = default; + using_data_t& operator=(using_data_t&&) = default; + ~using_data_t() = default; + + std::tuple _tables; + vendor::interpretable_list_t _dynamic_tables; + }; + // USING template struct using_t @@ -52,53 +70,95 @@ namespace sqlpp static_assert(::sqlpp::detail::all_t::value...>::value, "at least one argument is not an table in using()"); - using_t& _using() { return *this; } + // Data + using _data_t = using_data_t; - using_t(Tables... tables): - _tables(tables...) - {} - - using_t(const using_t&) = default; - using_t(using_t&&) = default; - using_t& operator=(const using_t&) = default; - using_t& operator=(using_t&&) = default; - ~using_t() = default; - - template - struct _methods_t + // Member implementation with data and methods + template + struct _impl_t { template - void add_using(Table table) + void add(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()"); + static_assert(_is_dynamic::value, "add must not be called for static using()"); + static_assert(is_table_t
::value, "invalid table argument in add()"); using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t
::value>; - _add_using_impl(table, ok()); // dispatch to prevent compile messages after the static_assert + _add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert } private: template - void _add_using_impl(Table table, const std::true_type&) + void _add_impl(Table table, const std::true_type&) { - return static_cast(this)->_using()._dynamic_tables.emplace_back(table); + return _data._dynamic_tables.emplace_back(table); } template - void _add_using_impl(Table table, const std::false_type&); + void _add_impl(Table table, const std::false_type&); + + public: + _data_t _data; }; + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = using_data_t; - std::tuple _tables; - vendor::interpretable_list_t _dynamic_tables; + _impl_t using_; + _impl_t& operator()() { return using_; } + const _impl_t& operator()() const { return using_; } + + template + static auto _get_member(T t) -> decltype(t.using_) + { + return t.using_; + } + }; + + // Additional methods for the statement + template + struct _methods_t + { + }; }; + // NO USING YET struct no_using_t { using _traits = make_traits; using _recursive_traits = make_recursive_traits<>; + // Data + using _data_t = no_data_t; + + // Member implementation with data and methods + template + struct _impl_t + { + _data_t _data; + }; + + // Member template for adding the named member to a statement + template + struct _member_t + { + using _data_t = no_data_t; + + _impl_t no_using; + _impl_t& operator()() { return no_using; } + const _impl_t& operator()() const { return no_using; } + + template + static auto _get_member(T t) -> decltype(t.no_using) + { + return t.no_using; + } + }; + template struct _methods_t { @@ -110,7 +170,7 @@ namespace sqlpp auto using_(Args... args) -> _new_statement_t> { - return { *static_cast(this), using_t{args...} }; + return { *static_cast(this), using_data_t{args...} }; } template @@ -118,16 +178,16 @@ namespace sqlpp -> _new_statement_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...} }; + return { *static_cast(this), using_data_t<_database_t, Args...>{args...} }; } }; }; // Interpreters template - struct serializer_t> + struct serializer_t> { - using T = using_t; + using T = using_data_t; static Context& _(const T& t, Context& context) { @@ -141,17 +201,6 @@ namespace sqlpp return context; } }; - - template - struct serializer_t - { - using T = no_using_t; - - static Context& _(const T& t, Context& context) - { - return context; - } - }; } } 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) diff --git a/tests/RemoveTest.cpp b/tests/RemoveTest.cpp index f4ce1302..777e944e 100644 --- a/tests/RemoveTest.cpp +++ b/tests/RemoveTest.cpp @@ -60,8 +60,8 @@ int main() serialize(remove_from(t).where(t.beta != "transparent"), printer).str(); serialize(remove_from(t).using_(t), printer).str(); auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where(); - r.add_using(t); - r.add_where(t.beta != "transparent"); + r.using_.add(t); + r.where.add(t.beta != "transparent"); serialize(r, printer).str(); db(r);