0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

Disallow unconditional join (ifdef to get it back)

One day, users of the library have to make the switch anyway, why not
today?
This commit is contained in:
rbock 2016-02-26 20:00:34 +01:00
parent 5e96551f83
commit 15247504f2
2 changed files with 39 additions and 59 deletions

View File

@ -39,17 +39,11 @@
namespace sqlpp namespace sqlpp
{ {
#ifdef SQLPP_ALLOW_UNCONDITIONAL_JOIN
constexpr bool allow_unconditional_from = 1;
#else
constexpr bool allow_unconditional_from = 0;
#endif
// FROM DATA // FROM DATA
template <typename Database, typename... Tables> template <typename Database, typename Table>
struct from_data_t struct from_data_t
{ {
from_data_t(Tables... tables) : _tables(tables...) from_data_t(Table table) : _table(table)
{ {
} }
@ -59,20 +53,20 @@ namespace sqlpp
from_data_t& operator=(from_data_t&&) = default; from_data_t& operator=(from_data_t&&) = default;
~from_data_t() = default; ~from_data_t() = default;
std::tuple<Tables...> _tables; Table _table;
interpretable_list_t<Database> _dynamic_tables; interpretable_list_t<Database> _dynamic_tables;
}; };
// FROM // FROM
template <typename Database, typename... Tables> 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<Tables...>; using _nodes = detail::type_vector<Table>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
// Data // Data
using _data_t = from_data_t<Database, Tables...>; using _data_t = from_data_t<Database, Table>;
// Member implementation with data and methods // Member implementation with data and methods
template <typename Policies> template <typename Policies>
@ -88,12 +82,8 @@ namespace sqlpp
void add(DynamicJoin dynamicJoin) void add(DynamicJoin dynamicJoin)
{ {
static_assert(_is_dynamic::value, "from::add() must not be called for static from()"); static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
static_assert( static_assert(is_dynamic_join_t<DynamicJoin>::value, "invalid argument in from::add(), expected dynamic_join");
is_dynamic_join_t<DynamicJoin>::value or (allow_unconditional_from and is_table_t<DynamicJoin>::value), using _known_tables = provided_tables_of<Table>; // Hint: Joins contain more than one table
"invalid argument in from::add(), or #define ALLOW_UNCONDITIONAL_JOIN "
"for a grace period of using tables here");
using _known_tables =
detail::make_joined_set_t<provided_tables_of<Tables>...>; // Hint: Joins contain more than one table
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198 // 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::transform_set_t<name_of, _known_tables>;
using _known_table_names = detail::make_name_of_set_t<_known_tables>; using _known_table_names = detail::make_name_of_set_t<_known_tables>;
@ -127,7 +117,7 @@ namespace sqlpp
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = from_data_t<Database, Tables...>; using _data_t = from_data_t<Database, 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
template <typename... Args> template <typename... Args>
@ -222,44 +212,35 @@ namespace sqlpp
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename Table, typename... Tables> template <typename Table>
auto from(Table table, Tables... tables) const auto from(Table table) const -> _new_statement_t<_check<Table>, from_t<void, from_table_t<Table>>>
-> _new_statement_t<_check<Table, Tables...>, from_t<void, from_table_t<Table>, from_table_t<Tables>...>>
{ {
static_assert(_check<Table, Tables...>::value, "at least one argument is not a table or join in from()"); static_assert(_check<Table>::value, "argument is not a table or join in from()");
static_assert(sizeof...(Tables) == 0 or ::sqlpp::allow_unconditional_from, return _from_impl<void>(_check<Table>{}, table);
"unconditional join is deprecated, please use explicit joins or #define ALLOW_UNCONDITIONAL_JOIN "
"for a grace period");
return _from_impl<void>(_check<Table, Tables...>{}, table, tables...);
} }
template <typename... Tables> template <typename Table>
auto dynamic_from(Tables... tables) const auto dynamic_from(Table table) const -> _new_statement_t<_check<Table>, from_t<_database_t, from_table_t<Table>>>
-> _new_statement_t<_check<Tables...>, from_t<_database_t, from_table_t<Tables>...>>
{ {
static_assert(not std::is_same<_database_t, void>::value, static_assert(not std::is_same<_database_t, void>::value,
"dynamic_from must not be called in a static statement"); "dynamic_from must not be called in a static statement");
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in from()"); static_assert(_check<Table>::value, "argument is not a table or join in from()");
static_assert( return _from_impl<_database_t>(_check<Table>{}, table);
sizeof...(Tables) == 1 or ::sqlpp::allow_unconditional_from,
"unconditional join is deprecated, please use explicit joins or #define SQLPP_ALLOW_UNCONDITIONAL_JOIN "
"for a grace period");
return _from_impl<_database_t>(_check<Tables...>{}, tables...);
} }
private: private:
template <typename Database, typename... Tables> template <typename Database, typename Table>
auto _from_impl(const std::false_type&, Tables... tables) const -> bad_statement; auto _from_impl(const std::false_type&, Table table) const -> bad_statement;
template <typename Database, typename... Tables> template <typename Database, typename Table>
auto _from_impl(const std::true_type&, Tables... tables) const auto _from_impl(const std::true_type&, Table table) const
-> _new_statement_t<std::true_type, from_t<Database, from_table_t<Tables>...>> -> _new_statement_t<std::true_type, from_t<Database, from_table_t<Table>>>
{ {
static_assert(required_tables_of<from_t<Database, Tables...>>::size::value == 0, static_assert(required_tables_of<from_t<Database, Table>>::size::value == 0,
"at least one table depends on another table in from()"); "at least one table depends on another table in from()");
static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Tables>::size::value...); static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Table>::size::value);
using _unique_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>; using _unique_tables = provided_tables_of<Table>;
using _unique_table_names = detail::make_name_of_set_t<_unique_tables>; using _unique_table_names = detail::make_name_of_set_t<_unique_tables>;
static_assert(_number_of_tables == _unique_tables::size::value, static_assert(_number_of_tables == _unique_tables::size::value,
"at least one duplicate table detected in from()"); "at least one duplicate table detected in from()");
@ -267,35 +248,35 @@ namespace sqlpp
"at least one duplicate table name detected in from()"); "at least one duplicate table name detected in from()");
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
from_data_t<Database, from_table_t<Tables>...>{from_table(tables)...}}; from_data_t<Database, from_table_t<Table>>{from_table(table)}};
} }
}; };
}; };
// Interpreters // Interpreters
template <typename Context, typename Database, typename... Tables> template <typename Context, typename Database, typename Table>
struct serializer_t<Context, from_data_t<Database, Tables...>> struct serializer_t<Context, from_data_t<Database, Table>>
{ {
using _serialize_check = serialize_check_of<Context, Tables...>; using _serialize_check = serialize_check_of<Context, Table>;
using T = from_data_t<Database, Tables...>; using T = from_data_t<Database, Table>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
return context;
context << " FROM "; context << " FROM ";
interpret_tuple(t._tables, ',', context); serialize(t._table, context);
if (sizeof...(Tables) and not t._dynamic_tables.empty()) if (not t._dynamic_tables.empty())
context << ','; {
interpret_list(t._dynamic_tables, ',', context); context << ' ';
interpret_list(t._dynamic_tables, ' ', context);
}
return context; return context;
} }
}; };
template <typename... T> template <typename T>
auto from(T&&... t) -> decltype(statement_t<void, no_from_t>().from(std::forward<T>(t)...)) auto from(T&& t) -> decltype(statement_t<void, no_from_t>().from(std::forward<T>(t)))
{ {
return statement_t<void, no_from_t>().from(std::forward<T>(t)...); return statement_t<void, no_from_t>().from(std::forward<T>(t));
} }
} }

View File

@ -31,7 +31,6 @@
namespace namespace
{ {
constexpr auto t = test::TabBar{}; constexpr auto t = test::TabBar{};
constexpr auto f = test::TabFoo{};
template <typename T> template <typename T>
void print_type_on_error(std::true_type) void print_type_on_error(std::true_type)