0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 12:51:13 +08:00

Continued required/provided table improvements

This commit is contained in:
Roland Bock 2024-08-30 13:28:12 +02:00
parent 9349f56d68
commit 31cb9c31ab
11 changed files with 38 additions and 57 deletions

View File

@ -28,6 +28,7 @@
#include <sqlpp11/core/basic/join_fwd.h> #include <sqlpp11/core/basic/join_fwd.h>
#include <sqlpp11/core/basic/enable_join.h> #include <sqlpp11/core/basic/enable_join.h>
#include <sqlpp11/core/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -57,21 +58,6 @@ namespace sqlpp
using type = sqlpp::detail::type_vector<Lhs, Rhs, Condition>; using type = sqlpp::detail::type_vector<Lhs, Rhs, Condition>;
}; };
template <typename Lhs, typename JoinType, typename Rhs, typename Condition>
struct provided_tables_of<join_t<Lhs, JoinType, dynamic_t<Rhs>, Condition>>
{
using type = detail::make_joined_set_t<provided_tables_of_t<Lhs>, detail::type_set<dynamic_t<Rhs>>>;
};
#warning: We need to quarantee that no tables are required by join and dynamic provision vs requirements need to be checked upon calling `on`.
#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<column_t<SomeSpec>>`.
template<typename T>
struct is_dynamic : public std::false_type {};
template<typename T>
struct is_dynamic<dynamic_t<T>> : public std::true_type {};
template <typename Lhs, typename JoinType, typename Rhs, typename Condition> template <typename Lhs, typename JoinType, typename Rhs, typename Condition>
struct provided_tables_of<join_t<Lhs, JoinType, Rhs, Condition>> struct provided_tables_of<join_t<Lhs, JoinType, Rhs, Condition>>
{ {
@ -83,8 +69,8 @@ namespace sqlpp
{ {
using type = typename std::conditional< using type = typename std::conditional<
is_dynamic<Rhs>::value, is_dynamic<Rhs>::value,
provided_static_tables_of<Lhs>, provided_static_tables_of_t<Lhs>,
detail::type_vector_cat_t<provided_static_tables_of<Lhs>, provided_static_tables_of<Rhs>>>::type; detail::type_vector_cat_t<provided_static_tables_of_t<Lhs>, provided_static_tables_of_t<Rhs>>>::type;
}; };
template <typename Lhs, typename JoinType, typename Rhs, typename Condition> template <typename Lhs, typename JoinType, typename Rhs, typename Condition>
@ -141,7 +127,6 @@ namespace sqlpp
} }
#warning: Verify that the Expr does not require tables other than Lhs, Rhs #warning: Verify that the Expr does not require tables other than Lhs, Rhs
//and detail::make_joined_set_t<provided_tables_of_t<Lhs>, provided_tables_of_t<Rhs>>::is_superset_of<required_tables_of_t<Expr>::value
template <typename Expr, typename StaticTableTypeVector, typename AllTableTypeVector> template <typename Expr, typename StaticTableTypeVector, typename AllTableTypeVector>
struct are_table_requirements_satisfied struct are_table_requirements_satisfied
: std::integral_constant<bool, : std::integral_constant<bool,

View File

@ -30,7 +30,7 @@
#include <sqlpp11/core/query/dynamic.h> #include <sqlpp11/core/query/dynamic.h>
#include <sqlpp11/core/type_traits.h> #include <sqlpp11/core/type_traits.h>
#include <sqlpp11/core/compat/type_traits.h> #include <sqlpp11/core/compat/type_traits.h>
#include <sqlpp11/core/detail/type_set.h> #include <sqlpp11/core/detail/type_vector.h>
namespace sqlpp namespace sqlpp
{ {
@ -69,9 +69,9 @@ namespace sqlpp
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
using check_join_args = using check_join_args =
sqlpp::enable_if_t<is_table<Lhs>::value and is_table<remove_dynamic_t<Rhs>>::value and sqlpp::enable_if_t<is_table<Lhs>::value and is_table<remove_dynamic_t<Rhs>>::value and
required_tables_of_t<Lhs>::size::value == 0 and required_tables_of_t<Rhs>::size::value == 0 and required_tables_of_t<Lhs>::empty() and required_tables_of_t<Rhs>::empty() and
detail::is_disjunct_from<detail::make_name_of_set_t<provided_tables_of_t<Lhs>>, sqlpp::detail::transform_t<provided_tables_of_t<Lhs>, make_char_sequence>::contains_none(
detail::make_name_of_set_t<provided_tables_of_t<Rhs>>>::value>; sqlpp::detail::transform_t<provided_tables_of_t<Rhs>, make_char_sequence>{})>;
template <typename Lhs, typename Rhs, typename = check_join_args<Lhs, Rhs>> template <typename Lhs, typename Rhs, typename = check_join_args<Lhs, Rhs>>
auto join(Lhs lhs, Rhs rhs) -> pre_join_t<Lhs, inner_join_t, Rhs>; auto join(Lhs lhs, Rhs rhs) -> pre_join_t<Lhs, inner_join_t, Rhs>;

View File

@ -31,7 +31,7 @@
#include <sqlpp11/core/basic/table_alias.h> #include <sqlpp11/core/basic/table_alias.h>
#include <sqlpp11/core/basic/all_of.h> #include <sqlpp11/core/basic/all_of.h>
#include <sqlpp11/core/basic/column.h> #include <sqlpp11/core/basic/column.h>
#include <sqlpp11/core/detail/type_set.h> #include <sqlpp11/core/detail/type_vector.h>
#include <sqlpp11/core/basic/join.h> #include <sqlpp11/core/basic/join.h>
namespace sqlpp namespace sqlpp
@ -66,7 +66,7 @@ namespace sqlpp
template <typename TableSpec> template <typename TableSpec>
struct provided_tables_of<table_t<TableSpec>> struct provided_tables_of<table_t<TableSpec>>
{ {
using type = sqlpp::detail::type_set<table_t<TableSpec>>; using type = sqlpp::detail::type_vector<table_t<TableSpec>>;
}; };
template <typename TableSpec> template <typename TableSpec>

View File

@ -76,7 +76,6 @@ namespace sqlpp
"from() argument is a pre join, please use an explicit on() condition or unconditionally()"); "from() argument is a pre join, please use an explicit on() condition or unconditionally()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_table_t, "from() argument has to be a table or join expression"); SQLPP_PORTABLE_STATIC_ASSERT(assert_from_table_t, "from() argument has to be a table or join expression");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_dependency_free_t, "at least one table depends on another table in from()"); SQLPP_PORTABLE_STATIC_ASSERT(assert_from_dependency_free_t, "at least one table depends on another table in from()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_from_no_duplicates_t, "at least one duplicate table name detected in from()");
template <typename Table> template <typename Table>
struct check_from struct check_from
@ -84,10 +83,8 @@ namespace sqlpp
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<not is_pre_join_t<Table>::value, assert_from_not_pre_join_t>, static_check_t<not is_pre_join_t<Table>::value, assert_from_not_pre_join_t>,
static_check_t<is_table<Table>::value, assert_from_table_t>, static_check_t<is_table<Table>::value, assert_from_table_t>,
static_check_t<required_tables_of_t<Table>::size::value == 0, assert_from_dependency_free_t>, static_check_t<required_tables_of_t<Table>::size::value == 0, assert_from_dependency_free_t>
static_check_t<provided_tables_of_t<Table>::size::value == >;
detail::make_name_of_set_t<provided_tables_of_t<Table>>::size::value,
assert_from_no_duplicates_t>>;
}; };
template <typename Table> template <typename Table>

View File

@ -260,21 +260,5 @@ namespace sqlpp
template <template <typename> class Transformation, typename T> template <template <typename> class Transformation, typename T>
using transform_set_t = typename transform_set<Transformation, T>::type; using transform_set_t = typename transform_set<Transformation, T>::type;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198
template <typename T>
struct make_name_of_set
{
static_assert(wrong_t<make_name_of_set>::value, "invalid argument for make_name_of_set");
};
template <typename... E>
struct make_name_of_set<type_set<E...>>
{
using type =
make_type_set_t<make_char_sequence<sizeof(sqlpp::name_tag_of_t<E>::name), sqlpp::name_tag_of_t<E>::name>...>;
};
template <typename T>
using make_name_of_set_t = typename make_name_of_set<T>::type;
} // namespace detail } // namespace detail
} // namespace sqlpp } // namespace sqlpp

View File

@ -48,6 +48,12 @@ namespace sqlpp
return ::sqlpp::logic::all<contains<X>()...>::value; return ::sqlpp::logic::all<contains<X>()...>::value;
} }
template <typename... X>
static constexpr bool contains_none(type_vector<X...>)
{
return ::sqlpp::logic::none<contains<X>()...>::value;
}
static constexpr size_t size() static constexpr size_t size()
{ {
return sizeof...(T); return sizeof...(T);

View File

@ -45,8 +45,13 @@ namespace sqlpp
using type = char_sequence<s[i]...>; using type = char_sequence<s[i]...>;
}; };
template <std::size_t N, const char* Input> template <typename T>
using make_char_sequence = struct make_char_sequence
typename make_char_sequence_impl<N, Input, ::sqlpp::make_index_sequence<N - 1>>::type; : make_char_sequence_impl<sizeof(sqlpp::name_tag_of_t<T>::name), sqlpp::name_tag_of_t<T>::name, ::sqlpp::make_index_sequence<sizeof(sqlpp::name_tag_of_t<T>::name) - 1>>
{
};
template <typename T>
using make_char_sequence_t = typename make_char_sequence<T>::type;
} // namespace sqlpp } // namespace sqlpp

View File

@ -77,7 +77,7 @@ namespace sqlpp
using _all_required_ctes = detail::make_joined_set_t<required_ctes_of<Policies>...>; using _all_required_ctes = detail::make_joined_set_t<required_ctes_of<Policies>...>;
using _all_provided_ctes = detail::make_joined_set_t<provided_ctes_of<Policies>...>; using _all_provided_ctes = detail::make_joined_set_t<provided_ctes_of<Policies>...>;
using _all_required_tables = detail::make_joined_set_t<required_tables_of_t<Policies>...>; using _all_required_tables = detail::type_vector_cat_t<required_tables_of_t<Policies>...>;
using _all_provided_tables = detail::type_vector_cat_t<provided_tables_of_t<Policies>...>; using _all_provided_tables = detail::type_vector_cat_t<provided_tables_of_t<Policies>...>;
//using _all_provided_outer_tables = detail::make_joined_set_t<provided_optional_tables_of_t<Policies>...>; //using _all_provided_outer_tables = detail::make_joined_set_t<provided_optional_tables_of_t<Policies>...>;
using _all_provided_aggregates = detail::make_joined_set_t<provided_aggregates_of<Policies>...>; using _all_provided_aggregates = detail::make_joined_set_t<provided_aggregates_of<Policies>...>;

View File

@ -82,14 +82,19 @@ namespace sqlpp
template <typename T> template <typename T>
struct can_be_null : public is_optional<value_type_of_t<T>> {}; struct can_be_null : public is_optional<value_type_of_t<T>> {};
#warning: remove this
template <typename T> template <typename T>
struct is_not_cpp_bool_t struct dynamic_t;
template <typename T>
struct is_dynamic : public std::false_type
{
};
template <typename T>
struct is_dynamic<dynamic_t<T>> : public std::true_type
{ {
static constexpr bool value = not std::is_same<T, bool>::value;
}; };
//
template <typename L, typename R> template <typename L, typename R>
struct values_are_comparable struct values_are_comparable
: public std::integral_constant<bool, : public std::integral_constant<bool,
@ -102,7 +107,6 @@ namespace sqlpp
{ {
}; };
template<typename T> template<typename T>
struct result_value {}; struct result_value {};

View File

@ -28,11 +28,10 @@
#include <sqlpp11/core/type_traits/nodes_of.h> #include <sqlpp11/core/type_traits/nodes_of.h>
#include <sqlpp11/core/detail/type_vector.h> #include <sqlpp11/core/detail/type_vector.h>
#include <sqlpp11/core/detail/type_set.h>
namespace sqlpp namespace sqlpp
{ {
// required_tables_of determines the type_set of tables referenced by columns within within T. // required_tables_of determines the type_vector of tables referenced by columns within within T.
// column_t or other structs that might reference a table shall specialize this template to indicate their table // column_t or other structs that might reference a table shall specialize this template to indicate their table
// requirement. // requirement.
// Dynamic parts of a query shall wrap their required tables in dynamic_t. // Dynamic parts of a query shall wrap their required tables in dynamic_t.
@ -69,7 +68,7 @@ namespace sqlpp
#warning: need type tests... #warning: need type tests...
//static_assert(required_tables_of_t<int>::size::value == 0, ""); //static_assert(required_tables_of_t<int>::size::value == 0, "");
// provided_tables_of determines the type_set of tables provided by the query clause, e.g. by FROM. // provided_tables_of determines the type_vector of tables provided by the query clause, e.g. by FROM.
// Provided tables can be wrapped in dynamic_t if they are provided through a dynamic join. // Provided tables can be wrapped in dynamic_t if they are provided through a dynamic join.
// table_t, cte_ref_t, or other structs that might provide a table in a query need to specialize this template. // table_t, cte_ref_t, or other structs that might provide a table in a query need to specialize this template.
template <typename T> template <typename T>

View File

@ -65,6 +65,7 @@ int main(int, char* [])
#warning: Need to add tests with 3 tables #warning: Need to add tests with 3 tables
#warning: Need to add tests with sub selects
#warning: Need to add tests with CTEs #warning: Need to add tests with CTEs
return 0; return 0;
} }