diff --git a/include/sqlpp11/cross_join.h b/include/sqlpp11/cross_join.h index a0e97b74..b5ea2a6f 100644 --- a/include/sqlpp11/cross_join.h +++ b/include/sqlpp11/cross_join.h @@ -53,6 +53,35 @@ namespace sqlpp template using check_cross_join_t = typename check_cross_join::type; + SQLPP_PORTABLE_STATIC_ASSERT(assert_join_consist_of_cross_join_and_on_t, + "join has to consist of a cross_join and a join condition"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_join_no_table_dependencies_t, "joined tables must not depend on other tables"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_join_on_no_foreign_table_dependencies_t, + "on() condition must not depend on other tables"); + + template + struct check_join + { + using type = static_combined_check_t< + static_check_t::value, assert_join_consist_of_cross_join_and_on_t>, + static_check_t::value, assert_join_consist_of_cross_join_and_on_t>, + static_check_t::size::value == 0, assert_join_no_table_dependencies_t>, + static_check_t, provided_tables_of>::value, + assert_join_on_no_foreign_table_dependencies_t>>; + }; + + template + using check_join_t = typename check_join::type; + + template + struct check_join_on + { + using type = static_combined_check_t, check_join_t>>; + }; + + template + using check_join_on_t = typename check_join_on::type; + template struct join_t; @@ -73,16 +102,16 @@ namespace sqlpp static_assert(required_tables_of::size::value == 0, "joined tables must not depend on other tables"); template - auto on(Expr expr) -> join_t> + auto on(Expr expr) -> typename std::conditional::value, + join_t>, + bad_statement>::type { - static_assert(is_expression_t::value, "argument is not an expression in on()"); + check_join_on_t::_(); - static_assert(is_boolean_t::value, "argument is not a boolean expression in on()"); - - return {*this, {expr, {}}}; + return {*this, {expr}}; } - auto unconditionally() -> join_t> + auto unconditionally() -> join_t> { return {*this, {}}; } diff --git a/include/sqlpp11/dynamic_cross_join.h b/include/sqlpp11/dynamic_cross_join.h index 325dbf23..3c2dfec4 100644 --- a/include/sqlpp11/dynamic_cross_join.h +++ b/include/sqlpp11/dynamic_cross_join.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, Roland Bock + * Copyright (c) 2016-2016, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -32,6 +32,32 @@ namespace sqlpp { + SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_consist_of_cross_join_and_on_t, + "dynamic join has to consist of a dynamic cross_join and a join condition"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_dynamic_join_no_table_dependencies_t, + "dynamically joined tables must not depend on other tables"); + + template + struct check_dynamic_join + { + using type = static_combined_check_t< + static_check_t::value, assert_dynamic_join_consist_of_cross_join_and_on_t>, + static_check_t::value, assert_dynamic_join_consist_of_cross_join_and_on_t>, + static_check_t::size::value == 0, assert_dynamic_join_no_table_dependencies_t>>; + }; + + template + using check_dynamic_join_t = typename check_dynamic_join::type; + + template + struct check_dynamic_join_on + { + using type = static_combined_check_t, check_dynamic_join_t>>; + }; + + template + using check_dynamic_join_on_t = typename check_dynamic_join_on::type; + template struct dynamic_join_t; @@ -49,15 +75,16 @@ namespace sqlpp "joined tables must not depend on other tables"); template - auto on(Expr expr) -> dynamic_join_t> + auto on(Expr expr) -> typename std::conditional::value, + dynamic_join_t>, + bad_statement>::type { - static_assert(is_expression_t::value, "argument is not a boolean expression in on()"); - static_assert(is_boolean_t::value, "argument is not a boolean expression in on()"); + check_dynamic_join_on_t::_(); - return {*this, {expr, {}}}; + return {*this, {expr}}; } - auto unconditionally() -> dynamic_join_t> + auto unconditionally() -> dynamic_join_t> { return {*this, {}}; } diff --git a/include/sqlpp11/dynamic_join.h b/include/sqlpp11/dynamic_join.h index 6316c610..90cb3045 100644 --- a/include/sqlpp11/dynamic_join.h +++ b/include/sqlpp11/dynamic_join.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, Roland Bock + * Copyright (c) 2016-2016, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index 26198688..8679cf02 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -42,13 +42,6 @@ namespace sqlpp using _provided_tables = provided_tables_of; using _required_tables = detail::make_difference_set_t, _provided_tables>; - static_assert(is_cross_join_t::value, "lhs argument for join() has to be a table or join"); - static_assert(is_on_t::value, "invalid on expression in join().on()"); - - static_assert(required_tables_of::size::value == 0, "joined tables must not depend on other tables"); - static_assert(detail::is_subset_of, provided_tables_of>::value, - "on() condition must not depend on other tables"); - template auto join(T t) const -> decltype(::sqlpp::join(*this, t)) { diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index 58fb3996..f3ba3a04 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -34,54 +34,40 @@ namespace sqlpp { - template + SQLPP_PORTABLE_STATIC_ASSERT(assert_on_is_expression_t, "argument is not an expression in on()"); + SQLPP_PORTABLE_STATIC_ASSERT(assert_on_is_boolean_expression_t, "argument is not a boolean expression in on()"); + + template + struct check_on + { + using type = static_combined_check_t::value, assert_on_is_expression_t>, + static_check_t::value, assert_on_is_boolean_expression_t>>; + }; + + template + using check_on_t = typename check_on::type; + + template struct on_t { using _traits = make_traits; using _nodes = detail::type_vector; - using _is_dynamic = is_database; - - template - void add(Expr expr) - { - static_assert(_is_dynamic::value, "on::add() must not be called for static on()"); - static_assert(is_expression_t::value, "invalid expression argument in on::add()"); - using _serialize_check = sqlpp::serialize_check_t; - _serialize_check::_(); - - using ok = logic::all_t<_is_dynamic::value, is_expression_t::value, _serialize_check::type::value>; - - _add_impl(expr, ok()); // dispatch to prevent compile messages after the static_assert - } - - private: - template - void _add_impl(Expr expr, const std::true_type&) - { - return _dynamic_expressions.emplace_back(expr); - } - - template - void _add_impl(Expr expr, const std::false_type&); - - public: Expression _expression; - interpretable_list_t _dynamic_expressions; }; template <> - struct on_t + struct on_t { using _traits = make_traits; using _nodes = detail::type_vector<>; }; template - struct serializer_t> + struct serializer_t> { using _serialize_check = consistent_t; - using T = on_t; + using T = on_t; static Context& _(const T&, Context& context) { @@ -89,21 +75,16 @@ namespace sqlpp } }; - template - struct serializer_t> + template + struct serializer_t> { - using _serialize_check = serialize_check_of; - using T = on_t; + using _serialize_check = serialize_check_of; + using T = on_t; static Context& _(const T& t, Context& context) { - if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty()) - return context; context << " ON ("; serialize(t._expression, context); - if (not t._dynamic_expressions.empty()) - context << " AND "; - interpret_list(t._dynamic_expressions, " AND ", context); context << " )"; return context; }