mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Added static_assert tests for dynamic from.add()
This commit is contained in:
parent
dec3f5b3df
commit
712c79cb8a
@ -58,6 +58,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_dynamic, "from::add() requires a dynamic_from");
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_dynamic, "from::add() requires a dynamic_from");
|
||||||
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_not_dynamic_pre_join, "join condition missing");
|
||||||
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_dynamic_join, "from::add(X) requires X to be a dynamic join");
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_unique_names,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_add_unique_names,
|
||||||
"from::add() must not add table names already used in from");
|
"from::add() must not add table names already used in from");
|
||||||
@ -66,44 +67,48 @@ namespace sqlpp
|
|||||||
"tables not statically known, use "
|
"tables not statically known, use "
|
||||||
"without_table_check() to express the intent");
|
"without_table_check() to express the intent");
|
||||||
|
|
||||||
|
template <typename From, typename DynamicJoin>
|
||||||
|
struct check_from_add
|
||||||
|
{
|
||||||
|
using _known_tables = provided_tables_of<typename From::_table_t>; // 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<name_of, _known_tables>;
|
||||||
|
using _known_table_names = detail::make_name_of_set_t<_known_tables>;
|
||||||
|
using _joined_tables = provided_tables_of<DynamicJoin>;
|
||||||
|
using _joined_table_names = detail::make_name_of_set_t<_joined_tables>;
|
||||||
|
using _required_tables = required_tables_of<DynamicJoin>;
|
||||||
|
using type = static_combined_check_t<
|
||||||
|
static_check_t<From::_is_dynamic::value, assert_from_add_dynamic>,
|
||||||
|
static_check_t<not is_dynamic_pre_join_t<DynamicJoin>::value, assert_from_add_not_dynamic_pre_join>,
|
||||||
|
static_check_t<is_dynamic_join_t<DynamicJoin>::value, assert_from_add_dynamic_join>,
|
||||||
|
static_check_t<detail::is_disjunct_from<_joined_table_names, _known_table_names>::value,
|
||||||
|
assert_from_add_unique_names>,
|
||||||
|
static_check_t<detail::is_subset_of<_required_tables, _known_tables>::value,
|
||||||
|
assert_from_add_no_required_tables>,
|
||||||
|
sqlpp::serialize_check_t<serializer_context_of<typename From::_database_t>, DynamicJoin>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename From, typename DynamicJoin>
|
||||||
|
using check_from_add_t = typename check_from_add<From, DynamicJoin>::type;
|
||||||
|
|
||||||
// FROM
|
// FROM
|
||||||
template <typename Database, typename Table>
|
template <typename Database, typename Table>
|
||||||
struct from_t
|
struct from_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::is_from>;
|
using _traits = make_traits<no_value_t, tag::is_from>;
|
||||||
using _nodes = detail::type_vector<Table>;
|
using _nodes = detail::type_vector<Table>;
|
||||||
using _is_dynamic = is_database<Database>;
|
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
using _data_t = from_data_t<Database, Table>;
|
using _data_t = from_data_t<Database, Table>;
|
||||||
|
|
||||||
template <typename DynamicJoin>
|
|
||||||
struct check_add
|
|
||||||
{
|
|
||||||
using _known_tables = provided_tables_of<Table>; // 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<name_of, _known_tables>;
|
|
||||||
using _known_table_names = detail::make_name_of_set_t<_known_tables>;
|
|
||||||
using _joined_tables = provided_tables_of<DynamicJoin>;
|
|
||||||
using _joined_table_names = detail::make_name_of_set_t<_joined_tables>;
|
|
||||||
using _required_tables = required_tables_of<DynamicJoin>;
|
|
||||||
using type = static_combined_check_t<
|
|
||||||
static_check_t<_is_dynamic::value, assert_from_add_dynamic>,
|
|
||||||
static_check_t<is_dynamic_join_t<DynamicJoin>::value, assert_from_add_dynamic_join>,
|
|
||||||
static_check_t<detail::is_disjunct_from<_joined_table_names, _known_table_names>::value,
|
|
||||||
assert_from_add_unique_names>,
|
|
||||||
static_check_t<detail::is_subset_of<_required_tables, _known_tables>::value,
|
|
||||||
assert_from_add_no_required_tables>,
|
|
||||||
sqlpp::serialize_check_t<typename Database::_serializer_context_t, DynamicJoin>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DynamicJoin>
|
|
||||||
using check_add_t = typename check_add<DynamicJoin>::type;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
// Member implementation with data and methods
|
||||||
template <typename Policies>
|
template <typename Policies>
|
||||||
struct _impl_t
|
struct _impl_t
|
||||||
{
|
{
|
||||||
|
using _database_t = Database;
|
||||||
|
using _is_dynamic = is_database<_database_t>;
|
||||||
|
using _table_t = Table;
|
||||||
|
|
||||||
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
|
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
|
||||||
_impl_t() = default;
|
_impl_t() = default;
|
||||||
_impl_t(const _data_t& data) : _data(data)
|
_impl_t(const _data_t& data) : _data(data)
|
||||||
@ -112,9 +117,9 @@ namespace sqlpp
|
|||||||
|
|
||||||
template <typename DynamicJoin>
|
template <typename DynamicJoin>
|
||||||
auto add(DynamicJoin dynamicJoin) ->
|
auto add(DynamicJoin dynamicJoin) ->
|
||||||
typename std::conditional<check_add_t<DynamicJoin>::value, void, bad_statement>::type
|
typename std::conditional<check_from_add_t<_impl_t, DynamicJoin>::value, void, bad_statement>::type
|
||||||
{
|
{
|
||||||
using Check = check_add_t<DynamicJoin>;
|
using Check = check_from_add_t<_impl_t, DynamicJoin>;
|
||||||
Check::_();
|
Check::_();
|
||||||
return _add_impl(dynamicJoin, Check{});
|
return _add_impl(dynamicJoin, Check{});
|
||||||
}
|
}
|
||||||
|
@ -502,6 +502,24 @@ namespace sqlpp
|
|||||||
|
|
||||||
template <typename Statement, template <typename> class Predicate>
|
template <typename Statement, template <typename> class Predicate>
|
||||||
using has_policy_t = typename has_policy_impl<Statement, Predicate>::type;
|
using has_policy_t = typename has_policy_impl<Statement, Predicate>::type;
|
||||||
|
|
||||||
|
struct no_context_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <typename Db, typename = void>
|
||||||
|
struct serializer_context_of_impl
|
||||||
|
{
|
||||||
|
using type = no_context_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Db>
|
||||||
|
struct serializer_context_of_impl<Db, detail::void_t<typename Db::_serializer_context_t>>
|
||||||
|
{
|
||||||
|
using type = typename Db::_serializer_context_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Db>
|
||||||
|
using serializer_context_of = typename serializer_context_of_impl<Db>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -111,9 +111,56 @@ namespace
|
|||||||
from_dynamic_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
|
from_dynamic_check<sqlpp::assert_from_not_pre_join_t>(t.join(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Assert, typename FromImpl, typename Expression>
|
||||||
|
void dynamic_from_add_check(FromImpl from, const Expression& expression)
|
||||||
|
{
|
||||||
|
using CheckResult = sqlpp::check_from_add_t<FromImpl, Expression>;
|
||||||
|
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
|
||||||
|
print_type_on_error<CheckResult>(ExpectedCheckResult{});
|
||||||
|
static_assert(ExpectedCheckResult::value, "Unexpected check result");
|
||||||
|
|
||||||
|
using ReturnType = decltype(from.add(expression));
|
||||||
|
using ExpectedReturnType =
|
||||||
|
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
|
||||||
|
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||||
|
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||||
|
}
|
||||||
|
|
||||||
void dynamic_from_add()
|
void dynamic_from_add()
|
||||||
{
|
{
|
||||||
#warning : need to add tests for dynamic_from(xxx).add(yyy)
|
static auto db = MockDb{};
|
||||||
|
auto fromT = dynamic_select(db, t.alpha).dynamic_from(t).from;
|
||||||
|
auto staticFrom = dynamic_select(db, t.alpha).from(t).from;
|
||||||
|
const auto fa = f.as(sqlpp::alias::a);
|
||||||
|
|
||||||
|
// OK
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_join(f).on(t.alpha > f.omega));
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_inner_join(f).on(t.alpha > f.omega));
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_left_outer_join(f).on(t.alpha > f.omega));
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_right_outer_join(f).on(t.alpha > f.omega));
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_outer_join(f).on(t.alpha > f.omega));
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_cross_join(f));
|
||||||
|
|
||||||
|
// Try a bunch of non dynamic joins
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_dynamic>(staticFrom, 7);
|
||||||
|
|
||||||
|
// Try a bunch of non dynamic joins
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_dynamic_join>(fromT, 7);
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_dynamic_join>(fromT, t.gamma);
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_dynamic_join>(fromT, join(f, f.as(sqlpp::alias::a)));
|
||||||
|
|
||||||
|
// Try incomplete dynamic join
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_not_dynamic_pre_join>(fromT, dynamic_join(f));
|
||||||
|
|
||||||
|
// Try joining the same table name
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_unique_names>(fromT, dynamic_cross_join(t));
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_unique_names>(fromT, dynamic_cross_join(f.as(t)));
|
||||||
|
|
||||||
|
// Try joining with a condition that requires other tables
|
||||||
|
dynamic_from_add_check<sqlpp::assert_from_add_no_required_tables>(fromT, dynamic_join(f).on(t.alpha > fa.omega));
|
||||||
|
|
||||||
|
// If you really think you know what you are doing, use without_table_check
|
||||||
|
dynamic_from_add_check<sqlpp::consistent_t>(fromT, dynamic_join(f).on(t.alpha > without_table_check(fa.omega)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user