mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-05-18 01:12:12 -05:00
Added improved check for potential name duplicates in from()
This commit is contained in:
@@ -211,6 +211,24 @@ namespace sqlpp
|
||||
template<typename Minuend, typename Subtrahend>
|
||||
using make_difference_set_t = typename make_difference_set<Minuend, Subtrahend>::type;
|
||||
|
||||
|
||||
template<template<typename> class Transformation, typename T>
|
||||
struct transform_set
|
||||
{
|
||||
static_assert(::sqlpp::wrong_t<T>::value, "invalid argument for transform_set");
|
||||
};
|
||||
|
||||
template<template<typename> class Transformation, typename... E>
|
||||
struct transform_set<Transformation, type_set<E...>>
|
||||
{
|
||||
using type = typename make_type_set<Transformation<E>...>::type;
|
||||
};
|
||||
|
||||
template<template<typename> class Transformation, typename T>
|
||||
using transform_set_t = typename transform_set<Transformation, T>::type;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-19
@@ -32,6 +32,7 @@
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/logic.h>
|
||||
#include <sqlpp11/detail/sum.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
|
||||
namespace sqlpp
|
||||
@@ -60,18 +61,8 @@ namespace sqlpp
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::from>;
|
||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||
|
||||
using _is_dynamic = is_database<Database>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()");
|
||||
|
||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
||||
|
||||
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
|
||||
|
||||
// Data
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
@@ -84,7 +75,9 @@ namespace sqlpp
|
||||
{
|
||||
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
||||
#warning need to check if table is already known
|
||||
using _known_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>; // Hint: Joins contain more than one table
|
||||
using _known_table_names = detail::transform_set_t<name_of, _known_tables>;
|
||||
static_assert(not detail::is_element_of<typename Table::_name_t, _known_table_names>::value, "Must not use the same table name twice in from()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
@@ -172,20 +165,39 @@ namespace sqlpp
|
||||
|
||||
static void _check_consistency() {}
|
||||
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<from_t<void, Args...>>
|
||||
template<typename... Tables>
|
||||
auto from(Tables... tables)
|
||||
-> _new_statement_t<from_t<void, Tables...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<void, Args...>{args...} };
|
||||
static_assert(sizeof...(Tables), "at least one table or join argument required in from()");
|
||||
return _from_impl<void>(tables...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto dynamic_from(Args... args)
|
||||
-> _new_statement_t<from_t<_database_t, Args...>>
|
||||
template<typename... Tables>
|
||||
auto dynamic_from(Tables... tables)
|
||||
-> _new_statement_t<from_t<_database_t, Tables...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<_database_t, Args...>{args...} };
|
||||
return _from_impl<_database_t>(tables...);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Database, typename... Tables>
|
||||
auto _from_impl(Tables... tables)
|
||||
-> _new_statement_t<from_t<Database, Tables...>>
|
||||
{
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
||||
static_assert(required_tables_of<from_t<Database, Tables...>>::size::value == 0, "at least one table depends on another table");
|
||||
|
||||
static constexpr std::size_t _number_of_tables = detail::sum(provided_tables_of<Tables>::size::value...);
|
||||
using _unique_tables = detail::make_joined_set_t<provided_tables_of<Tables>...>;
|
||||
using _unique_table_names = detail::transform_set_t<name_of, _unique_tables>;
|
||||
static_assert(_number_of_tables == _unique_tables::size::value, "at least one duplicate table detected in from()");
|
||||
static_assert(_number_of_tables == _unique_table_names::size::value, "at least one duplicate table name detected in from()");
|
||||
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<Database, Tables...>{tables...} };
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_remove.h>
|
||||
#include <sqlpp11/noop.h>
|
||||
#warning: need to use another table provider, since delete can be used with several tables
|
||||
#include <sqlpp11/from.h>
|
||||
#include <sqlpp11/extra_tables.h>
|
||||
#include <sqlpp11/using.h>
|
||||
|
||||
@@ -187,6 +187,12 @@ namespace sqlpp
|
||||
using type = typename T::_recursive_traits::_parameters;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct name_of_impl
|
||||
{
|
||||
using type = typename T::_name_t;
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct make_parameter_tuple_impl
|
||||
{
|
||||
@@ -211,6 +217,9 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
using parameters_of = typename detail::parameters_of_impl<T>::type;
|
||||
|
||||
template<typename T>
|
||||
using name_of = typename detail::name_of_impl<T>::type;
|
||||
|
||||
template<typename ValueType, typename... Tags>
|
||||
struct make_traits
|
||||
{
|
||||
|
||||
@@ -49,8 +49,10 @@ namespace sqlpp
|
||||
|
||||
struct verbatim_table_t: public sqlpp::table_t<verbatim_table_t, detail::unusable_pseudo_column_t>
|
||||
{
|
||||
verbatim_table_t(std::string name):
|
||||
_name(name)
|
||||
struct _name_t {};
|
||||
|
||||
verbatim_table_t(std::string representation):
|
||||
_representation(representation)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -60,7 +62,7 @@ namespace sqlpp
|
||||
verbatim_table_t& operator=(verbatim_table_t&& rhs) = default;
|
||||
~verbatim_table_t() = default;
|
||||
|
||||
std::string _name;
|
||||
std::string _representation;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
@@ -70,7 +72,7 @@ namespace sqlpp
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._name;
|
||||
context << t._representation;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user