diff --git a/include/sqlpp11/from.h b/include/sqlpp11/from.h index e778e1fc..751e41e7 100644 --- a/include/sqlpp11/from.h +++ b/include/sqlpp11/from.h @@ -57,6 +57,15 @@ namespace sqlpp interpretable_list_t _dynamic_tables; }; + SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_dynamic, "from::add() requires a dynamic_from"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_dynamic_join, "from::add(X) requires X to be a dynamic join"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_unique_names, + "from::add() must not add table names already used in from"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_no_required_tables, + "from::add():dynamic join condition depends on " + "tables not statically known, use " + "without_table_check() to express the intent"); + // FROM template struct from_t @@ -68,6 +77,29 @@ namespace sqlpp // Data using _data_t = from_data_t; + template + struct check_add + { + using _known_tables = provided_tables_of; // Hint: Joins contain more than one table + // workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198 + // using _known_table_names = detail::transform_set_t; + using _known_table_names = detail::make_name_of_set_t<_known_tables>; + using _joined_tables = provided_tables_of; + using _joined_table_names = detail::make_name_of_set_t<_joined_tables>; + using _required_tables = required_tables_of; + using type = static_combined_check_t< + static_check_t<_is_dynamic::value, assert_from_add_dynamic>, + static_check_t::value, assert_from_add_dynamic_join>, + static_check_t::value, + assert_from_add_unique_names>, + static_check_t::value, + assert_from_add_no_required_tables>, + sqlpp::serialize_check_t>; + }; + + template + using check_add_t = typename check_add::type; + // Member implementation with data and methods template struct _impl_t @@ -79,28 +111,12 @@ namespace sqlpp } template - void add(DynamicJoin dynamicJoin) + auto add(DynamicJoin dynamicJoin) -> + typename std::conditional::value, void, bad_statement>::type { - static_assert(_is_dynamic::value, "from::add() must not be called for static from()"); - static_assert(is_dynamic_join_t::value, "invalid argument in from::add(), expected dynamic_join"); - using _known_tables = provided_tables_of
; // Hint: Joins contain more than one table - // workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198 - // using _known_table_names = detail::transform_set_t; - using _known_table_names = detail::make_name_of_set_t<_known_tables>; - using _joined_tables = provided_tables_of; - using _joined_table_names = detail::make_name_of_set_t<_joined_tables>; - static_assert(detail::is_disjunct_from<_joined_table_names, _known_table_names>::value, - "Must not use the same table name twice in from()"); - using _required_tables = required_tables_of; - static_assert(detail::is_subset_of<_required_tables, _known_tables>::value, - "dynamic join condition depends on tables not statically known, use without_table_check() to " - "express the intent"); - using _serialize_check = sqlpp::serialize_check_t; - _serialize_check::_(); - - using ok = logic::all_t<_is_dynamic::value, is_table_t::value, _serialize_check::type::value>; - - _add_impl(dynamicJoin, ok()); // dispatch to prevent compile messages after the static_assert + using Check = check_add_t; + Check::_(); + return _add_impl(dynamicJoin, Check{}); } private: @@ -111,7 +127,7 @@ namespace sqlpp } template - auto _add_impl(DynamicJoin dynamicJoin, const std::false_type&) -> void; + auto _add_impl(DynamicJoin dynamicJoin, const std::false_type&) -> bad_statement; public: _data_t _data;