diff --git a/include/sqlpp11/core/basic/column.h b/include/sqlpp11/core/basic/column.h index 4e74fdba..ae6750d4 100644 --- a/include/sqlpp11/core/basic/column.h +++ b/include/sqlpp11/core/basic/column.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include namespace sqlpp { @@ -104,13 +104,18 @@ namespace sqlpp { }; - template - struct table_t; + template + struct table_t; template struct required_tables_of> { - using type = detail::type_set>; + using type = detail::type_vector>; + }; + + template + struct required_static_tables_of> : public required_tables_of> + { }; template diff --git a/include/sqlpp11/core/basic/join.h b/include/sqlpp11/core/basic/join.h index 3b132b52..9fdc5fa1 100644 --- a/include/sqlpp11/core/basic/join.h +++ b/include/sqlpp11/core/basic/join.h @@ -67,18 +67,36 @@ namespace sqlpp #warning: We should mix dynamic and optional into the provided_tables_of (instead of having separate traits for each). #warning: it might be great to search for missing tables and return something like `missing_table_for>`. + template + struct is_dynamic : public std::false_type {}; + template + struct is_dynamic> : public std::true_type {}; + + template + struct provided_tables_of> + { + using type = detail::type_vector_cat_t, provided_tables_of_t>; + }; + + template + struct provided_static_tables_of> + { + using type = typename std::conditional< + is_dynamic::value, + provided_static_tables_of, + detail::type_vector_cat_t, provided_static_tables_of>>::type; + }; + template struct provided_optional_tables_of> { - using type = typename std::conditional< - std::is_same::value, - sqlpp::detail::type_set, - typename std::conditional< - std::is_same::value, - sqlpp::detail::type_set, - typename std::conditional::value, - detail::make_joined_set_t, provided_tables_of_t>, - detail::type_set<>>::type>::type>::type; + using type = detail::type_vector_cat_t< + typename std::conditional::contains(), + provided_tables_of_t, + detail::type_vector<>>::type, + typename std::conditional::contains(), + provided_tables_of_t, + detail::type_vector<>>::type>; }; template @@ -124,8 +142,36 @@ namespace sqlpp #warning: Verify that the Expr does not require tables other than Lhs, Rhs //and detail::make_joined_set_t, provided_tables_of_t>::is_superset_of::value + template + struct are_table_requirements_satisfied + : std::integral_constant{}) and + AllTableTypeVector::contains_all(required_tables_of_t{})> + { + }; + template - using check_on_args = sqlpp::enable_if_t::value>; + struct are_join_table_requirements_satisfied + : public std::integral_constant< + bool, + is_dynamic::value ? + // In case of a dynamic join, we can use all tables in the ON expr. + are_table_requirements_satisfied< + Expr, + provided_tables_of_t>, + provided_tables_of_t>>::value + : + // In case of a static join, we can use static tables in the static part of the ON + // expression and dynamic tables in any potential dynamic part of the expression. + are_table_requirements_satisfied< + Expr, + provided_static_tables_of_t>, + provided_tables_of_t>>::value> + { + }; + + template + using check_on_args = sqlpp::enable_if_t::value and are_join_table_requirements_satisfied::value>; template struct pre_join_t @@ -133,7 +179,7 @@ namespace sqlpp template > auto on(Expr expr) const -> join_t { - return {_lhs, _rhs, std::move(expr)}; + return {_lhs, _rhs, std::move(expr)}; } Lhs _lhs; diff --git a/include/sqlpp11/core/basic/table.h b/include/sqlpp11/core/basic/table.h index e4fb1179..19128f10 100644 --- a/include/sqlpp11/core/basic/table.h +++ b/include/sqlpp11/core/basic/table.h @@ -69,6 +69,16 @@ namespace sqlpp using type = sqlpp::detail::type_set>; }; + template + struct provided_static_tables_of> : public provided_tables_of> + { + }; + + template + struct provided_optional_tables_of> : public provided_tables_of> + { + }; + template auto to_sql_string(Context& context, const table_t& /*unused*/) -> std::string { diff --git a/include/sqlpp11/core/clause/where.h b/include/sqlpp11/core/clause/where.h index e4715d69..7b066b1f 100644 --- a/include/sqlpp11/core/clause/where.h +++ b/include/sqlpp11/core/clause/where.h @@ -159,7 +159,7 @@ namespace sqlpp using _new_statement_t = new_statement_t; using _consistency_check = - typename std::conditional 0), + typename std::conditional 0), assert_where_or_unconditionally_called_t, consistent_t>::type; diff --git a/include/sqlpp11/core/detail/type_vector.h b/include/sqlpp11/core/detail/type_vector.h index 9bf4d633..c727fafa 100644 --- a/include/sqlpp11/core/detail/type_vector.h +++ b/include/sqlpp11/core/detail/type_vector.h @@ -36,16 +36,26 @@ namespace sqlpp template struct type_vector { - template - using contains = std::integral_constant::value...>::value>; + template + static constexpr bool contains() + { + return ::sqlpp::logic::any::value...>::value; + } - template