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

SelectTypeTests compile again!

This commit is contained in:
rbock 2014-05-20 21:22:55 +02:00
parent c81a7d33ae
commit c4a02d931c
21 changed files with 109 additions and 75 deletions

View File

@ -35,7 +35,7 @@ namespace sqlpp
template<typename Expression, typename AliasProvider> template<typename Expression, typename AliasProvider>
struct expression_alias_t struct expression_alias_t
{ {
using _traits = make_traits<value_type_of<Expression>, tag::named_expression>; using _traits = make_traits<value_type_of<Expression>, tag::named_expression, tag::alias>;
using _recursive_traits = make_recursive_traits<Expression>; using _recursive_traits = make_recursive_traits<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");

View File

@ -76,7 +76,7 @@ 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<no_value_t, tag::alias>; using _traits = make_traits<no_value_t, tag::alias, tag::named_expression>;
using _recursive_traits = make_recursive_traits<Columns...>; using _recursive_traits = make_recursive_traits<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");

View File

@ -109,9 +109,14 @@ namespace sqlpp
using _value_type = typename std::conditional< using _value_type = typename std::conditional<
detail::none_t<is_missing_t<Policies>::value...>::value, detail::none_t<is_missing_t<Policies>::value...>::value,
value_type_of<_result_type_provider>, value_type_of<_result_type_provider>,
no_value_t // if a required statement part is missing (columns in a select), then the statement cannot be used as a value no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value
>::type; >::type;
using _is_expression = typename std::conditional<
std::is_same<_value_type, no_value_t>::value,
std::false_type,
std::true_type>::type;
using _traits = make_traits<_value_type>; using _traits = make_traits<_value_type>;
struct _recursive_traits struct _recursive_traits
@ -136,7 +141,7 @@ namespace sqlpp
{ {
using _policies_t = typename detail::select_policies_t<Db, Policies...>; using _policies_t = typename detail::select_policies_t<Db, Policies...>;
using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select>; using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select, tag::expression_if<typename _policies_t::_is_expression>, tag::named_expression_if<typename _policies_t::_is_expression>>;
using _recursive_traits = typename _policies_t::_recursive_traits; using _recursive_traits = typename _policies_t::_recursive_traits;
using _database_t = Db; using _database_t = Db;
@ -274,9 +279,9 @@ namespace sqlpp
template<typename... Columns> template<typename... Columns>
auto select(Columns... columns) auto select(Columns... columns)
-> decltype(blank_select_t<void>().columns(detail::make_select_column_list_t<void, Columns...>(columns...))) -> decltype(blank_select_t<void>().columns(columns...))
{ {
return blank_select_t<void>().columns(detail::make_select_column_list_t<void, Columns...>(columns...)); return blank_select_t<void>().columns(columns...);
} }
template<typename Database> template<typename Database>
@ -287,9 +292,9 @@ namespace sqlpp
template<typename Database, typename... Columns> template<typename Database, typename... Columns>
auto dynamic_select(const Database&, Columns... columns) auto dynamic_select(const Database&, Columns... columns)
-> decltype(blank_select_t<Database>().columns(detail::make_select_column_list_t<void, Columns...>(columns...))) -> decltype(blank_select_t<Database>().columns(columns...))
{ {
return blank_select_t<Database>().columns(detail::make_select_column_list_t<void, Columns...>(columns...)); return blank_select_t<Database>().columns(columns...);
} }
} }

View File

@ -40,9 +40,8 @@ namespace sqlpp
template<typename Expression, sort_type SortType> template<typename Expression, sort_type SortType>
struct sort_order_t struct sort_order_t
{ {
using _is_sort_order = std::true_type; using _traits = make_traits<no_value_t, tag::sort_order, sqlpp::tag::expression>;
using _provided_tables = detail::type_set<>; using _recursive_traits = make_recursive_traits<Expression>;
using _required_tables = typename Expression::_required_tables;
Expression _expression; Expression _expression;
}; };

View File

@ -47,7 +47,8 @@ namespace sqlpp
{ {
using _parameters = std::tuple<>; using _parameters = std::tuple<>;
using _required_tables = detail::type_set<>; using _required_tables = detail::type_set<>;
using _provided_tables = detail::type_set<Table>; using _provided_tables = detail::type_set<AliasProvider>;
using _extra_tables = detail::type_set<>;
}; };
static_assert(required_tables_of<Table>::size::value == 0, "table aliases must not depend on external tables"); static_assert(required_tables_of<Table>::size::value == 0, "table aliases must not depend on external tables");

View File

@ -73,18 +73,19 @@ namespace sqlpp
}; };
} }
template<typename T> template<typename Operand>
struct maybe_tvin_t struct maybe_tvin_t
{ {
using _provided_tables = detail::type_set<>; using _traits = make_traits<value_type_of<Operand>, tag::expression>;
using _required_tables = typename T::_required_tables; using _recursive_traits = make_recursive_traits<Operand>;
static constexpr bool _is_trivial() static constexpr bool _is_trivial()
{ {
return false; return false;
} }
maybe_tvin_t(T t): maybe_tvin_t(Operand operand):
_value(t) _value(operand)
{} {}
maybe_tvin_t(const maybe_tvin_t&) = default; maybe_tvin_t(const maybe_tvin_t&) = default;
maybe_tvin_t(maybe_tvin_t&&) = default; maybe_tvin_t(maybe_tvin_t&&) = default;
@ -92,21 +93,22 @@ namespace sqlpp
maybe_tvin_t& operator=(maybe_tvin_t&&) = default; maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
~maybe_tvin_t() = default; ~maybe_tvin_t() = default;
T _value; Operand _value;
}; };
template<typename T> template<typename Operand>
struct maybe_tvin_t<tvin_t<T>> struct maybe_tvin_t<tvin_t<Operand>>
{ {
using _provided_tables = detail::type_set<>; using _traits = make_traits<value_type_of<Operand>, tag::expression>;
using _required_tables = typename T::_required_tables; using _recursive_traits = make_recursive_traits<Operand>;
bool _is_trivial() const bool _is_trivial() const
{ {
return _value._is_trivial(); return _value._is_trivial();
}; };
maybe_tvin_t(tvin_t<T> t): maybe_tvin_t(tvin_t<Operand> operand):
_value(t._value) _value(operand._value)
{} {}
maybe_tvin_t(const maybe_tvin_t&) = default; maybe_tvin_t(const maybe_tvin_t&) = default;
maybe_tvin_t(maybe_tvin_t&&) = default; maybe_tvin_t(maybe_tvin_t&&) = default;
@ -114,7 +116,7 @@ namespace sqlpp
maybe_tvin_t& operator=(maybe_tvin_t&&) = default; maybe_tvin_t& operator=(maybe_tvin_t&&) = default;
~maybe_tvin_t() = default; ~maybe_tvin_t() = default;
typename tvin_t<T>::_operand_t _value; typename tvin_t<Operand>::_operand_t _value;
}; };
namespace vendor namespace vendor
@ -139,13 +141,13 @@ namespace sqlpp
}; };
} }
template<typename T> template<typename Operand>
auto tvin(T t) -> tvin_t<typename vendor::wrap_operand<T>::type> auto tvin(Operand operand) -> tvin_t<typename vendor::wrap_operand<Operand>::type>
{ {
using _operand_t = typename vendor::wrap_operand<T>::type; using _operand_t = typename vendor::wrap_operand<Operand>::type;
static_assert(std::is_same<_operand_t, vendor::text_operand>::value static_assert(std::is_same<_operand_t, vendor::text_operand>::value
or not std::is_same<_operand_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)"); or not std::is_same<_operand_t, Operand>::value, "tvin() used with invalid type (only string and primitive types allowed)");
return {{t}}; return {{operand}};
} }
} }

View File

@ -95,6 +95,11 @@ namespace sqlpp
template<typename C> template<typename C>
using named_expression_if = typename std::conditional<C::value, tag::named_expression, void>::type; using named_expression_if = typename std::conditional<C::value, tag::named_expression, void>::type;
} }
namespace tag
{
template<typename C>
using expression_if = typename std::conditional<C::value, tag::expression, void>::type;
}
SQLPP_IS_VALUE_TRAIT_GENERATOR(multi_expression); SQLPP_IS_VALUE_TRAIT_GENERATOR(multi_expression);
SQLPP_IS_VALUE_TRAIT_GENERATOR(alias); SQLPP_IS_VALUE_TRAIT_GENERATOR(alias);
SQLPP_IS_VALUE_TRAIT_GENERATOR(select_flag); SQLPP_IS_VALUE_TRAIT_GENERATOR(select_flag);

View File

@ -35,99 +35,99 @@ namespace sqlpp
{ {
struct less struct less
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
static constexpr const char* _name = "<"; static constexpr const char* _name = "<";
}; };
struct less_equal struct less_equal
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
static constexpr const char* _name = "<="; static constexpr const char* _name = "<=";
}; };
struct equal_to struct equal_to
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
}; };
struct not_equal_to struct not_equal_to
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
}; };
struct greater_equal struct greater_equal
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
static constexpr const char* _name = ">="; static constexpr const char* _name = ">=";
}; };
struct greater struct greater
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
static constexpr const char* _name = ">"; static constexpr const char* _name = ">";
}; };
struct logical_or struct logical_or
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
static constexpr const char* _name = " OR "; static constexpr const char* _name = " OR ";
}; };
struct logical_and struct logical_and
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
static constexpr const char* _name = " AND "; static constexpr const char* _name = " AND ";
}; };
struct logical_not struct logical_not
{ {
using _value_type = ::sqlpp::detail::boolean; using _traits = make_traits<::sqlpp::detail::boolean>;
}; };
template<typename ValueType> template<typename ValueType>
struct plus struct plus
{ {
using _value_type = ValueType; using _traits = make_traits<ValueType>;
static constexpr const char* _name = "+"; static constexpr const char* _name = "+";
}; };
template<typename ValueType> template<typename ValueType>
struct minus struct minus
{ {
using _value_type = ValueType; using _traits = make_traits<ValueType>;
static constexpr const char* _name = "-"; static constexpr const char* _name = "-";
}; };
template<typename ValueType> template<typename ValueType>
struct multiplies struct multiplies
{ {
using _value_type = ValueType; using _traits = make_traits<ValueType>;
static constexpr const char* _name = "*"; static constexpr const char* _name = "*";
}; };
struct divides struct divides
{ {
using _value_type = ::sqlpp::detail::floating_point; using _traits = make_traits<::sqlpp::detail::floating_point>;
static constexpr const char* _name = "/"; static constexpr const char* _name = "/";
}; };
struct modulus struct modulus
{ {
using _value_type = ::sqlpp::detail::integral; using _traits = make_traits<::sqlpp::detail::integral>;
static constexpr const char* _name = "%"; static constexpr const char* _name = "%";
}; };
template<typename ValueType> template<typename ValueType>
struct unary_minus struct unary_minus
{ {
using _value_type = ValueType; using _traits = make_traits<ValueType>;
static constexpr const char* _name = "-"; static constexpr const char* _name = "-";
}; };
template<typename ValueType> template<typename ValueType>
struct unary_plus struct unary_plus
{ {
using _value_type = ValueType; using _traits = make_traits<ValueType>;
static constexpr const char* _name = "+"; static constexpr const char* _name = "+";
}; };
} }

View File

@ -36,8 +36,10 @@ namespace sqlpp
template<typename NameType, typename ValueType, bool TrivialValueIsNull> template<typename NameType, typename ValueType, bool TrivialValueIsNull>
struct field_t struct field_t
{ {
using _traits = make_traits<ValueType, tag::noop>;
using _recursive_traits = make_recursive_traits<>;
using _name_t = NameType; using _name_t = NameType;
using _value_type = ValueType;
static constexpr bool _trivial_value_is_null = TrivialValueIsNull; static constexpr bool _trivial_value_is_null = TrivialValueIsNull;
}; };

View File

@ -55,6 +55,7 @@ namespace sqlpp
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table"); static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
from_t& _from() { return *this; }
from_t(Tables... tables): from_t(Tables... tables):
_tables(tables...) _tables(tables...)
@ -84,7 +85,7 @@ namespace sqlpp
template<typename Table> template<typename Table>
void _add_from_impl(Table table, const std::true_type&) void _add_from_impl(Table table, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_from._dynamic_tables.emplace_back(table); return static_cast<typename Policies::_statement_t*>(this)->_from()._dynamic_tables.emplace_back(table);
} }
template<typename Table> template<typename Table>

View File

@ -54,6 +54,8 @@ namespace sqlpp
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()"); static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
group_by_t& _group_by() { return *this; }
group_by_t(Expressions... expressions): group_by_t(Expressions... expressions):
_expressions(expressions...) _expressions(expressions...)
{} {}
@ -89,7 +91,7 @@ namespace sqlpp
template<typename Expression> template<typename Expression>
void _add_group_by_impl(Expression expression, const std::true_type&) void _add_group_by_impl(Expression expression, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_group_by._dynamic_expressions.emplace_back(expression); return static_cast<typename Policies::_statement_t*>(this)->_group_by()._dynamic_expressions.emplace_back(expression);
} }
template<typename Expression> template<typename Expression>

View File

@ -50,6 +50,8 @@ namespace sqlpp
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()"); static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()"); static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
having_t& _having() { return *this; }
having_t(Expressions... expressions): having_t(Expressions... expressions):
_expressions(expressions...) _expressions(expressions...)
{} {}
@ -85,7 +87,7 @@ namespace sqlpp
template<typename Expression> template<typename Expression>
void _add_having_impl(Expression expression, const std::true_type&) void _add_having_impl(Expression expression, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_having._dynamic_expressions.emplace_back(expression); return static_cast<typename Policies::_statement_t*>(this)->_having()._dynamic_expressions.emplace_back(expression);
} }
template<typename Expression> template<typename Expression>

View File

@ -68,6 +68,8 @@ namespace sqlpp
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>; using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
using _recursive_traits = make_recursive_traits<>; using _recursive_traits = make_recursive_traits<>;
dynamic_limit_t& _limit() { return *this; }
dynamic_limit_t(): dynamic_limit_t():
_value(noop()) _value(noop())
{ {
@ -94,8 +96,8 @@ namespace sqlpp
{ {
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL // FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
using arg_t = typename wrap_operand<Limit>::type; using arg_t = typename wrap_operand<Limit>::type;
static_cast<typename Policies::_statement_t*>(this)->_limit._value = arg_t{value}; static_cast<typename Policies::_statement_t*>(this)->_limit()._value = arg_t{value};
static_cast<typename Policies::_statement_t*>(this)->_limit._initialized = true; static_cast<typename Policies::_statement_t*>(this)->_limit()._initialized = true;
} }
}; };

View File

@ -68,6 +68,8 @@ namespace sqlpp
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>; using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
using _recursive_traits = make_recursive_traits<>; using _recursive_traits = make_recursive_traits<>;
dynamic_offset_t& _offset() { return *this; }
dynamic_offset_t(): dynamic_offset_t():
_value(noop()) _value(noop())
{ {
@ -94,8 +96,8 @@ namespace sqlpp
{ {
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL // FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
using arg_t = typename wrap_operand<Offset>::type; using arg_t = typename wrap_operand<Offset>::type;
static_cast<typename Policies::_statement_t*>(this)->_offset._value = arg_t{value}; static_cast<typename Policies::_statement_t*>(this)->_offset()._value = arg_t{value};
static_cast<typename Policies::_statement_t*>(this)->_offset._initialized = true; static_cast<typename Policies::_statement_t*>(this)->_offset()._initialized = true;
} }
}; };

View File

@ -53,6 +53,8 @@ namespace sqlpp
static_assert(::sqlpp::detail::all_t<is_sort_order_t<Expressions>::value...>::value, "at least one argument is not a sort order expression in order_by()"); static_assert(::sqlpp::detail::all_t<is_sort_order_t<Expressions>::value...>::value, "at least one argument is not a sort order expression in order_by()");
order_by_t& _order_by() { return *this; }
order_by_t(Expressions... expressions): order_by_t(Expressions... expressions):
_expressions(expressions...) _expressions(expressions...)
{} {}
@ -88,7 +90,7 @@ namespace sqlpp
template<typename Expression> template<typename Expression>
void _add_order_by_impl(Expression expression, const std::true_type&) void _add_order_by_impl(Expression expression, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_order_by._dynamic_expressions.emplace_back(expression); return static_cast<typename Policies::_statement_t*>(this)->_order_by()._dynamic_expressions.emplace_back(expression);
} }
template<typename Expression> template<typename Expression>

View File

@ -164,6 +164,8 @@ namespace sqlpp
template <typename Db> template <typename Db>
using _dynamic_t = select_column_list_t<Db, std::tuple<Columns...>>; using _dynamic_t = select_column_list_t<Db, std::tuple<Columns...>>;
select_column_list_t& _select_column_list() { return *this; }
select_column_list_t(std::tuple<Columns...> columns): select_column_list_t(std::tuple<Columns...> columns):
_columns(columns) _columns(columns)
{} {}
@ -213,7 +215,7 @@ namespace sqlpp
template<typename NamedExpression> template<typename NamedExpression>
void _add_column_impl(NamedExpression namedExpression, const std::true_type&) void _add_column_impl(NamedExpression namedExpression, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_column_list._dynamic_columns.emplace_back(namedExpression); return static_cast<typename Policies::_statement_t*>(this)->_select_column_list()._dynamic_columns.emplace_back(namedExpression);
} }
template<typename NamedExpression> template<typename NamedExpression>

View File

@ -51,6 +51,8 @@ namespace sqlpp
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list"); static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
select_flag_list_t& _select_flag_list() { return *this; }
select_flag_list_t(Flags... flags): select_flag_list_t(Flags... flags):
_flags(flags...) _flags(flags...)
{} {}
@ -86,7 +88,7 @@ namespace sqlpp
template<typename Flag> template<typename Flag>
void _add_flag_impl(Flag flag, const std::true_type&) void _add_flag_impl(Flag flag, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_flag_list._dynamic_flags.emplace_back(flag); return static_cast<typename Policies::_statement_t*>(this)->_select_flag_list()._dynamic_flags.emplace_back(flag);
} }
template<typename Flag> template<typename Flag>

View File

@ -35,8 +35,11 @@ namespace sqlpp
template<typename Expr> template<typename Expr>
struct select_column_spec_t struct select_column_spec_t
{ {
using _traits = make_traits<value_type_of<Expr>>;
using _recursive_traits = make_recursive_traits<>;
using _value_type = value_type_of<Expr>; // FIXME: column specs probably should use _traits, too
using _name_t = typename Expr::_name_t; using _name_t = typename Expr::_name_t;
using _value_type = typename Expr::_value_type;
struct _column_type struct _column_type
{ {
using _must_not_insert = std::true_type; using _must_not_insert = std::true_type;

View File

@ -51,6 +51,8 @@ namespace sqlpp
static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()"); static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()"); static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
where_t& _where() { return *this; }
where_t(Expressions... expressions): where_t(Expressions... expressions):
_expressions(expressions...) _expressions(expressions...)
{} {}
@ -86,7 +88,7 @@ namespace sqlpp
template<typename Expression> template<typename Expression>
void _add_where_impl(Expression expression, const std::true_type&) void _add_where_impl(Expression expression, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_where._dynamic_expressions.emplace_back(expression); return static_cast<typename Policies::_statement_t*>(this)->_where()._dynamic_expressions.emplace_back(expression);
} }
template<typename Expression> template<typename Expression>

View File

@ -11,7 +11,7 @@ endmacro ()
#build_and_run(RemoveTest) #build_and_run(RemoveTest)
#build_and_run(UpdateTest) #build_and_run(UpdateTest)
#build_and_run(SelectTest) #build_and_run(SelectTest)
#build_and_run(SelectTypeTest) build_and_run(SelectTypeTest)
build_and_run(FunctionTest) build_and_run(FunctionTest)
#build_and_run(PreparedTest) #build_and_run(PreparedTest)

View File

@ -158,10 +158,10 @@ int main()
// Test a select of a single column without a from // Test a select of a single column without a from
{ {
using T = decltype(select(t.alpha)); // Hint: The current rule is pretty crude (a from is required), but certainly better than nothing using T = decltype(select(t.alpha));
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement"); static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement"); static_assert(not sqlpp::must_not_update_t<T>::value, "type requirement");
@ -175,8 +175,8 @@ int main()
// Test a select of a single numeric table column // Test a select of a single numeric table column
{ {
using T = decltype(select(t.alpha).from(t)); using T = decltype(select(t.alpha).from(t));
static_assert(sqlpp::is_select_column_list_t<decltype(T::_column_list)>::value, "Must not be noop"); //static_assert(sqlpp::is_select_column_list_t<decltype(T::_column_list)>::value, "Must not be noop");
static_assert(sqlpp::is_from_t<decltype(T::_from)>::value, "Must not be noop"); //static_assert(sqlpp::is_from_t<decltype(T::_from)>::value, "Must not be noop");
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement"); static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
@ -290,7 +290,7 @@ int main()
{ {
auto m = multi_column(t.alpha, t.beta).as(alias::a); auto m = multi_column(t.alpha, t.beta).as(alias::a);
auto a = select(m).from(t).as(alias::b).a; auto a = select(m).from(t).as(alias::b).a;
static_assert(not sqlpp::is_value_t<decltype(a)>::value, "a multi_column is not a value"); // FIXME: Do we really need that test? multi_column is a no_value static_assert(not sqlpp::is_expression_t<decltype(a)>::value, "a multi_column is not a value");
} }
// Test that result sets with identical name/value combinations have identical types // Test that result sets with identical name/value combinations have identical types
{ {
@ -299,8 +299,8 @@ int main()
using A = typename decltype(a)::_result_row_t<MockDb>; using A = typename decltype(a)::_result_row_t<MockDb>;
using B = typename decltype(b)::_result_row_t<MockDb>; using B = typename decltype(b)::_result_row_t<MockDb>;
static_assert(std::is_same< static_assert(std::is_same<
decltype(t.alpha)::_value_type::_base_value_type, sqlpp::value_type_of<decltype(t.alpha)>,
decltype(f.epsilon)::_value_type::_base_value_type>::value, "Two bigint columns must have identical base_value_type"); sqlpp::value_type_of<decltype(f.epsilon)>>::value, "Two bigint columns must have identical base_value_type");
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types"); static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
} }
@ -339,9 +339,8 @@ int main()
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag"); static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
using T = sqlpp::vendor::wrap_operand<int>::type; using T = sqlpp::vendor::wrap_operand<int>::type;
static_assert(sqlpp::is_regular<T>::value, "type requirement"); static_assert(sqlpp::is_regular<T>::value, "type requirement");
static_assert(T::_is_expression, "T has to be an expression"); static_assert(sqlpp::is_expression_t<T>::value, "T has to be an expression");
static_assert(std::is_same<typename T::_value_type::_is_numeric, std::true_type>::value, "T has to be a numeric"); static_assert(sqlpp::is_numeric_t<T>::value, "T has to be numeric");
static_assert(sqlpp::is_numeric_t<T>::value, "T has to be a numeric");
static_assert(sqlpp::is_numeric_t<decltype(t.alpha)>::value, "TabBar.alpha has to be a numeric"); static_assert(sqlpp::is_numeric_t<decltype(t.alpha)>::value, "TabBar.alpha has to be a numeric");
((t.alpha + 7) + 4).asc(); ((t.alpha + 7) + 4).asc();
static_assert(sqlpp::is_boolean_t<decltype(t.gamma == t.gamma)>::value, "Comparison expression have to be boolean"); static_assert(sqlpp::is_boolean_t<decltype(t.gamma == t.gamma)>::value, "Comparison expression have to be boolean");
@ -353,7 +352,6 @@ int main()
static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted"); static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted");
serialize(t.alpha, printer).str(); serialize(t.alpha, printer).str();
std::cerr << "\n" << sizeof(test::TabBar) << std::endl; std::cerr << "\n" << sizeof(test::TabBar) << std::endl;
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_is_named_expression, std::true_type>::value, "alpha should be a named expression");
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha)>::value, "alpha should be a named expression"); static_assert(sqlpp::is_named_expression_t<decltype(t.alpha)>::value, "alpha should be a named expression");
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be a named expression"); static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be a named expression");
static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be an alias"); static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be an alias");
@ -366,6 +364,7 @@ int main()
auto s = select(r.a).from(r); auto s = select(r.a).from(r);
using RA = decltype(r.a); using RA = decltype(r.a);
using S = decltype(s); using S = decltype(s);
/*
using SCL = typename S::_column_list_t; using SCL = typename S::_column_list_t;
using SF = typename S::_from_t; using SF = typename S::_from_t;
static_assert(sqlpp::is_select_column_list_t<SCL>::value, "no column list"); static_assert(sqlpp::is_select_column_list_t<SCL>::value, "no column list");
@ -375,6 +374,7 @@ int main()
static_assert(SCL_T::size::value == 1, "unexpected table_set in column_list"); static_assert(SCL_T::size::value == 1, "unexpected table_set in column_list");
static_assert(SF_T::size::value == 1, "unexpected table_set in from"); static_assert(SF_T::size::value == 1, "unexpected table_set in from");
static_assert(std::is_same<SCL_T, SF_T>::value, "should be the same"); static_assert(std::is_same<SCL_T, SF_T>::value, "should be the same");
*/
static_assert(sqlpp::is_boolean_t<decltype(select(r.a).from(r))>::value, "select(bool) has to be a bool"); static_assert(sqlpp::is_boolean_t<decltype(select(r.a).from(r))>::value, "select(bool) has to be a bool");
auto s1 = sqlpp::select().flags(sqlpp::distinct, sqlpp::straight_join).columns(l.alpha, l.beta, select(r.a).from(r)) auto s1 = sqlpp::select().flags(sqlpp::distinct, sqlpp::straight_join).columns(l.alpha, l.beta, select(r.a).from(r))
.from(r,t,l) .from(r,t,l)