0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Started to rewrite traits and recursive traits

traits are shorter and easier to identify by using tags in a variadic
template

recursive traits can be automatically derived, which makes it much
easier to add new traits to be handed through the expression tree.
This commit is contained in:
rbock 2014-05-15 08:00:03 +02:00
parent df3fd999b3
commit d062c1a0d8
51 changed files with 218 additions and 224 deletions

View File

@ -33,18 +33,13 @@ namespace sqlpp
template<typename Expression, typename AliasProvider> template<typename Expression, typename AliasProvider>
struct expression_alias_t struct expression_alias_t
{ {
using _traits = make_traits_t<value_type_of<Expression>, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Expression>;
static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias"); static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias");
static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias"); static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias");
struct _value_type: Expression::_value_type
{
using _is_expression = std::false_type;
using _is_named_expression = std::true_type;
using _is_alias = std::true_type;
};
using _name_t = typename AliasProvider::_name_t; using _name_t = typename AliasProvider::_name_t;
using _table_set = typename Expression::_table_set;
Expression _expression; Expression _expression;
}; };

View File

@ -37,11 +37,8 @@ namespace sqlpp
template<typename Select> template<typename Select>
struct any_t struct any_t
{ {
struct _value_type: public Select::_value_type::_base_value_type using _traits = make_traits_t<value_type_of<Select>, tag::multi_expression>;
{ using _recursive_traits = make_recursive_traits_t<Select>;
using _is_expression = std::false_type;
using _is_multi_expression = std::true_type; // must not be named or used with +,-,*,/, etc
};
struct _name_t struct _name_t
{ {
@ -55,8 +52,6 @@ namespace sqlpp
}; };
}; };
using _table_set = typename Select::_table_set;
any_t(Select select): any_t(Select select):
_select(select) _select(select)
{} {}

View File

@ -36,16 +36,12 @@ namespace sqlpp
template<typename Flag, typename Expr> template<typename Flag, typename Expr>
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>> struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>
{ {
using _traits = make_traits_t<value_type_of<Expr>, tag::expression, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Select>;
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "avg() used with flag other than 'distinct'"); static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "avg() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument"); static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
struct _value_type: public floating_point
{
using _is_named_expression = std::true_type;
};
using _table_set = typename Expr::_table_set;
struct _name_t struct _name_t
{ {
static constexpr const char* _get_name() { return "AVG"; } static constexpr const char* _get_name() { return "AVG"; }

View File

@ -42,16 +42,11 @@ namespace sqlpp
// boolean value type // boolean value type
struct boolean struct boolean
{ {
using _value_type = boolean;
using _base_value_type = boolean;
using _is_boolean = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = bool; using _cpp_value_type = bool;
struct _parameter_t struct _parameter_t
{ {
using _value_type = boolean; using _value_type = boolean; // FIXME
_parameter_t(): _parameter_t():
_value(false), _value(false),

View File

@ -45,21 +45,20 @@ namespace sqlpp
struct column_t: public ColumnSpec::_value_type::template expression_operators<column_t<Table, ColumnSpec>>, struct column_t: public ColumnSpec::_value_type::template expression_operators<column_t<Table, ColumnSpec>>,
public ColumnSpec::_value_type::template column_operators<column_t<Table, ColumnSpec>> public ColumnSpec::_value_type::template column_operators<column_t<Table, ColumnSpec>>
{ {
using _is_column = std::true_type; using _traits = make_traits_t<value_type_of<ColumnSpec>, tag::column, tag::expression, tag::named_expression>;
struct _recursive_traits
{
using _provided_tables = detail::type_set<>;
using _required_tables = detail::type_set<_table>;
};
using _spec_t = ColumnSpec; using _spec_t = ColumnSpec;
using _table = Table; using _table = Table;
using _table_set = detail::type_set<_table>; using _column_type = typename _spec_t::_column_type;
using _column_type = typename ColumnSpec::_column_type; using _name_t = typename _spec_t::_name_t;
struct _value_type: ColumnSpec::_value_type
{
using _is_expression = std::true_type;
using _is_named_expression = std::true_type;
using _is_alias = std::false_type;
};
template<typename T>
using _is_valid_operand = typename _value_type::template _is_valid_operand<T>;
using _name_t = typename ColumnSpec::_name_t; template<typename T>
using _is_valid_operand = typename value_type_of<ColumnSpec>::template _is_valid_operand<T>;
column_t() = default; column_t() = default;
column_t(const column_t&) = default; column_t(const column_t&) = default;

View File

@ -37,16 +37,12 @@ namespace sqlpp
template<typename Flag, typename Expr> template<typename Flag, typename Expr>
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>> struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>
{ {
using _traits = make_traits_t<value_type_of<Expr>, tag::expression, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Select>;
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "count() used with flag other than 'distinct'"); static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "count() used with flag other than 'distinct'");
static_assert(is_expression_t<Expr>::value, "count() requires a sql expression as argument"); static_assert(is_expression_t<Expr>::value, "count() requires a sql expression as argument");
struct _value_type: public sqlpp::detail::integral
{
using _is_named_expression = std::true_type;
};
using _table_set = typename Expr::_table_set;
struct _name_t struct _name_t
{ {
static constexpr const char* _get_name() { return "COUNT"; } static constexpr const char* _get_name() { return "COUNT"; }

View File

@ -33,9 +33,8 @@ namespace sqlpp
{ {
struct default_value_t struct default_value_t
{ {
static constexpr bool _is_expression = true; using _traits = make_traits_t<no_value_t, tag::expression>;
using _value_type = no_value_t; using _recursive_traits = make_recursive_traits_t<>;
using _table_set = ::sqlpp::detail::type_set<>;
static constexpr bool _is_trivial() { return false; } static constexpr bool _is_trivial() { return false; }
}; };

View File

@ -36,15 +36,11 @@ namespace sqlpp
template<typename Select> template<typename Select>
struct exists_t: public boolean::template expression_operators<exists_t<Select>> struct exists_t: public boolean::template expression_operators<exists_t<Select>>
{ {
using _traits = make_traits_t<boolean, tag::expression, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Select>;
static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument"); static_assert(is_select_t<Select>::value, "exists() requires a select expression as argument");
struct _value_type: public boolean
{
using _is_named_expression = std::true_type;
};
using _table_set = typename Select::_table_set;
struct _name_t struct _name_t
{ {
static constexpr const char* _get_name() { return "EXISTS"; } static constexpr const char* _get_name() { return "EXISTS"; }

View File

@ -41,17 +41,11 @@ namespace sqlpp
// floating_point value type // floating_point value type
struct floating_point struct floating_point
{ {
using _value_type = floating_point;
using _base_value_type = floating_point;
using _is_numeric = std::true_type;
using _is_floating_point = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = double; using _cpp_value_type = double;
struct _parameter_t struct _parameter_t
{ {
using _value_type = integral; using _value_type = floating_point;
_parameter_t(): _parameter_t():
_value(0), _value(0),

View File

@ -48,7 +48,8 @@ namespace sqlpp
template<typename T> template<typename T>
auto value(T t) -> vendor::wrap_operand_t<T> auto value(T t) -> vendor::wrap_operand_t<T>
{ {
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
static_assert(not is_value_t<T>::value, "value() is to be called with non-sql-type like int, or string"); static_assert(not is_value_t<T>::value, "value() is to be called with non-sql-type like int, or string");
return { t }; return { t };
} }
@ -56,8 +57,8 @@ namespace sqlpp
template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>> struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>
{ {
using _value_type = ValueType; using _traits = make_traits_t<ValueType, tag::expression>;
using _table_set = ::sqlpp::detail::type_set<>; using _recursive_traits = make_recursive_traits_t<Select>;
verbatim_t(std::string verbatim): _verbatim(verbatim) {} verbatim_t(std::string verbatim): _verbatim(verbatim) {}
verbatim_t(const verbatim_t&) = default; verbatim_t(const verbatim_t&) = default;
@ -102,9 +103,10 @@ namespace sqlpp
template<typename Container> template<typename Container>
struct value_list_t // to be used in .in() method struct value_list_t // to be used in .in() method
{ {
using _traits = make_traits_t<vendor::value_type_t<typename _container_t::value_type>;
using _recursive_traits = make_recursive_traits_t<Select>;
using _container_t = Container; using _container_t = Container;
using _table_set = ::sqlpp::detail::type_set<>;// FIXME: Could it be something else?
using _value_type = vendor::value_type_t<typename _container_t::value_type>;
value_list_t(_container_t container): value_list_t(_container_t container):
_container(container) _container(container)

View File

@ -42,14 +42,7 @@ namespace sqlpp
// integral value type // integral value type
struct integral struct integral
{ {
using _value_type = integral;
using _base_value_type = integral;
using _is_numeric = std::true_type;
using _is_integral = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = int64_t; using _cpp_value_type = int64_t;
struct _parameter_t struct _parameter_t
{ {

View File

@ -77,16 +77,17 @@ namespace sqlpp
template<typename JoinType, typename Lhs, typename Rhs, typename On = vendor::noop> template<typename JoinType, typename Lhs, typename Rhs, typename On = vendor::noop>
struct join_t struct join_t
{ {
using _traits = make_traits_t<no_value_t, tag::table, tag::join>;
using _recursive_traits = make_recursive_traits_t<Lhs, Rhs>;
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join"); static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table"); static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join"); static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()"); static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
static_assert(::sqlpp::detail::is_disjunct_from<typename Lhs::_table_set, typename Rhs::_table_set>::value, "joined tables must not be identical"); static_assert(::sqlpp::detail::is_disjunct_from<typename Lhs::_provided_tables, typename Rhs::_provided_tables>::value, "joined tables must not be identical");
using _is_table = std::true_type; static_assert(_recursive_traits::_required_tables::size::value == 0, "joined tables must not depend on other tables");
using _is_join = std::true_type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
template<typename OnT> template<typename OnT>
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>; using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;

View File

@ -36,15 +36,11 @@ namespace sqlpp
template<typename Expr> template<typename Expr>
struct max_t: public Expr::_value_type::template expression_operators<max_t<Expr>> struct max_t: public Expr::_value_type::template expression_operators<max_t<Expr>>
{ {
using _traits = make_traits_t<value_type_of<Expr>, tag::expression, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Select>;
static_assert(is_value_t<Expr>::value, "max() requires a value expression as argument"); static_assert(is_value_t<Expr>::value, "max() requires a value expression as argument");
struct _value_type: public Expr::_value_type::_base_value_type
{
using _is_named_expression = std::true_type;
};
using _table_set = typename Expr::_table_set;
struct _name_t struct _name_t
{ {
static constexpr const char* _get_name() { return "MAX"; } static constexpr const char* _get_name() { return "MAX"; }

View File

@ -36,15 +36,11 @@ namespace sqlpp
template<typename Expr> template<typename Expr>
struct min_t: public Expr::_value_type::template expression_operators<min_t<Expr>> struct min_t: public Expr::_value_type::template expression_operators<min_t<Expr>>
{ {
using _traits = make_traits_t<value_type_of<Expr>, tag::expression, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Select>;
static_assert(is_value_t<Expr>::value, "min() requires a value expression as argument"); static_assert(is_value_t<Expr>::value, "min() requires a value expression as argument");
struct _value_type: public Expr::_value_type::_base_value_type
{
using _is_named_expression = std::true_type;
};
using _table_set = typename Expr::_table_set;
struct _name_t struct _name_t
{ {
static constexpr const char* _get_name() { return "MIN"; } static constexpr const char* _get_name() { return "MIN"; }

View File

@ -41,9 +41,10 @@ namespace sqlpp
template<typename Unused, typename... Columns> template<typename Unused, typename... Columns>
struct multi_column_t struct multi_column_t
{ {
static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions"); using _traits = make_traits_t<no_value_t>;
using _recursive_traits = make_recursive_traits_t<Columns...>;
using _table_set = sqlpp::detail::make_joined_set_t<typename Columns::_table_set...>; static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
multi_column_t(std::tuple<Columns...> columns): multi_column_t(std::tuple<Columns...> columns):
_columns(columns) _columns(columns)
@ -75,10 +76,12 @@ namespace sqlpp
template<typename AliasProvider, typename... Columns> template<typename AliasProvider, typename... Columns>
struct multi_column_alias_t struct multi_column_alias_t
{ {
using _traits = make_traits_t<no_value_t, alias>;
using _recursive_traits = make_recursive_traits_t<Columns...>;
static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions"); static_assert(detail::all_t<is_named_expression_t<Columns>::value...>::value, "multi_column parameters need to be named expressions");
using _name_t = typename AliasProvider::_name_t; using _name_t = typename AliasProvider::_name_t;
using _table_set = sqlpp::detail::make_joined_set_t<typename Columns::_table_set...>;
multi_column_alias_t(multi_column_t<void, Columns...> multi_column): multi_column_alias_t(multi_column_t<void, Columns...> multi_column):
_columns(multi_column._columns) _columns(multi_column._columns)

View File

@ -33,11 +33,6 @@ namespace sqlpp
{ {
struct no_value_t struct no_value_t
{ {
template<typename T>
using _constraint = std::false_type;
using _base_value_type = no_value_t;
template<typename T> template<typename T>
struct _is_valid_operand struct _is_valid_operand
{ {

View File

@ -33,9 +33,8 @@ namespace sqlpp
{ {
struct null_t struct null_t
{ {
static constexpr bool _is_expression = true; using _traits = make_traits_t<no_value_t, tag::expression>;
using _value_type = no_value_t; using _recursive_traits = make_recursive_traits_t<>;
using _table_set = ::sqlpp::detail::type_set<>;
}; };
namespace vendor namespace vendor

View File

@ -37,7 +37,9 @@ namespace sqlpp
template<typename Database, typename... Expr> template<typename Database, typename... Expr>
struct on_t struct on_t
{ {
using _is_on = std::true_type; using _traits = make_traits_t<no_value_t, tag::on>;
using _recursive_traits = make_recursive_traits_t<Expr...>;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type; using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()"); static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in on()");

View File

@ -36,14 +36,10 @@ namespace sqlpp
template<typename ValueType, typename NameType> template<typename ValueType, typename NameType>
struct parameter_t: public ValueType::template expression_operators<parameter_t<ValueType, NameType>> struct parameter_t: public ValueType::template expression_operators<parameter_t<ValueType, NameType>>
{ {
struct _value_type: public ValueType using _traits = make_traits_t<ValueType, tag::parameter, tag::expression>;
{ using _recursive_traits = make_recursive_traits_t<>;
using _is_expression = std::true_type;
using _is_alias = std::false_type;
};
using _is_parameter = std::true_type;
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>; using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
using _table_set = sqlpp::detail::type_set<>;
parameter_t() parameter_t()
{} {}

View File

@ -42,9 +42,9 @@ namespace sqlpp
template<typename Db, std::size_t index, typename NamedExpr> template<typename Db, std::size_t index, typename NamedExpr>
struct result_field: struct result_field:
public NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>> public NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>
{ {
using _field = typename NamedExpr::_name_t::template _member_t<typename NamedExpr::_value_type::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>; using _field = typename NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
result_field() = default; result_field() = default;
result_field(const char_result_row_t& char_result_row_t): result_field(const char_result_row_t& char_result_row_t):

View File

@ -37,11 +37,8 @@ namespace sqlpp
// standard select flags // standard select flags
struct all_t struct all_t
{ {
struct _value_type using _traits = make_traits_t<no_value_t, tag::select_flag>;
{ using _recursive_traits = make_recursive_traits_t<>;
using _is_select_flag = std::true_type;
};
using _table_set = detail::type_set<>;
}; };
static constexpr all_t all = {}; static constexpr all_t all = {};
@ -60,11 +57,8 @@ namespace sqlpp
struct distinct_t struct distinct_t
{ {
struct _value_type using _traits = make_traits_t<no_value_t, tag::select_flag>;
{ using _recursive_traits = make_recursive_traits_t<>;
using _is_select_flag = std::true_type;
};
using _table_set = detail::type_set<>;
}; };
static constexpr distinct_t distinct = {}; static constexpr distinct_t distinct = {};
@ -83,11 +77,8 @@ namespace sqlpp
struct straight_join_t struct straight_join_t
{ {
struct _value_type using _traits = make_traits_t<no_value_t, tag::select_flag>;
{ using _recursive_traits = make_recursive_traits_t<>;
using _is_select_flag = std::true_type;
};
using _table_set = detail::type_set<>;
}; };
static constexpr straight_join_t straight_join = {}; static constexpr straight_join_t straight_join = {};

View File

@ -37,11 +37,8 @@ namespace sqlpp
template<typename Select> template<typename Select>
struct some_t struct some_t
{ {
struct _value_type: public Select::_value_type::_base_value_type using _traits = make_traits_t<value_type_of<Select>, tag::multi_expression>;
{ using _recursive_traits = make_recursive_traits_t<Select>;
using _is_expression = std::false_type;
using _is_multi_expression = std::true_type; // must not be named or used with +,-,*,/, etc
};
struct _name_t struct _name_t
{ {
@ -54,7 +51,6 @@ namespace sqlpp
const T& operator()() const { return some; } const T& operator()() const { return some; }
}; };
}; };
using _table_set = typename Select::_table_set;
some_t(Select select): some_t(Select select):
_select(select) _select(select)

View File

@ -41,7 +41,8 @@ namespace sqlpp
struct sort_order_t struct sort_order_t
{ {
using _is_sort_order = std::true_type; using _is_sort_order = std::true_type;
using _table_set = typename Expression::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename Expression::_required_tables;
Expression _expression; Expression _expression;
}; };

View File

@ -36,14 +36,12 @@ namespace sqlpp
template<typename Flag, typename Expr> template<typename Flag, typename Expr>
struct sum_t: public Expr::_value_type::template expression_operators<sum_t<Flag, Expr>> struct sum_t: public Expr::_value_type::template expression_operators<sum_t<Flag, Expr>>
{ {
using _traits = make_traits_t<value_type_of<Expr>, tag::expression, tag::named_expression>;
using _recursive_traits = make_recursive_traits_t<Select>;
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "sum() used with flag other than 'distinct'"); static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "sum() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument"); static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");
struct _value_type: public Expr::_value_type::_base_value_type
{
using _is_named_expression = std::true_type;
};
struct _name_t struct _name_t
{ {
static constexpr const char* _get_name() { return "SUM"; } static constexpr const char* _get_name() { return "SUM"; }

View File

@ -42,14 +42,21 @@ namespace sqlpp
template<typename Table, typename... ColumnSpec> template<typename Table, typename... ColumnSpec>
struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>... struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
{ {
using _table_set = detail::type_set<Table>; // Hint need a type_set here to be similar to a join (which always represents more than one table) using _traits = make_traits_t<no_value_t, tag::table>;
struct _recursive_traits
{
using _parameters = std::tuple<>;
using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<Table>;
};
static_assert(sizeof...(ColumnSpec), "at least one column required per table"); static_assert(sizeof...(ColumnSpec), "at least one column required per table");
using _required_insert_columns = typename detail::make_type_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type; using _required_insert_columns = typename detail::make_type_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;
using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>; using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>;
template<typename AliasProvider> template<typename AliasProvider>
using _alias_t = table_alias_t<AliasProvider, Table, ColumnSpec...>; using _alias_t = table_alias_t<AliasProvider, Table, ColumnSpec...>;
using _is_table = std::true_type;
template<typename T> template<typename T>
join_t<inner_join_t, Table, T> join(T t) join_t<inner_join_t, Table, T> join(T t)

View File

@ -41,16 +41,17 @@ namespace sqlpp
struct table_alias_t: public table_alias_base_t, public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>... struct table_alias_t: public table_alias_base_t, public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
{ {
//FIXME: Need to add join functionality //FIXME: Need to add join functionality
using _is_table = std::true_type; using _traits = make_traits_t<value_type_of<Table>, tag::table, tag::alias, tag::named_expression_if<tag::is_expression<Table>>;
using _table_set = detail::type_set<AliasProvider>;
struct _value_type: Table::_value_type struct _recursive_traits
{ {
using _is_expression = std::false_type; using _parameters = std::tuple<>;
using _is_named_expression = copy_type_trait<Table, is_value_t>; using _required_tables = detail::type_set<>;
using _is_alias = std::true_type; using _provided_tables = detail::type_set<Table>;
}; };
static_assert(Table::_required_tables::size::value == 0, "table aliases must not depend on external tables");
using _name_t = typename AliasProvider::_name_t; using _name_t = typename AliasProvider::_name_t;
using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>; using _column_tuple_t = std::tuple<column_t<Table, ColumnSpec>...>;

View File

@ -41,11 +41,6 @@ namespace sqlpp
// text value type // text value type
struct text struct text
{ {
using _value_type = text;
using _base_value_type = text;
using _is_text = std::true_type;
using _is_value = std::true_type;
using _is_expression = std::true_type;
using _cpp_value_type = std::string; using _cpp_value_type = std::string;
struct _parameter_t struct _parameter_t

View File

@ -38,9 +38,8 @@ namespace sqlpp
template<typename Operand> template<typename Operand>
struct tvin_t struct tvin_t
{ {
using _operand_t = Operand; using _traits = make_traits_t<value_type_of<Operand>, tag::operand, tag::expression>;
using _value_type = typename _operand_t::_value_type; using _recursive_traits = make_recursive_traits_t<Operand>;
using _table_set = typename _operand_t::_table_set;
tvin_t(Operand operand): tvin_t(Operand operand):
_value(operand) _value(operand)
@ -76,7 +75,8 @@ namespace sqlpp
template<typename T> template<typename T>
struct maybe_tvin_t struct maybe_tvin_t
{ {
using _table_set = typename T::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename T::_required_tables;
static constexpr bool _is_trivial() static constexpr bool _is_trivial()
{ {
return false; return false;
@ -97,7 +97,8 @@ namespace sqlpp
template<typename T> template<typename T>
struct maybe_tvin_t<tvin_t<T>> struct maybe_tvin_t<tvin_t<T>>
{ {
using _table_set = typename T::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename T::_required_tables;
bool _is_trivial() const bool _is_trivial() const
{ {
return _value._is_trivial(); return _value._is_trivial();

View File

@ -65,13 +65,18 @@ namespace sqlpp
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
struct assignment_t struct assignment_t
{ {
using _is_assignment = std::true_type; struct _traits
using _column_t = Lhs; {
using value_type = Rhs; using _is_assignment = std::true_type;
using _parameter_tuple_t = std::tuple<_column_t, Rhs>; using value_type = no_value;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type; };
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<Rhs, null_t>::value, "column must not be null"); using _recursive_traits = make_recursive_traits_t<Lhs, Rhs>;
using _column_t = Lhs;
using _value_t = Lhs;
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<_value_t, null_t>::value, "column must not be null");
assignment_t(_column_t lhs, value_type rhs): assignment_t(_column_t lhs, value_type rhs):
_lhs(lhs), _lhs(lhs),
@ -85,7 +90,7 @@ namespace sqlpp
~assignment_t() = default; ~assignment_t() = default;
_column_t _lhs; _column_t _lhs;
value_type _rhs; _value_t _rhs;
}; };
template<typename Context, typename Lhs, typename Rhs> template<typename Context, typename Lhs, typename Rhs>
@ -115,15 +120,21 @@ namespace sqlpp
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
struct assignment_t<Lhs, tvin_t<Rhs>> struct assignment_t<Lhs, tvin_t<Rhs>>
{ {
struct _traits
{
using _is_assignment = std::true_type;
using value_type = no_value;
};
using _recursive_traits = make_recursive_traits_t<Lhs, Rhs>;
using _is_assignment = std::true_type; using _is_assignment = std::true_type;
using _column_t = Lhs; using _column_t = Lhs;
using value_type = tvin_t<Rhs>; using _value_t = tvin_t<Rhs>;
using _parameter_tuple_t = std::tuple<_column_t, Rhs>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type;
static_assert(can_be_null_t<_column_t>::value, "column cannot be null"); static_assert(can_be_null_t<_column_t>::value, "column cannot be null");
assignment_t(_column_t lhs, value_type rhs): assignment_t(_column_t lhs, _value_t rhs):
_lhs(lhs), _lhs(lhs),
_rhs(rhs) _rhs(rhs)
{} {}
@ -135,7 +146,7 @@ namespace sqlpp
~assignment_t() = default; ~assignment_t() = default;
_column_t _lhs; _column_t _lhs;
value_type _rhs; _value_t _rhs;
}; };
template<typename Context, typename Lhs, typename Rhs> template<typename Context, typename Lhs, typename Rhs>

View File

@ -40,7 +40,8 @@ namespace sqlpp
{ {
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()"); static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
using _table_set = typename ::sqlpp::detail::make_joined_set<typename First::_table_set, typename Args::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename First::_required_tables, typename Args::_required_tables...>::type;
struct _value_type: public First::_value_type::_base_value_type struct _value_type: public First::_value_type::_base_value_type
{ {

View File

@ -44,7 +44,8 @@ namespace sqlpp
{ {
using _value_type = ::sqlpp::detail::boolean; using _value_type = ::sqlpp::detail::boolean;
using _parameter_tuple_t = std::tuple<Lhs, Rhs>; using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Lhs::_required_tables, typename Rhs::_required_tables>::type;
binary_expression_t(Lhs lhs, Rhs rhs): binary_expression_t(Lhs lhs, Rhs rhs):
_lhs(lhs), _lhs(lhs),
@ -89,7 +90,8 @@ namespace sqlpp
{ {
using _value_type = ::sqlpp::detail::boolean; using _value_type = ::sqlpp::detail::boolean;
using _parameter_tuple_t = std::tuple<Lhs, Rhs>; using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Lhs::_required_tables, typename Rhs::_required_tables>::type;
binary_expression_t(Lhs lhs, Rhs rhs): binary_expression_t(Lhs lhs, Rhs rhs):
_lhs(lhs), _lhs(lhs),
@ -134,7 +136,8 @@ namespace sqlpp
{ {
using _value_type = ::sqlpp::detail::boolean; using _value_type = ::sqlpp::detail::boolean;
using _parameter_tuple_t = std::tuple<Rhs>; using _parameter_tuple_t = std::tuple<Rhs>;
using _table_set = typename Rhs::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename Rhs::_required_tables;
unary_expression_t(Rhs rhs): unary_expression_t(Rhs rhs):
_rhs(rhs) _rhs(rhs)
@ -171,7 +174,8 @@ namespace sqlpp
using _rhs_t = Rhs; using _rhs_t = Rhs;
using _value_type = typename O::_value_type; using _value_type = typename O::_value_type;
using _parameter_tuple_t = std::tuple<_lhs_t, _rhs_t>; using _parameter_tuple_t = std::tuple<_lhs_t, _rhs_t>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Lhs::_table_set, typename Rhs::_table_set>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Lhs::_required_tables, typename Rhs::_required_tables>::type;
binary_expression_t(_lhs_t lhs, _rhs_t rhs): binary_expression_t(_lhs_t lhs, _rhs_t rhs):
_lhs(lhs), _lhs(lhs),
@ -209,7 +213,8 @@ namespace sqlpp
{ {
using _value_type = typename O::_value_type; using _value_type = typename O::_value_type;
using _parameter_tuple_t = std::tuple<Rhs>; using _parameter_tuple_t = std::tuple<Rhs>;
using _table_set = typename Rhs::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename Rhs::_required_tables;
unary_expression_t(Rhs rhs): unary_expression_t(Rhs rhs):
_rhs(rhs) _rhs(rhs)

View File

@ -47,7 +47,8 @@ namespace sqlpp
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()"); static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>; using _provided_tables = ::sqlpp::detail::make_joined_set_t<typename Tables::_provided_tables...>;
using _required_tables = ::sqlpp::detail::make_joined_set_t<typename Tables::_required_tables...>;
extra_tables_t() extra_tables_t()
@ -68,7 +69,8 @@ namespace sqlpp
struct no_extra_tables_t struct no_extra_tables_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -42,6 +42,8 @@ namespace sqlpp
struct from_t struct from_t
{ {
using _is_from = std::true_type; using _is_from = std::true_type;
using _required_tables = ::sqlpp::detail::make_joined_set_t<typename Tables::_required_tables...>;
using _provided_tables = ::sqlpp::detail::make_joined_set_t<typename Tables::_provided_tables...>;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type; using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()"); static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()");
@ -51,7 +53,7 @@ namespace sqlpp
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(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>; static_assert(_required_tables::size::value == 0, "at least one table depends on another table");
from_t(Tables... tables): from_t(Tables... tables):
@ -96,7 +98,8 @@ namespace sqlpp
struct no_from_t struct no_from_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -48,7 +48,8 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expressions...>; using _parameter_tuple_t = std::tuple<Expressions...>;
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Expressions::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Expressions::_required_tables...>::type;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()"); static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
@ -106,7 +107,8 @@ namespace sqlpp
struct no_group_by_t struct no_group_by_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -51,7 +51,8 @@ namespace sqlpp
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Expressions::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Expressions::_required_tables...>::type;
having_t(Expressions... expressions): having_t(Expressions... expressions):
_expressions(expressions...) _expressions(expressions...)
@ -102,7 +103,8 @@ namespace sqlpp
struct no_having_t struct no_having_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -56,7 +56,8 @@ namespace sqlpp
T in; T in;
}; };
}; };
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Operand::_table_set, typename Args::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Operand::_required_tables, typename Args::_required_tables...>::type;
in_t(Operand operand, Args... args): in_t(Operand operand, Args... args):
_operand(operand), _operand(operand),

View File

@ -44,7 +44,8 @@ namespace sqlpp
struct type_if struct type_if
{ {
using type = Type; using type = Type;
using _table_set = typename Type::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename Type::_required_tables;
}; };
template<typename Type> template<typename Type>
@ -52,7 +53,8 @@ namespace sqlpp
{ {
struct type struct type
{ {
using _table_set = sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = sqlpp::detail::type_set<>;
}; };
}; };
} }

View File

@ -42,7 +42,7 @@ namespace sqlpp
// COLUMN AND VALUE LIST // COLUMN AND VALUE LIST
struct insert_default_values_t struct insert_default_values_t
{ {
using _table_set = ::sqlpp::detail::type_set<>; using _required_tables = ::sqlpp::detail::type_set<>;
using _is_dynamic = std::false_type; using _is_dynamic = std::false_type;
template<typename Policies> template<typename Policies>
@ -69,11 +69,12 @@ namespace sqlpp
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()"); static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type; using _column_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_required_tables...>::type;
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type; using _value_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_required_tables...>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type; using _provided_tables = ::sqlpp::detail::type_set<>;
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns"); using _required_tables = typename ::sqlpp::detail::make_joined_set<_column_required_tables, _value_required_tables>::type;
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables"); static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for tables from several columns");
static_assert(::sqlpp::detail::is_subset_of<_value_required_tables, _column_required_tables>::value, "set() contains values from foreign tables");
insert_list_t(Assignments... assignment): insert_list_t(Assignments... assignment):
_assignments(assignment...), _assignments(assignment...),
@ -203,7 +204,8 @@ namespace sqlpp
struct no_insert_value_list_t struct no_insert_value_list_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = ::sqlpp::detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -39,7 +39,8 @@ namespace sqlpp
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>> struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>
{ {
static constexpr bool _inverted = not NotInverted; static constexpr bool _inverted = not NotInverted;
using _table_set = typename Operand::_table_set; using _provided_tables = detail::type_set<>;
using _required_tables = typename Operand::_required_tables;
struct _value_type: public boolean struct _value_type: public boolean
{ {

View File

@ -41,7 +41,8 @@ namespace sqlpp
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text"); static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text"); static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
using _parameter_tuple_t = std::tuple<Operand, Pattern>; using _parameter_tuple_t = std::tuple<Operand, Pattern>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Operand::_table_set, typename Pattern::_table_set>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Operand::_required_tables, typename Pattern::_required_tables>::type;
struct _value_type: public boolean struct _value_type: public boolean
{ {

View File

@ -42,7 +42,8 @@ namespace sqlpp
using _is_limit = std::true_type; using _is_limit = std::true_type;
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter"); static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
// FIXME: Is this really always empty? // FIXME: Is this really always empty?
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
limit_t(Limit value): limit_t(Limit value):
_value(value) _value(value)
@ -67,7 +68,8 @@ namespace sqlpp
{ {
using _is_limit = std::true_type; using _is_limit = std::true_type;
using _is_dynamic = std::true_type; using _is_dynamic = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
dynamic_limit_t(): dynamic_limit_t():
_value(noop()) _value(noop())
@ -107,7 +109,8 @@ namespace sqlpp
struct no_limit_t struct no_limit_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -40,7 +40,8 @@ namespace sqlpp
struct offset_t struct offset_t
{ {
using _is_offset = std::true_type; using _is_offset = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter"); static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
offset_t(Offset value): offset_t(Offset value):
@ -66,7 +67,8 @@ namespace sqlpp
{ {
using _is_offset = std::true_type; using _is_offset = std::true_type;
using _is_dynamic = std::true_type; using _is_dynamic = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
dynamic_offset_t(): dynamic_offset_t():
_value(noop()) _value(noop())
@ -106,7 +108,8 @@ namespace sqlpp
struct no_offset_t struct no_offset_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -47,7 +47,8 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Expressions...>; using _parameter_tuple_t = std::tuple<Expressions...>;
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Expressions::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Expressions::_required_tables...>::type;
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one sort-order expression required in order_by()"); static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one sort-order expression required in order_by()");
@ -104,7 +105,8 @@ namespace sqlpp
struct no_order_by_t struct no_order_by_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -137,7 +137,8 @@ namespace sqlpp
using _parameter_tuple_t = std::tuple<Columns...>; using _parameter_tuple_t = std::tuple<Columns...>;
using size = std::tuple_size<_parameter_tuple_t>; using size = std::tuple_size<_parameter_tuple_t>;
using _table_set = sqlpp::detail::make_joined_set_t<typename Columns::_table_set...>; using _provided_tables = detail::type_set<>;
using _required_tables = sqlpp::detail::make_joined_set_t<typename Columns::_required_tables...>;
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected"); static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
@ -245,7 +246,8 @@ namespace sqlpp
struct no_select_column_list_t struct no_select_column_list_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Db> template<typename Db>
using _result_row_t = ::sqlpp::result_row_t<Db>; using _result_row_t = ::sqlpp::result_row_t<Db>;
using _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t; using _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t;

View File

@ -46,7 +46,8 @@ namespace sqlpp
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type; using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Flags...>; using _parameter_tuple_t = std::tuple<Flags...>;
using size = std::tuple_size<_parameter_tuple_t>; using size = std::tuple_size<_parameter_tuple_t>;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Flags::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Flags::_required_tables...>::type;
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list"); static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
@ -102,7 +103,8 @@ namespace sqlpp
struct no_select_flag_list_t struct no_select_flag_list_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -39,8 +39,11 @@ namespace sqlpp
struct single_table_t struct single_table_t
{ {
using _is_single_table = std::true_type; using _is_single_table = std::true_type;
using _required_tables = typename Table::_required_tables;
using _provided_tables = typename Table::_provided_tables;
static_assert(is_table_t<Table>::value, "argument has to be a table"); static_assert(is_table_t<Table>::value, "argument has to be a table");
static_assert(_required_tables::size::value == 0, "table depends on another table");
single_table_t(Table table): single_table_t(Table table):
_table(table) _table(table)
@ -52,13 +55,13 @@ namespace sqlpp
single_table_t& operator=(single_table_t&&) = default; single_table_t& operator=(single_table_t&&) = default;
~single_table_t() = default; ~single_table_t() = default;
using _table_set = typename Table::_table_set;
Table _table; Table _table;
}; };
struct no_single_table_t struct no_single_table_t
{ {
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
}; };
// Interpreters // Interpreters

View File

@ -112,7 +112,8 @@ namespace sqlpp
struct no_update_list_t struct no_update_list_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -51,7 +51,8 @@ namespace sqlpp
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()"); static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
using _table_set = ::sqlpp::detail::make_joined_set_t<typename Tables::_table_set...>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::make_joined_set_t<typename Tables::_required_tables...>;
using_t(Tables... tables): using_t(Tables... tables):
_tables(tables...) _tables(tables...)
@ -96,7 +97,8 @@ namespace sqlpp
struct no_using_t struct no_using_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -52,7 +52,8 @@ namespace sqlpp
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
using _table_set = typename ::sqlpp::detail::make_joined_set<typename Expressions::_table_set...>::type; using _provided_tables = detail::type_set<>;
using _required_tables = typename ::sqlpp::detail::make_joined_set<typename Expressions::_required_tables...>::type;
where_t(Expressions... expressions): where_t(Expressions... expressions):
_expressions(expressions...) _expressions(expressions...)
@ -105,7 +106,8 @@ namespace sqlpp
{ {
using _is_where = std::true_type; using _is_where = std::true_type;
using _is_dynamic = std::false_type; using _is_dynamic = std::false_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
where_t(bool condition): where_t(bool condition):
_condition(condition) _condition(condition)
@ -128,7 +130,8 @@ namespace sqlpp
struct no_where_t struct no_where_t
{ {
using _is_noop = std::true_type; using _is_noop = std::true_type;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t

View File

@ -48,7 +48,8 @@ namespace sqlpp
static constexpr bool _is_expression = true; static constexpr bool _is_expression = true;
using _value_type = sqlpp::detail::boolean; using _value_type = sqlpp::detail::boolean;
using _value_t = bool; using _value_t = bool;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
boolean_operand(): boolean_operand():
_t{} _t{}
@ -86,7 +87,8 @@ namespace sqlpp
static constexpr bool _is_expression = true; static constexpr bool _is_expression = true;
using _value_type = ::sqlpp::detail::integral; using _value_type = ::sqlpp::detail::integral;
using _value_t = int64_t; using _value_t = int64_t;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
integral_operand(): integral_operand():
_t{} _t{}
@ -125,7 +127,8 @@ namespace sqlpp
static constexpr bool _is_expression = true; static constexpr bool _is_expression = true;
using _value_type = ::sqlpp::detail::floating_point; using _value_type = ::sqlpp::detail::floating_point;
using _value_t = double; using _value_t = double;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
floating_point_operand(): floating_point_operand():
_t{} _t{}
@ -163,7 +166,8 @@ namespace sqlpp
static constexpr bool _is_expression = true; static constexpr bool _is_expression = true;
using _value_type = ::sqlpp::detail::text; using _value_type = ::sqlpp::detail::text;
using _value_t = std::string; using _value_t = std::string;
using _table_set = ::sqlpp::detail::type_set<>; using _provided_tables = detail::type_set<>;
using _required_tables = ::sqlpp::detail::type_set<>;
text_operand(): text_operand():
_t{} _t{}

View File

@ -49,8 +49,6 @@ namespace sqlpp
struct verbatim_table_t: public sqlpp::table_t<verbatim_table_t, detail::unusable_pseudo_column_t> struct verbatim_table_t: public sqlpp::table_t<verbatim_table_t, detail::unusable_pseudo_column_t>
{ {
using _value_type = no_value_t;
verbatim_table_t(std::string name): verbatim_table_t(std::string name):
_name(name) _name(name)
{ {