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

More tests fixed

Make as_expression usable in select only
This commit is contained in:
Roland Bock 2024-07-27 19:25:38 +02:00
parent 2b7b568c49
commit 6a92f139b7
37 changed files with 621 additions and 557 deletions

View File

@ -27,12 +27,13 @@
*/ */
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/enable_as.h>
#include <sqlpp11/serialize.h> #include <sqlpp11/serialize.h>
namespace sqlpp namespace sqlpp
{ {
template <typename Expr> template <typename Expr>
struct dynamic_t struct dynamic_t: public enable_as<dynamic_t<Expr>>
{ {
using _traits = make_traits<value_type_of_t<Expr>, tag::is_multi_expression>; using _traits = make_traits<value_type_of_t<Expr>, tag::is_multi_expression>;
@ -50,13 +51,7 @@ namespace sqlpp
Expr _expr; Expr _expr;
}; };
// No value_type_of defined for dynamic_t, because it is to be used in very specific contexts in which _expr may be // No value_type_of or name_tag_of defined for dynamic_t, to prevent its usage outside of select columns.
// used depending on the value of _condition.
template <typename Expr>
struct name_tag_of<dynamic_t<Expr>> : public name_tag_of<Expr>
{
};
template <typename Expr> template <typename Expr>
struct nodes_of<dynamic_t<Expr>> : public nodes_of<Expr> struct nodes_of<dynamic_t<Expr>> : public nodes_of<Expr>

View File

@ -42,10 +42,14 @@ namespace sqlpp
public: public:
template <typename AliasProvider> template <typename AliasProvider>
constexpr auto as(const AliasProvider& alias) const constexpr auto as(const AliasProvider& alias) const -> decltype(::sqlpp::as(this->derived(), alias))
{ {
return ::sqlpp::as(this->derived(), alias); return ::sqlpp::as(this->derived(), alias);
} }
}; };
#warning: columns and tables should also use enable_as with specialized as_expression functions.
template <typename T>
struct has_enabled_as : public std::is_base_of<enable_as<T>, T>{};
} // namespace sqlpp } // namespace sqlpp

View File

@ -123,4 +123,7 @@ namespace sqlpp
} }
}; };
template <typename T>
struct has_enabled_comparison : public std::is_base_of<enable_comparison<T>, T>{};
} // namespace sqlpp } // namespace sqlpp

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -26,17 +26,54 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sqlpp11/operator/as_expression.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/join.h>
namespace sqlpp namespace sqlpp
{ {
template <typename Expr> template <typename Joinable>
struct alias_operators struct enable_join
{ {
template <typename alias_provider> constexpr auto derived() const -> const Joinable&
as_expression<Expr, alias_provider> as(const alias_provider& /*unused*/) const
{ {
return {*static_cast<const Expr*>(this)}; return static_cast<const Joinable&>(*this);
}
public:
template <typename T>
auto join(T t) const -> decltype(::sqlpp::join(this->derived(), t))
{
return ::sqlpp::join(this->derived(), t);
}
template <typename T>
auto inner_join(T t) const -> decltype(::sqlpp::inner_join(this->derived(), t))
{
return ::sqlpp::inner_join(this->derived(), t);
}
template <typename T>
auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(this->derived(), t))
{
return ::sqlpp::left_outer_join(this->derived(), t);
}
template <typename T>
auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(this->derived(), t))
{
return ::sqlpp::right_outer_join(this->derived(), t);
}
template <typename T>
auto outer_join(T t) const -> decltype(::sqlpp::outer_join(this->derived(), t))
{
return ::sqlpp::outer_join(this->derived(), t);
}
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(this->derived(), t))
{
return ::sqlpp::cross_join(this->derived(), t);
} }
}; };
} // namespace sqlpp } // namespace sqlpp

View File

@ -29,7 +29,7 @@
#include <type_traits> #include <type_traits>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/dynamic.h> #include <sqlpp11/select_column_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -76,24 +76,15 @@ namespace sqlpp
template <typename Select, typename NamedExpr> template <typename Select, typename NamedExpr>
struct make_field_spec_impl struct make_field_spec_impl
{ {
using ValueType = value_type_of_t<NamedExpr>; using ValueType = select_column_value_type_of_t<NamedExpr>;
static constexpr bool _depends_on_outer_table = static constexpr bool _depends_on_outer_table =
detail::make_intersect_set_t<required_tables_of_t<NamedExpr>, detail::make_intersect_set_t<required_tables_of_t<NamedExpr>,
typename Select::_used_outer_tables>::size::value > 0; typename Select::_used_outer_tables>::size::value > 0;
using type = field_spec_t< using type = field_spec_t<
name_tag_of_t<NamedExpr>, select_column_name_tag_of_t<NamedExpr>,
typename std::conditional<_depends_on_outer_table, sqlpp::force_optional_t<ValueType>, ValueType>::type>; typename std::conditional<_depends_on_outer_table, sqlpp::force_optional_t<ValueType>, ValueType>::type>;
}; };
template <typename Select, typename NamedExpr>
struct make_field_spec_impl<Select, dynamic_t<NamedExpr>>
{
using ValueType = force_optional_t<value_type_of_t<NamedExpr>>;
using type = field_spec_t<name_tag_of_t<NamedExpr>,
ValueType>;
};
} // namespace detail } // namespace detail
template <typename Select, typename NamedExpr> template <typename Select, typename NamedExpr>

View File

@ -47,7 +47,6 @@ namespace sqlpp
struct from_t struct from_t
{ {
using _traits = make_traits<no_value_t, tag::is_from>; using _traits = make_traits<no_value_t, tag::is_from>;
using _nodes = detail::type_vector<Table>;
using _data_t = from_data_t<Table>; using _data_t = from_data_t<Table>;
@ -66,6 +65,12 @@ namespace sqlpp
}; };
}; };
template<typename Table>
struct nodes_of<from_t<Table>>
{
using type = detail::type_vector<Table>;
};
SQLPP_PORTABLE_STATIC_ASSERT( SQLPP_PORTABLE_STATIC_ASSERT(
assert_from_not_pre_join_t, assert_from_not_pre_join_t,
"from() argument is a pre join, please use an explicit on() condition or unconditionally()"); "from() argument is a pre join, please use an explicit on() condition or unconditionally()");
@ -94,7 +99,6 @@ namespace sqlpp
struct no_from_t struct no_from_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -82,13 +82,13 @@ namespace sqlpp
}; };
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_group_by_args_are_expressions_t, SQLPP_PORTABLE_STATIC_ASSERT(assert_group_by_args_have_values_t,
"arguments for group_by() must be valid expressions"); "all arguments for group_by() must have values");
template <typename... Exprs> template <typename... Exprs>
struct check_group_by struct check_group_by
{ {
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<logic::all_t<is_expression_t<Exprs>::value...>::value, assert_group_by_args_are_expressions_t>>; static_check_t<logic::all_t<has_value_type<Exprs>::value...>::value, assert_group_by_args_have_values_t>>;
}; };
template <typename... Exprs> template <typename... Exprs>
using check_group_by_t = typename check_group_by<Exprs...>::type; using check_group_by_t = typename check_group_by<Exprs...>::type;

View File

@ -33,6 +33,7 @@ namespace sqlpp
{ {
struct noop struct noop
{ {
#warning: All this should go away
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>; using _nodes = detail::type_vector<>;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
/* /*
Copyright (c) 2017, Roland Bock Copyright (c) 2024, Roland Bock
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace sqlpp namespace sqlpp
{ {
#warning: need type tests
template <typename Expression, typename AliasProvider> template <typename Expression, typename AliasProvider>
struct as_expression struct as_expression
{ {
@ -55,17 +56,7 @@ namespace sqlpp
Expression _expression; Expression _expression;
}; };
template <typename Expression, typename AliasProvider> // No value_type_of or name_tag_of defined for as_expression, to prevent its usage outside of select columns.
struct value_type_of<as_expression<Expression, AliasProvider>>
{
using type = value_type_of_t<Expression>;
};
template <typename Expression, typename AliasProvider>
struct name_tag_of<as_expression<Expression, AliasProvider>>
{
using type = name_tag_of_t<AliasProvider>;
};
template <typename Expression, typename AliasProvider> template <typename Expression, typename AliasProvider>
struct nodes_of<as_expression<Expression, AliasProvider>> struct nodes_of<as_expression<Expression, AliasProvider>>
@ -73,11 +64,6 @@ namespace sqlpp
using type = detail::type_vector<Expression>; using type = detail::type_vector<Expression>;
}; };
template <typename Expression, typename AliasProvider>
struct has_name<as_expression<Expression, AliasProvider>> : std::true_type
{
};
template <typename Context, typename Expression, typename AliasProvider> template <typename Context, typename Expression, typename AliasProvider>
Context& serialize(Context& context, const as_expression<Expression, AliasProvider>& t) Context& serialize(Context& context, const as_expression<Expression, AliasProvider>& t)
{ {
@ -97,4 +83,12 @@ namespace sqlpp
return {std::move(expr)}; return {std::move(expr)};
} }
template <typename Expr>
struct dynamic_t;
template <typename Expr, typename AliasProvider, typename = check_as_args<Expr, AliasProvider>>
constexpr auto as(dynamic_t<Expr> expr, const AliasProvider&) -> as_expression<dynamic_t<Expr>, AliasProvider>
{
return {std::move(expr)};
}
} // namespace sqlpp } // namespace sqlpp

View File

@ -63,7 +63,10 @@ namespace sqlpp
}; };
template <typename ValueType, typename Expr> template <typename ValueType, typename Expr>
struct nodes_of<parameterized_verbatim_t<ValueType, Expr>> : public nodes_of<Expr>{}; struct nodes_of<parameterized_verbatim_t<ValueType, Expr>>
{
using type = detail::type_vector<Expr>;
};
template <typename Context, typename ValueType, typename Expr> template <typename Context, typename ValueType, typename Expr>
Context& serialize(Context& context, const parameterized_verbatim_t<ValueType, Expr>& t) Context& serialize(Context& context, const parameterized_verbatim_t<ValueType, Expr>& t)

View File

@ -28,6 +28,7 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/enable_as.h> #include <sqlpp11/enable_as.h>
#include <sqlpp11/enable_join.h>
namespace sqlpp namespace sqlpp
{ {
@ -59,8 +60,8 @@ namespace sqlpp
} }
template <typename Select, typename AliasProvider, typename... ColumnSpecs> template <typename Select, typename AliasProvider, typename... ColumnSpecs>
struct select_as_t struct select_as_t : public ColumnSpecs::_alias_t::template _member_t<pseudo_column_t<AliasProvider, ColumnSpecs>>...,
: public ColumnSpecs::_alias_t::template _member_t<pseudo_column_t<AliasProvider, ColumnSpecs>>... public enable_join<select_as_t<Select, AliasProvider, ColumnSpecs...>>
{ {
select_as_t(Select select) : _select(select) select_as_t(Select select) : _select(select)
{ {

View File

@ -27,12 +27,14 @@
*/ */
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/operator/as_expression.h>
#include <sqlpp11/dynamic.h> #include <sqlpp11/dynamic.h>
#include <sqlpp11/field_spec.h> #include <sqlpp11/field_spec.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/policy_update.h> #include <sqlpp11/policy_update.h>
#include <sqlpp11/result_row.h> #include <sqlpp11/result_row.h>
#include <sqlpp11/select_as.h> #include <sqlpp11/select_as.h>
#include <sqlpp11/select_column_traits.h>
#include <sqlpp11/table.h> #include <sqlpp11/table.h>
#include <tuple> #include <tuple>
@ -84,7 +86,7 @@ namespace sqlpp
template <typename Select, typename Column> template <typename Select, typename Column>
struct select_column_spec_t: public name_tag_base struct select_column_spec_t: public name_tag_base
{ {
using _alias_t = name_tag_of_t<Column>; using _alias_t = select_column_name_tag_of_t<Column>;
#warning: Need to test this! #warning: Need to test this!
static constexpr bool _depends_on_outer_table = static constexpr bool _depends_on_outer_table =
@ -92,7 +94,7 @@ namespace sqlpp
0; 0;
}; };
template <typename Select, typename Column> template <typename Select, typename Column>
struct value_type_of<select_column_spec_t<Select, Column>> : public value_type_of<Column> {}; struct value_type_of<select_column_spec_t<Select, Column>> : public select_column_value_type_of<Column> {};
SQLPP_PORTABLE_STATIC_ASSERT( SQLPP_PORTABLE_STATIC_ASSERT(
assert_no_unknown_tables_in_selected_columns_t, assert_no_unknown_tables_in_selected_columns_t,
@ -108,7 +110,6 @@ namespace sqlpp
struct select_column_list_t struct select_column_list_t
{ {
using _traits = typename detail::select_traits<Columns...>::_traits; using _traits = typename detail::select_traits<Columns...>::_traits;
using _nodes = detail::type_vector<Columns...>;
using _data_t = std::tuple<Columns...>; using _data_t = std::tuple<Columns...>;
@ -215,30 +216,22 @@ namespace sqlpp
}; };
}; };
template <typename Column> template <typename Column>
struct value_type_of<select_column_list_t<Column>> : public value_type_of<Column> struct value_type_of<select_column_list_t<Column>> : public select_column_value_type_of<Column>
{ {
}; };
template <typename Column>
struct value_type_of<select_column_list_t<dynamic_t<Column>>>
{
using type = force_optional_t<value_type_of_t<Column>>;
};
template <typename Column> template <typename Column>
struct name_tag_of<select_column_list_t<Column>> : public name_tag_of<Column> struct name_tag_of<select_column_list_t<Column>> : public name_tag_of<Column>
{ {
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable"); template <typename... Columns>
struct nodes_of<select_column_list_t<Columns...>>
{
using type = detail::type_vector<Columns...>;
};
template <typename T> SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable");
struct check_selected_column : std::integral_constant<bool, has_value_type<T>::value and has_name<T>::value>
{
};
template <typename T>
struct check_selected_column<dynamic_t<T>> : check_selected_column<T>
{
};
template <typename T> template <typename T>
struct check_selected_tuple; struct check_selected_tuple;
@ -246,7 +239,7 @@ namespace sqlpp
struct check_selected_tuple<std::tuple<T...>> struct check_selected_tuple<std::tuple<T...>>
{ {
using type = static_combined_check_t< using type = static_combined_check_t<
static_check_t<logic::all_t<check_selected_column<T>::value...>::value, static_check_t<logic::all_t<(select_column_has_value_type<T>::value and select_column_has_name<T>::value)...>::value,
assert_selected_colums_are_selectable_t>>; assert_selected_colums_are_selectable_t>>;
}; };
template <typename T> template <typename T>
@ -265,7 +258,6 @@ namespace sqlpp
struct no_select_column_list_t struct no_select_column_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>; using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>;
using _nodes = detail::type_vector<>;
struct _alias_t struct _alias_t
{ {

View File

@ -0,0 +1,91 @@
#pragma once
/*
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/operator/as_expression.h>
#include <sqlpp11/dynamic.h>
#include <sqlpp11/type_traits.h>
// Select columns require a value type and a name.
// They can be dynamic values and they can be as_expressions.
// These type traits consider `dynamic_t` and `as_expression`
namespace sqlpp
{
// Get value type
template <typename T>
struct select_column_value_type_of : public value_type_of<T>
{
};
template <typename T>
using select_column_value_type_of_t = typename select_column_value_type_of<T>::type;
template <typename T>
struct select_column_value_type_of<dynamic_t<T>>
{
using type = sqlpp::force_optional_t<select_column_value_type_of_t<T>>;
};
template <typename T, typename AliasProvider>
struct select_column_value_type_of<as_expression<T, AliasProvider>> : public select_column_value_type_of<T>
{
};
// Get name tag
template <typename T>
struct select_column_name_tag_of : public name_tag_of<T>
{
};
template <typename T>
using select_column_name_tag_of_t = typename select_column_name_tag_of<T>::type;
template <typename T>
struct select_column_name_tag_of<dynamic_t<T>> : public select_column_name_tag_of<T>
{
};
template <typename T, typename AliasProvider>
struct select_column_name_tag_of<as_expression<T, AliasProvider>> : public name_tag_of<AliasProvider>
{
};
// Test for value
template <typename T>
struct select_column_has_value_type
: public std::integral_constant<bool, not std::is_same<select_column_value_type_of_t<T>, no_value_t>::value>
{
};
// Test for name
template <typename T>
struct select_column_has_name
: public std::integral_constant<bool, not std::is_same<select_column_name_tag_of_t<T>, no_name_t>::value>
{
};
} // namespace sqlpp

View File

@ -55,7 +55,6 @@ namespace sqlpp
struct single_table_t struct single_table_t
{ {
using _traits = make_traits<no_value_t, tag::is_single_table>; using _traits = make_traits<no_value_t, tag::is_single_table>;
using _nodes = detail::type_vector<Table>;
#warning: can't we do this with a table_t<> specialization #warning: can't we do this with a table_t<> specialization
static_assert(is_table<Table>::value, "argument has to be a table"); static_assert(is_table<Table>::value, "argument has to be a table");
@ -81,6 +80,12 @@ namespace sqlpp
}; };
}; };
template <typename Table>
struct nodes_of<single_table_t<Table>>
{
using type = detail::type_vector<Table>;
};
SQLPP_PORTABLE_STATIC_ASSERT(assert_update_table_arg_is_table_t, "argument for update() must be a table"); SQLPP_PORTABLE_STATIC_ASSERT(assert_update_table_arg_is_table_t, "argument for update() must be a table");
template <typename Table> template <typename Table>
struct check_update_table struct check_update_table
@ -94,7 +99,6 @@ namespace sqlpp
struct no_single_table_t struct no_single_table_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -26,6 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sqlpp11/enable_join.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/table_alias.h> #include <sqlpp11/table_alias.h>
#include <sqlpp11/all_of.h> #include <sqlpp11/all_of.h>
@ -36,7 +37,7 @@
namespace sqlpp namespace sqlpp
{ {
template <typename TableSpec> template <typename TableSpec>
struct table_t : public TableSpec::_table_columns<TableSpec> struct table_t : public TableSpec::_table_columns<TableSpec>, public enable_join<table_t<TableSpec>>
{ {
using _traits = make_traits<no_value_t, tag::is_raw_table>; using _traits = make_traits<no_value_t, tag::is_raw_table>;
@ -51,42 +52,6 @@ namespace sqlpp
template <typename AliasProvider> template <typename AliasProvider>
using _alias_t = table_alias_t<AliasProvider, TableSpec>; using _alias_t = table_alias_t<AliasProvider, TableSpec>;
template <typename T>
auto join(T t) const -> decltype(::sqlpp::join(*this, t))
{
return ::sqlpp::join(*this, t);
}
template <typename T>
auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t))
{
return ::sqlpp::inner_join(*this, t);
}
template <typename T>
auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t))
{
return ::sqlpp::left_outer_join(*this, t);
}
template <typename T>
auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t))
{
return ::sqlpp::right_outer_join(*this, t);
}
template <typename T>
auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t))
{
return ::sqlpp::outer_join(*this, t);
}
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t))
{
return ::sqlpp::cross_join(*this, t);
}
template <typename AliasProvider> template <typename AliasProvider>
_alias_t<AliasProvider> as(const AliasProvider& /*unused*/) const _alias_t<AliasProvider> as(const AliasProvider& /*unused*/) const
{ {

View File

@ -26,8 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sqlpp11/operator/as_expression.h> #include <sqlpp11/enable_join.h>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/table_columns.h> #include <sqlpp11/table_columns.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/serialize.h> #include <sqlpp11/serialize.h>
@ -37,15 +36,9 @@
namespace sqlpp namespace sqlpp
{ {
template <typename AliasProvider, typename TableSpec> template <typename AliasProvider, typename TableSpec>
struct table_alias_t : public TableSpec::_table_columns<AliasProvider> struct table_alias_t : public TableSpec::_table_columns<AliasProvider>,
public enable_join<table_alias_t<AliasProvider, TableSpec>>
{ {
#warning: Need to declare this an alias?
/*
using _traits = make_traits<value_type_of_t<TableSpec>,
tag::is_alias,
tag_if<tag::is_selectable, is_expression_t<TableSpec>::value>>;
*/
using _nodes = detail::type_vector<>; using _nodes = detail::type_vector<>;
using _required_ctes = required_ctes_of<TableSpec>; using _required_ctes = required_ctes_of<TableSpec>;
using _provided_tables = detail::type_set<AliasProvider>; using _provided_tables = detail::type_set<AliasProvider>;
@ -54,42 +47,6 @@ namespace sqlpp
#warning: need to inherit? #warning: need to inherit?
//using _column_tuple_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>; //using _column_tuple_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>;
template <typename T>
auto join(T t) const -> decltype(::sqlpp::join(*this, t))
{
return ::sqlpp::join(*this, t);
}
template <typename T>
auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t))
{
return ::sqlpp::inner_join(*this, t);
}
template <typename T>
auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t))
{
return ::sqlpp::left_outer_join(*this, t);
}
template <typename T>
auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t))
{
return ::sqlpp::right_outer_join(*this, t);
}
template <typename T>
auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t))
{
return ::sqlpp::outer_join(*this, t);
}
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t))
{
return ::sqlpp::cross_join(*this, t);
}
}; };
template<typename AliasProvider, typename TableSpec> template<typename AliasProvider, typename TableSpec>

View File

@ -37,8 +37,6 @@ namespace sqlpp
{ {
using _traits = make_traits<text, tag::is_expression, tag::is_selectable>; using _traits = make_traits<text, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr>;
trim_t(const Expr expr) : _expr(expr) trim_t(const Expr expr) : _expr(expr)
{ {
} }
@ -52,6 +50,15 @@ namespace sqlpp
Expr _expr; Expr _expr;
}; };
template<typename Expr>
struct value_type_of<trim_t<Expr>> : public value_type_of<Expr> {};
template<typename Expr>
struct nodes_of<trim_t<Expr>>
{
using type = detail::type_vector<Expr>;
};
template <typename Context, typename Expr> template <typename Context, typename Expr>
Context& serialize(Context& context, const trim_t<Expr>& t) Context& serialize(Context& context, const trim_t<Expr>& t)
{ {

View File

@ -28,14 +28,13 @@
#include <utility> #include <utility>
#include <sqlpp11/table.h> #include <sqlpp11/enable_join.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
template <typename AliasProvider> template <typename AliasProvider>
struct verbatim_table_alias_t struct verbatim_table_alias_t : public enable_join<verbatim_table_alias_t<AliasProvider>>
{ {
verbatim_table_alias_t(std::string representation) : _representation(std::move(representation)) verbatim_table_alias_t(std::string representation) : _representation(std::move(representation))
{ {
@ -47,43 +46,6 @@ namespace sqlpp
verbatim_table_alias_t& operator=(verbatim_table_alias_t&& rhs) = default; verbatim_table_alias_t& operator=(verbatim_table_alias_t&& rhs) = default;
~verbatim_table_alias_t() = default; ~verbatim_table_alias_t() = default;
#warning: We should have enable_join CRTP
template <typename T>
auto join(T t) const -> decltype(::sqlpp::join(*this, t))
{
return ::sqlpp::join(*this, t);
}
template <typename T>
auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t))
{
return ::sqlpp::inner_join(*this, t);
}
template <typename T>
auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t))
{
return ::sqlpp::left_outer_join(*this, t);
}
template <typename T>
auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t))
{
return ::sqlpp::right_outer_join(*this, t);
}
template <typename T>
auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t))
{
return ::sqlpp::outer_join(*this, t);
}
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t))
{
return ::sqlpp::cross_join(*this, t);
}
std::string _representation; std::string _representation;
}; };
@ -100,7 +62,7 @@ namespace sqlpp
return context; return context;
} }
struct verbatim_table_t struct verbatim_table_t: public enable_join<verbatim_table_t>
{ {
verbatim_table_t(std::string representation) : _representation(std::move(representation)) verbatim_table_t(std::string representation) : _representation(std::move(representation))
{ {
@ -118,43 +80,6 @@ namespace sqlpp
return {_representation}; return {_representation};
} }
#warning: We should have enable_join CRTP
template <typename T>
auto join(T t) const -> decltype(::sqlpp::join(*this, t))
{
return ::sqlpp::join(*this, t);
}
template <typename T>
auto inner_join(T t) const -> decltype(::sqlpp::inner_join(*this, t))
{
return ::sqlpp::inner_join(*this, t);
}
template <typename T>
auto left_outer_join(T t) const -> decltype(::sqlpp::left_outer_join(*this, t))
{
return ::sqlpp::left_outer_join(*this, t);
}
template <typename T>
auto right_outer_join(T t) const -> decltype(::sqlpp::right_outer_join(*this, t))
{
return ::sqlpp::right_outer_join(*this, t);
}
template <typename T>
auto outer_join(T t) const -> decltype(::sqlpp::outer_join(*this, t))
{
return ::sqlpp::outer_join(*this, t);
}
template <typename T>
auto cross_join(T t) const -> decltype(::sqlpp::cross_join(*this, t))
{
return ::sqlpp::cross_join(*this, t);
}
std::string _representation; std::string _representation;
}; };

View File

@ -52,7 +52,6 @@ namespace sqlpp
struct where_t struct where_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<Expression>;
using _data_t = where_data_t<Expression>; using _data_t = where_data_t<Expression>;
@ -73,6 +72,12 @@ namespace sqlpp
}; };
}; };
template <typename Expression>
struct nodes_of<where_t<Expression>>
{
using type = detail::type_vector<Expression>;
};
template <> template <>
struct where_data_t<unconditional_t> struct where_data_t<unconditional_t>
{ {
@ -83,7 +88,6 @@ namespace sqlpp
struct where_t<unconditional_t> struct where_t<unconditional_t>
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
using _data_t = where_data_t<unconditional_t>; using _data_t = where_data_t<unconditional_t>;
@ -138,7 +142,6 @@ namespace sqlpp
struct no_where_t struct no_where_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
using _data_t = no_data_t; using _data_t = no_data_t;

View File

@ -691,7 +691,7 @@ def createHeader():
% (sqlTableName, sqlColumnName) % (sqlTableName, sqlColumnName)
) )
DataTypeError = True DataTypeError = True
if columnType == "integer" and column.isUnsigned: if columnType == "integral" and column.isUnsigned:
columnType = "unsigned_" + columnType columnType = "unsigned_" + columnType
if columnType == "time_point" and not noTimestampWarning: if columnType == "time_point" and not noTimestampWarning:
print( print(

View File

@ -34,15 +34,10 @@ function(test_compile name)
endif() endif()
endfunction() endfunction()
test_compile(any) add_subdirectory(operator)
test_compile(aggregate_functions) test_compile(aggregate_functions)
test_compile(arithmetic_expression)
test_compile(assign_expression)
test_compile(case_when) test_compile(case_when)
test_compile(comparison_expression)
test_compile(dynamic) test_compile(dynamic)
test_compile(in_expression)
test_compile(logical_expression)
test_compile(result_row) test_compile(result_row)
test_compile(select_as) test_compile(select_as)
test_compile(value) test_compile(value)

View File

@ -41,8 +41,8 @@ void test_case_when(Value v)
using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>; using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>;
// Selectable values. // Selectable values.
auto v_not_null = sqlpp::value(v).as(r_not_null); auto v_not_null = sqlpp::value(v);
const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
// No value types for incomplete clauses // No value types for incomplete clauses
static_assert(is_same_type<decltype(sqlpp::case_when(true)), sqlpp::no_value_t>::value, ""); static_assert(is_same_type<decltype(sqlpp::case_when(true)), sqlpp::no_value_t>::value, "");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -36,7 +36,7 @@ SQLPP_ALIAS_PROVIDER(r_not_null);
SQLPP_ALIAS_PROVIDER(r_maybe_null); SQLPP_ALIAS_PROVIDER(r_maybe_null);
template <typename T, typename ValueType> template <typename T, typename ValueType>
using is_value_type = std::is_same<sqlpp::value_type_of_t<T>, ValueType>; using is_select_column_value_type = std::is_same<sqlpp::select_column_value_type_of_t<T>, ValueType>;
template<typename Value> template<typename Value>
void test_dynamic(Value v) void test_dynamic(Value v)
@ -46,8 +46,8 @@ void test_dynamic(Value v)
auto v_not_null= dynamic(true, sqlpp::value(v)); auto v_not_null= dynamic(true, sqlpp::value(v));
auto v_maybe_null= dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))); auto v_maybe_null= dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)));
auto v_not_null_alias = dynamic(true, sqlpp::value(v).as(r_not_null)); auto v_not_null_alias = dynamic(true, sqlpp::value(v)).as(r_not_null);
auto v_maybe_null_alias = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null)); auto v_maybe_null_alias = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))).as(r_maybe_null);
static_assert(not sqlpp::has_value_type<decltype(v_not_null)>::value, ""); static_assert(not sqlpp::has_value_type<decltype(v_not_null)>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null)>::value, ""); static_assert(not sqlpp::has_value_type<decltype(v_maybe_null)>::value, "");
@ -59,10 +59,15 @@ void test_dynamic(Value v)
static_assert(sqlpp::has_name<decltype(v_not_null_alias)>::value, ""); static_assert(sqlpp::has_name<decltype(v_not_null_alias)>::value, "");
static_assert(sqlpp::has_name<decltype(v_maybe_null_alias)>::value, ""); static_assert(sqlpp::has_name<decltype(v_maybe_null_alias)>::value, "");
static_assert(is_value_type<sqlpp::remove_dynamic_t<decltype(v_not_null)>, ValueType>::value, ""); static_assert(is_select_column_value_type<decltype(v_not_null), OptValueType>::value, "");
static_assert(is_value_type<sqlpp::remove_dynamic_t<decltype(v_maybe_null)>, OptValueType>::value, ""); static_assert(is_select_column_value_type<decltype(v_maybe_null), OptValueType>::value, "");
static_assert(is_value_type<sqlpp::remove_dynamic_t<decltype(v_not_null_alias)>, ValueType>::value, ""); static_assert(is_select_column_value_type<decltype(v_not_null_alias), OptValueType>::value, "");
static_assert(is_value_type<sqlpp::remove_dynamic_t<decltype(v_maybe_null_alias)>, OptValueType>::value, ""); static_assert(is_select_column_value_type<decltype(v_maybe_null_alias), OptValueType>::value, "");
static_assert(not sqlpp::select_column_has_name<decltype(v_not_null)>::value, "");
static_assert(not sqlpp::select_column_has_name<decltype(v_maybe_null)>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_not_null_alias)>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_maybe_null_alias)>::value, "");
#warning: test can be aliased #warning: test can be aliased
#warning: test has comparison operators #warning: test has comparison operators

View File

@ -0,0 +1,44 @@
# Copyright (c) 2024, Roland Bock
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function(test_compile name)
set(target sqlpp11_${name})
add_executable(${target} ${name}.cpp)
target_link_libraries(${target} PRIVATE sqlpp11::sqlpp11 sqlpp11_testing)
# conditionally bump to a higher C++ standard to test compatibility
if (SQLPP11_TESTS_CXX_STD)
set_property(TARGET sqlpp11_${name} PROPERTY CXX_STANDARD ${SQLPP11_TESTS_CXX_STD})
set_property(TARGET sqlpp11_${name} PROPERTY CXX_STANDARD_REQUIRED yes)
set_property(TARGET sqlpp11_${name} PROPERTY CXX_EXTENSIONS no)
endif()
endfunction()
test_compile(any)
test_compile(arithmetic_expression)
test_compile(as_expression)
test_compile(assign_expression)
test_compile(comparison_expression)
test_compile(in_expression)
test_compile(logical_expression)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -35,13 +35,12 @@ void test_any(Value v)
using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>; using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>;
// Selectable values. // Selectable values.
auto v_not_null = sqlpp::value(v).as(r_not_null); const auto v_not_null = sqlpp::value(v).as(r_not_null);
const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null);
// ANY expression are not to be in most expressions and therefore have no value defined. // ANY expression are not to be in most expressions and therefore have no value defined.
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(any(select(v_not_null)))>, sqlpp::no_value_t>::value, ""); static_assert(not sqlpp::has_value_type<decltype(any(select(v_not_null)))>::value, "");
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(any(select(v_maybe_null)))>, sqlpp::no_value_t>::value, static_assert(not sqlpp::has_value_type<decltype(any(select(v_maybe_null)))>::value, "");
"");
// ANY expression can be used in basic comparison expressions, which use remove_any_t to look inside. // ANY expression can be used in basic comparison expressions, which use remove_any_t to look inside.
static_assert( static_assert(
@ -51,9 +50,17 @@ void test_any(Value v)
OptValueType>::value, OptValueType>::value,
""); "");
#warning: test can be aliased // ANY expressions do not have `as` member function.
#warning: test has comparison operators static_assert(not sqlpp::has_enabled_as<decltype(any(select(v_not_null)))>::value, "");
#warning: test nodes
// ANY expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(any(select(v_not_null)))>::value, "");
// ANY expressions have the SELECT as node.
using S = decltype(select(v_not_null));
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(any(select(v_not_null)))>, sqlpp::detail::type_vector<S>>::value, "");
#warning: Note that a sub select may require tables from the enclosing select. This is currently not correctly implemented. We need to test that.
} }
int main() int main()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -80,9 +80,18 @@ void test_arithmetic_expressions(Value v)
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-value)>, ValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-value)>, ValueType>(), "");
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(-opt_value)>, OptValueType>(), "");
#warning: test can be aliased // Arithmetic expressions enable the `as` member function.
#warning: test has comparison operators static_assert(sqlpp::has_enabled_as<decltype(value + opt_value)>::value, "");
#warning: test nodes static_assert(sqlpp::has_enabled_as<decltype(-opt_value)>::value, "");
// Arithmetic expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(-opt_value)>::value, "");
// Arithmetic expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type;
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value + opt_value)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(-opt_value)>, sqlpp::detail::type_vector<sqlpp::noop, R>>::value, "");
} }
template<typename Value> template<typename Value>
@ -105,6 +114,17 @@ void test_modulus_expressions(Value v)
// Modulus combining optional with optional values // Modulus combining optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % opt_value)>, OptValueType>(), "");
// Modulus expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value % opt_value)>::value, "");
// Modulus expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(value % opt_value)>::value, "");
// Modulus expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type;
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value % opt_value)>, sqlpp::detail::type_vector<L, R>>::value, "");
} }
template<typename Value> template<typename Value>
@ -127,6 +147,17 @@ void test_concatenation_expressions(Value v)
// Concatenating optional with optional values // Concatenating optional with optional values
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + opt_value)>, OptValueType>(), ""); static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + opt_value)>, OptValueType>(), "");
// Modulus expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value + opt_value)>::value, "");
// Modulus expressions enable comparison member functions.
static_assert(sqlpp::has_enabled_comparison<decltype(value + opt_value)>::value, "");
// Modulus expressions have their arguments as nodes
using L = typename std::decay<decltype(value)>::type;
using R = typename std::decay<decltype(opt_value)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(value + opt_value)>, sqlpp::detail::type_vector<L, R>>::value, "");
} }
int main() int main()

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MockDb.h"
#include "Sample.h"
#include <sqlpp11/sqlpp11.h>
SQLPP_ALIAS_PROVIDER(r_not_null);
SQLPP_ALIAS_PROVIDER(r_maybe_null);
SQLPP_ALIAS_PROVIDER(cheese);
template <typename T, typename ValueType>
using is_select_column_value_type = std::is_same<sqlpp::select_column_value_type_of_t<T>, ValueType>;
template<typename Value>
void test_as_expression(Value v)
{
using ValueType = sqlpp::value_type_of_t<Value>;
using OptValueType = sqlpp::compat::optional<ValueType>;
auto v_not_null= sqlpp::value(v);
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
auto v_dynamic_not_null = dynamic(true, sqlpp::value(v));
auto v_dynamic_maybe_null = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)));
static_assert(not sqlpp::has_value_type<decltype(v_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_dynamic_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_value_type<decltype(v_dynamic_maybe_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_maybe_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_dynamic_not_null.as(cheese))>::value, "");
static_assert(not sqlpp::has_name<decltype(v_dynamic_maybe_null.as(cheese))>::value, "");
static_assert(is_select_column_value_type<decltype(v_not_null.as(cheese)), ValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_maybe_null.as(cheese)), OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_dynamic_not_null.as(cheese)), OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_dynamic_maybe_null.as(cheese)), OptValueType>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_not_null.as(cheese))>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_maybe_null.as(cheese))>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_dynamic_not_null.as(cheese))>::value, "");
static_assert(sqlpp::select_column_has_name<decltype(v_dynamic_maybe_null.as(cheese))>::value, "");
// AS expressions have do not enable the `as` member function.
static_assert(not sqlpp::has_enabled_as<decltype(v_not_null.as(cheese))>::value, "");
// AS expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null.as(cheese))>::value, "");
// AS expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null.as(cheese))>, sqlpp::detail::type_vector<L>>::value, "");
}
int main()
{
// boolean
test_as_expression(bool{true});
// integral
test_as_expression(int8_t{7});
test_as_expression(int16_t{7});
test_as_expression(int32_t{7});
test_as_expression(int64_t{7});
// unsigned integral
test_as_expression(uint8_t{7});
test_as_expression(uint16_t{7});
test_as_expression(uint32_t{7});
test_as_expression(uint64_t{7});
// floating point
test_as_expression(float{7.7});
test_as_expression(double{7.7});
// text
test_as_expression('7');
test_as_expression("seven");
test_as_expression(std::string("seven"));
test_as_expression(sqlpp::compat::string_view("seven"));
// blob
test_as_expression(std::vector<uint8_t>{});
// date
test_as_expression(::sqlpp::chrono::day_point{});
// timestamp
test_as_expression(::sqlpp::chrono::microsecond_point{});
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
test_as_expression(minute_point{});
// time_of_day
test_as_expression(std::chrono::microseconds{});
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -68,8 +68,16 @@ void test_assign_expression(const Column& col, const Value& v)
sqlpp::detail::type_vector<Column, OptValueType>>::value, sqlpp::detail::type_vector<Column, OptValueType>>::value,
""); "");
#warning: test can be aliased // Assign expressions do not have the `as` member function.
#warning: test has comparison operators static_assert(not sqlpp::has_enabled_as<decltype(col = v_not_null)>::value, "");
// Assign expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(col = v_not_null)>::value, "");
// Assign expressions have their arguments as nodes.
using L = typename std::decay<decltype(col)>::type;
using R = typename std::decay<decltype(v_not_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = v_not_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
} }
#warning: test that non-nullable columns cannot be assigned optional values #warning: test that non-nullable columns cannot be assigned optional values

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -44,7 +44,7 @@ void test_comparison_expression(Value v)
auto v_not_null = sqlpp::value(v); auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)); auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
#warning : Should also implement like, is_null, is_distinct_from as member functions. #warning : Should also implement between as member functions?
// Compare non-nullable with non-nullable. // Compare non-nullable with non-nullable.
static_assert(is_bool<decltype(v_not_null < v_not_null)>::value, ""); static_assert(is_bool<decltype(v_not_null < v_not_null)>::value, "");
@ -96,9 +96,18 @@ void test_comparison_expression(Value v)
static_assert(is_bool<decltype(is_not_null(v_maybe_null))>::value, ""); static_assert(is_bool<decltype(is_not_null(v_maybe_null))>::value, "");
static_assert(is_bool<decltype(is_not_null(v_not_null))>::value, ""); static_assert(is_bool<decltype(is_not_null(v_not_null))>::value, "");
#warning: test can be aliased // Comparison expressions have the `as` member function.
#warning: test has comparison operators static_assert(sqlpp::has_enabled_as<decltype(v_not_null == v_maybe_null)>::value, "");
#warning: test nodes static_assert(sqlpp::has_enabled_as<decltype(is_null(v_not_null))>::value, "");
// Comparison expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null == v_maybe_null)>::value, "");
// Comparison expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null == v_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(is_null(v_not_null))>, sqlpp::detail::type_vector<L, sqlpp::compat::nullopt_t>>::value, "");
} }
template<typename Value> template<typename Value>
@ -118,10 +127,6 @@ void test_like(Value v)
// Compare nullable with nullable. // Compare nullable with nullable.
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_maybe_null))>::value, ""); static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_maybe_null))>::value, "");
#warning: test can be aliased
#warning: test has comparison operators
#warning: test nodes
} }
int main() int main()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -23,14 +23,10 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "MockDb.h"
#include "Sample.h"
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
{ {
auto db = MockDb{};
template <typename T> template <typename T>
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>; using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
@ -66,16 +62,26 @@ void test_in_expression(Value v)
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, ""); static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
static_assert(is_maybe_bool<decltype(in(v_maybe_null, select(v_maybe_null.as(sqlpp::alias::a))))>::value, ""); static_assert(is_maybe_bool<decltype(in(v_maybe_null, select(v_maybe_null.as(sqlpp::alias::a))))>::value, "");
#warning: test can be aliased // IN expressions have the `as` member function.
#warning: test has comparison operators static_assert(sqlpp::has_enabled_as<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
#warning: test nodes
// IN expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
// IN expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_maybe_null)>::type;
using R1= Value;
using R2= OptValue;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(in(v_maybe_null, std::vector<Value>{}))>, sqlpp::detail::type_vector<L, R1>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(in(v_maybe_null, v, sqlpp::compat::make_optional(v)))>, sqlpp::detail::type_vector<L, R1, R2>>::value, "");
} }
int main() int main()
{ {
// boolean // boolean
test_in_expression(bool{true}); test_in_expression(bool{true});
#warning reactivate
#if 0
// integral // integral
test_in_expression(int8_t{7}); test_in_expression(int8_t{7});
test_in_expression(int16_t{7}); test_in_expression(int16_t{7});
@ -111,5 +117,6 @@ int main()
// time_of_day // time_of_day
test_in_expression(std::chrono::microseconds{}); test_in_expression(std::chrono::microseconds{});
#endif
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2016, Roland Bock * Copyright (c) 2024, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -40,28 +40,28 @@ void test_logical_expression(Value v)
auto v_not_null= sqlpp::value(v); auto v_not_null= sqlpp::value(v);
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v)); auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
// Compare non-nullable with non-nullable. // Combine non-nullable with non-nullable.
static_assert(is_bool<decltype(v_not_null and v_not_null)>::value, ""); static_assert(is_bool<decltype(v_not_null and v_not_null)>::value, "");
static_assert(is_bool<decltype(v_not_null or v_not_null)>::value, ""); static_assert(is_bool<decltype(v_not_null or v_not_null)>::value, "");
static_assert(is_bool<decltype(v_not_null and dynamic(true, v_not_null))>::value, ""); static_assert(is_bool<decltype(v_not_null and dynamic(true, v_not_null))>::value, "");
static_assert(is_bool<decltype(v_not_null or dynamic(true, v_not_null))>::value, ""); static_assert(is_bool<decltype(v_not_null or dynamic(true, v_not_null))>::value, "");
// Compare nullable with non-nullable. // Combine nullable with non-nullable.
static_assert(is_maybe_bool<decltype(v_maybe_null and v_not_null)>::value, ""); static_assert(is_maybe_bool<decltype(v_maybe_null and v_not_null)>::value, "");
static_assert(is_maybe_bool<decltype(v_maybe_null or v_not_null)>::value, ""); static_assert(is_maybe_bool<decltype(v_maybe_null or v_not_null)>::value, "");
static_assert(is_maybe_bool<decltype(v_maybe_null and dynamic(true, v_not_null))>::value, ""); static_assert(is_maybe_bool<decltype(v_maybe_null and dynamic(true, v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(v_maybe_null or dynamic(true, v_not_null))>::value, ""); static_assert(is_maybe_bool<decltype(v_maybe_null or dynamic(true, v_not_null))>::value, "");
// Compare non-nullable with nullable. // Combine non-nullable with nullable.
static_assert(is_maybe_bool<decltype(v_not_null and v_maybe_null)>::value, ""); static_assert(is_maybe_bool<decltype(v_not_null and v_maybe_null)>::value, "");
static_assert(is_maybe_bool<decltype(v_not_null or v_maybe_null)>::value, ""); static_assert(is_maybe_bool<decltype(v_not_null or v_maybe_null)>::value, "");
static_assert(is_maybe_bool<decltype(v_not_null and dynamic(true, v_maybe_null))>::value, ""); static_assert(is_maybe_bool<decltype(v_not_null and dynamic(true, v_maybe_null))>::value, "");
static_assert(is_maybe_bool<decltype(v_not_null or dynamic(true, v_maybe_null))>::value, ""); static_assert(is_maybe_bool<decltype(v_not_null or dynamic(true, v_maybe_null))>::value, "");
// Compare nullable with nullable. // Combine nullable with nullable.
static_assert(is_maybe_bool<decltype(v_maybe_null and v_maybe_null)>::value, ""); static_assert(is_maybe_bool<decltype(v_maybe_null and v_maybe_null)>::value, "");
static_assert(is_maybe_bool<decltype(v_maybe_null or v_maybe_null)>::value, ""); static_assert(is_maybe_bool<decltype(v_maybe_null or v_maybe_null)>::value, "");
@ -72,9 +72,19 @@ void test_logical_expression(Value v)
static_assert(is_bool<decltype(not(v_not_null))>::value, ""); static_assert(is_bool<decltype(not(v_not_null))>::value, "");
static_assert(is_maybe_bool<decltype(not(v_maybe_null))>::value, ""); static_assert(is_maybe_bool<decltype(not(v_maybe_null))>::value, "");
#warning: test can be aliased // Logical expressions have the `as` member function.
#warning: test has comparison operators static_assert(sqlpp::has_enabled_as<decltype(v_not_null and v_maybe_null)>::value, "");
#warning: test nodes static_assert(sqlpp::has_enabled_as<decltype(v_maybe_null or dynamic(true, v_maybe_null))>::value, "");
// Logical expressions do not enable comparison member functions.
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null == v_maybe_null)>::value, "");
static_assert(not sqlpp::has_enabled_comparison<decltype(v_maybe_null or dynamic(true, v_maybe_null))>::value, "");
// Logical expressions have their arguments as nodes.
using L = typename std::decay<decltype(v_not_null)>::type;
using R = typename std::decay<decltype(v_maybe_null)>::type;
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null and v_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(v_not_null and dynamic(true, v_maybe_null))>, sqlpp::detail::type_vector<L, sqlpp::dynamic_t<R>>>::value, "");
} }
int main() int main()

View File

@ -57,8 +57,8 @@ void test_result_row(Value v)
const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null); const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null);
// Optional selectable values. // Optional selectable values.
const auto v_opt_not_null = dynamic(true, sqlpp::value(v).as(r_opt_not_null)); const auto v_opt_not_null = dynamic(true, sqlpp::value(v)).as(r_opt_not_null);
const auto v_opt_maybe_null = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)).as(r_opt_maybe_null)); const auto v_opt_maybe_null = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v))).as(r_opt_maybe_null);
for (const auto& row : db(select(v_not_null, v_maybe_null, v_opt_not_null, v_opt_maybe_null))) for (const auto& row : db(select(v_not_null, v_maybe_null, v_opt_not_null, v_opt_maybe_null)))
{ {
@ -126,7 +126,6 @@ int main()
// as expressions retain the value type of the real thing // as expressions retain the value type of the real thing
static_assert(sqlpp::has_name<decltype(bar.intN)>::value, ""); static_assert(sqlpp::has_name<decltype(bar.intN)>::value, "");
sqlpp::as(bar.intN, bar.textN); sqlpp::as(bar.intN, bar.textN);
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(bar.intN.as(bar.textN))>, sqlpp::value_type_of_t<decltype(bar.intN)>>::value, "");
#if 0 #if 0

View File

@ -32,6 +32,9 @@ namespace
template <typename T, typename V> template <typename T, typename V>
using is_same_type = std::is_same<sqlpp::value_type_of_t<T>, V>; using is_same_type = std::is_same<sqlpp::value_type_of_t<T>, V>;
template <typename T, typename V>
using is_select_column_same_type = std::is_same<sqlpp::select_column_value_type_of_t<T>, V>;
SQLPP_ALIAS_PROVIDER(always); SQLPP_ALIAS_PROVIDER(always);
SQLPP_ALIAS_PROVIDER(sometimes); SQLPP_ALIAS_PROVIDER(sometimes);
SQLPP_ALIAS_PROVIDER(column) SQLPP_ALIAS_PROVIDER(column)
@ -76,8 +79,8 @@ void test_select_as(Value v)
static_assert(sqlpp::has_name<decltype(select(v_not_null).as(column).always.as(foo))>::value, ""); static_assert(sqlpp::has_name<decltype(select(v_not_null).as(column).always.as(foo))>::value, "");
static_assert(sqlpp::has_name<decltype(select(v_maybe_null).as(column).sometimes.as(foo))>::value, ""); static_assert(sqlpp::has_name<decltype(select(v_maybe_null).as(column).sometimes.as(foo))>::value, "");
static_assert(is_same_type<decltype(select(v_not_null).as(column).always.as(foo)), ValueType>(), ""); static_assert(is_select_column_same_type<decltype(select(v_not_null).as(column).always.as(foo)), ValueType>(), "");
static_assert(is_same_type<decltype(select(v_maybe_null).as(column).sometimes.as(foo)), OptValueType>(), ""); static_assert(is_select_column_same_type<decltype(select(v_maybe_null).as(column).sometimes.as(foo)), OptValueType>(), "");
// MULTIPLE VALUES // MULTIPLE VALUES
@ -102,8 +105,8 @@ void test_select_as(Value v)
static_assert(sqlpp::has_name<decltype(select(v_not_null, v_maybe_null).as(table).always.as(foo))>::value, ""); static_assert(sqlpp::has_name<decltype(select(v_not_null, v_maybe_null).as(table).always.as(foo))>::value, "");
static_assert(sqlpp::has_name<decltype(select(v_not_null, v_maybe_null).as(table).sometimes.as(foo))>::value, ""); static_assert(sqlpp::has_name<decltype(select(v_not_null, v_maybe_null).as(table).sometimes.as(foo))>::value, "");
static_assert(is_same_type<decltype(select(v_not_null, v_maybe_null).as(table).always.as(foo)), ValueType>(), ""); static_assert(is_select_column_same_type<decltype(select(v_not_null, v_maybe_null).as(table).always.as(foo)), ValueType>(), "");
static_assert(is_same_type<decltype(select(v_not_null, v_maybe_null).as(table).sometimes.as(foo)), OptValueType>(), ""); static_assert(is_select_column_same_type<decltype(select(v_not_null, v_maybe_null).as(table).sometimes.as(foo)), OptValueType>(), "");
#warning: test can be aliased #warning: test can be aliased
@ -117,6 +120,8 @@ int main()
// boolean // boolean
test_select_as(bool{true}); test_select_as(bool{true});
#warning: reactivate
#if 0
// integral // integral
test_select_as(int8_t{7}); test_select_as(int8_t{7});
test_select_as(int16_t{7}); test_select_as(int16_t{7});
@ -152,5 +157,6 @@ int main()
// time_of_day // time_of_day
test_select_as(std::chrono::microseconds{}); test_select_as(std::chrono::microseconds{});
#endif
} }

View File

@ -23,15 +23,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "MockDb.h"
#include "Sample.h"
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace
{
auto db = MockDb{};
}
SQLPP_ALIAS_PROVIDER(r_not_null); SQLPP_ALIAS_PROVIDER(r_not_null);
SQLPP_ALIAS_PROVIDER(r_maybe_null); SQLPP_ALIAS_PROVIDER(r_maybe_null);
SQLPP_ALIAS_PROVIDER(r_opt_not_null); SQLPP_ALIAS_PROVIDER(r_opt_not_null);
@ -48,18 +41,12 @@ void test_value(Value v)
auto v_not_null= sqlpp::value(v); auto v_not_null= sqlpp::value(v);
auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v)); auto v_maybe_null= sqlpp::value(sqlpp::compat::make_optional(v));
auto v_not_null_alias = sqlpp::value(v).as(r_not_null);
auto v_maybe_null_alias = sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_null);
static_assert(is_value_type<decltype(v_not_null), ValueType>::value, ""); static_assert(is_value_type<decltype(v_not_null), ValueType>::value, "");
static_assert(is_value_type<decltype(v_maybe_null), OptValueType>::value, ""); static_assert(is_value_type<decltype(v_maybe_null), OptValueType>::value, "");
static_assert(is_value_type<decltype(v_not_null_alias), ValueType>::value, "");
static_assert(is_value_type<decltype(v_maybe_null_alias), OptValueType>::value, "");
static_assert(not sqlpp::can_be_null<decltype(v_not_null)>::value, ""); static_assert(not sqlpp::can_be_null<decltype(v_not_null)>::value, "");
static_assert(sqlpp::can_be_null<decltype(v_maybe_null)>::value, ""); static_assert(sqlpp::can_be_null<decltype(v_maybe_null)>::value, "");
static_assert(not sqlpp::can_be_null<decltype(v_not_null_alias)>::value, "");
static_assert(sqlpp::can_be_null<decltype(v_maybe_null_alias)>::value, "");
#warning: test can be aliased #warning: test can be aliased
#warning: test has comparison operators #warning: test has comparison operators

View File

@ -93,7 +93,7 @@ namespace test
const T& operator()() const { return uIntN; } const T& operator()() const { return uIntN; }
}; };
}; };
using value_type = ::sqlpp::compat::optional<::sqlpp::integral>; using value_type = ::sqlpp::compat::optional<::sqlpp::unsigned_integral>;
using has_default = std::true_type; using has_default = std::true_type;
}; };
struct BlobN : public ::sqlpp::name_tag_base struct BlobN : public ::sqlpp::name_tag_base

View File

@ -52,7 +52,11 @@ void print_row(Row const& row)
std::cout << a << ", " << b << std::endl; std::cout << a << ", " << b << std::endl;
} }
SQLPP_ALIAS_PROVIDER(cheese) SQLPP_ALIAS_PROVIDER(param2);
SQLPP_ALIAS_PROVIDER(cheese);
SQLPP_ALIAS_PROVIDER(average);
SQLPP_ALIAS_PROVIDER(N);
int Select(int, char*[]) int Select(int, char*[])
{ {
@ -63,11 +67,11 @@ int Select(int, char*[])
const auto t = test::TabBar{}; const auto t = test::TabBar{};
const auto tab_a = f.as(sqlpp::alias::a); const auto tab_a = f.as(sqlpp::alias::a);
select(count(t.id)); select(count(t.id).as(N));
select(sqlpp::count(1)); select(sqlpp::count(1).as(N));
select(count(sqlpp::value(1))); select(count(sqlpp::value(1)).as(N));
std::cerr << serialize(select(sqlpp::value(false).as(sqlpp::alias::a)), printer).str() << std::endl; std::cerr << serialize(printer, select(sqlpp::value(false).as(sqlpp::alias::a))).str() << std::endl;
for (const auto& row : db(select(sqlpp::value(false).as(sqlpp::alias::a)))) for (const auto& row : db(select(sqlpp::value(false).as(sqlpp::alias::a))))
{ {
std::cout << row.a << std::endl; std::cout << row.a << std::endl;
@ -109,14 +113,14 @@ int Select(int, char*[])
std::cout << row.id << std::endl; std::cout << row.id << std::endl;
} }
for (const auto& row : db(select(sqlpp::count(1), avg(t.id)).from(t).unconditionally())) for (const auto& row : db(select(sqlpp::count(1).as(N), avg(t.id).as(average)).from(t).unconditionally()))
{ {
std::cout << row.count << std::endl; std::cout << row.N << std::endl;
} }
for (const auto& row : db(select(count(t.id), avg(t.id)).from(t).where(t.id == 0))) for (const auto& row : db(select(count(t.id).as(N), avg(t.id).as(average)).from(t).where(t.id == 0)))
{ {
std::cout << row.count << std::endl; std::cout << row.N << std::endl;
} }
auto stat = sqlpp::select() auto stat = sqlpp::select()
@ -130,7 +134,7 @@ int Select(int, char*[])
.offset(19u) .offset(19u)
.limit(7u); .limit(7u);
printer.reset(); printer.reset();
std::cerr << serialize(stat, printer).str() << std::endl; std::cerr << serialize(printer, stat).str() << std::endl;
auto s = sqlpp::select() auto s = sqlpp::select()
.columns(t.id) .columns(t.id)
@ -150,12 +154,12 @@ int Select(int, char*[])
} }
printer.reset(); printer.reset();
std::cerr << serialize(s, printer).str() << std::endl; std::cerr << serialize(printer, s).str() << std::endl;
select(sqlpp::value(7).as(t.id)); select(sqlpp::value(7).as(t.id));
for (const auto& row : for (const auto& row :
db(select(sqlpp::case_when(true).then(t.textN).else_(sqlpp::null).as(t.textN)).from(t).unconditionally())) db(select(sqlpp::case_when(true).then(t.textN).else_(sqlpp::compat::nullopt).as(t.textN)).from(t).unconditionally()))
{ {
std::cerr << row.textN << std::endl; std::cerr << row.textN << std::endl;
} }
@ -182,16 +186,16 @@ int Select(int, char*[])
} }
for (const auto& row : for (const auto& row :
db(select(f.doubleN, select(count(t.id)).from(t).unconditionally().as(cheese)).from(f).unconditionally())) db(select(f.doubleN, select(count(t.id).as(N)).from(t).unconditionally().as(cheese)).from(f).unconditionally()))
{ {
std::cout << row.doubleN << " " << row.cheese << std::endl; std::cout << row.doubleN << " " << row.cheese << std::endl;
} }
// checking #584 // checking #584
auto abs = db.prepare(select(t.alpha).from(t).where(sqlpp::parameterized_verbatim<sqlpp::unsigned_integral>( auto abs = db.prepare(select(t.id).from(t).where(sqlpp::parameterized_verbatim<sqlpp::unsigned_integral>(
"ABS(field1 -", sqlpp::parameter(t.alpha), ")") <= "ABS(field1 -", sqlpp::parameter(t.id), ")") <=
sqlpp::parameter(sqlpp::unsigned_integral(), param2))); sqlpp::parameter(sqlpp::unsigned_integral(), param2)));
abs.params.alpha = 7; abs.params.id = 7;
abs.params.param2 = 7; abs.params.param2 = 7;
return 0; return 0;

View File

@ -25,7 +25,6 @@
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include "is_regular.h"
#include <iostream> #include <iostream>
#include <sqlpp11/alias_provider.h> #include <sqlpp11/alias_provider.h>
#include <sqlpp11/connection.h> #include <sqlpp11/connection.h>
@ -53,175 +52,85 @@ int SelectType(int, char*[])
// Test a table // Test a table
{ {
using T = typename std::decay<decltype(t)>::type; using T = typename std::decay<decltype(t)>::type;
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(not sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement"); static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement"); static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test an alias of table // Test an alias of table
{ {
using T = decltype(t.as(alias::a)); using T = decltype(t.as(alias::a));
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(not sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement"); static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement"); static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test an integral column of an alias of table // Test an integral column of an alias of table
{ {
using T = decltype(t.as(alias::a).id); using T = decltype(t.as(alias::a).id);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_integral_t<T>::value, "type requirement"); static_assert(sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement"); static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<T>::value, "type requirement");
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test an integral table column // Test an integral table column
{ {
using T = decltype(t.id); using T = decltype(t.id);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_integral_t<T>::value, "type requirement"); static_assert(sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_unsigned_integral_t<T>::value, "type requirement"); static_assert(not sqlpp::is_unsigned_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement"); static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<T>::value, "type requirement");
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test an unsigned integral table column // Test an unsigned integral table column
{ {
using T = decltype(f.uIntN); using T = decltype(f.uIntN);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement"); static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(sqlpp::is_unsigned_integral_t<T>::value, "type requirement"); static_assert(sqlpp::is_unsigned_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement"); static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
// subtraction on unsigned makes it signed
static_assert(sqlpp::is_integral_t<sqlpp::return_type_minus_t<T, T>>::value, "type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_unary_minus_t<T, T>>::value, "type requirement");
// any operation on float makes it float
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_minus_t<T, sqlpp::floating_point>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_plus_t<T, sqlpp::floating_point>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_multiplies_t<T, sqlpp::floating_point>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_divides_t<T, sqlpp::floating_point>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_minus_t<sqlpp::floating_point, T>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_plus_t<sqlpp::floating_point, T>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_multiplies_t<sqlpp::floating_point, T>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_divides_t<sqlpp::floating_point, T>>::value,
"type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_modulus_t<sqlpp::floating_point, T>>::value,
"type requirement");
// signed operation on unsigned makes it signed
static_assert(sqlpp::is_integral_t<sqlpp::return_type_minus_t<T, sqlpp::integral>>::value, "type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_plus_t<T, sqlpp::integral>>::value, "type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_multiplies_t<T, sqlpp::integral>>::value, "type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_divides_t<T, sqlpp::integral>>::value,
"type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_minus_t<sqlpp::integral, T>>::value, "type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_plus_t<sqlpp::integral, T>>::value, "type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_multiplies_t<sqlpp::integral, T>>::value, "type requirement");
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_divides_t<sqlpp::integral, T>>::value,
"type requirement");
static_assert(sqlpp::is_integral_t<sqlpp::return_type_modulus_t<sqlpp::integral, T>>::value, "type requirement");
} }
// Test a floating point table column // Test a floating point table column
{ {
using T = decltype(f.doubleN); using T = decltype(f.doubleN);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement"); static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(sqlpp::is_floating_point_t<T>::value, "type requirement"); static_assert(sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test a an alias of a numeric table column // Test a an alias of a numeric table column
{ {
using T = decltype(t.id.as(alias::a)); using T = decltype(t.id.as(alias::a));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// 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.id)); using T = decltype(select(t.id));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test a select of a single numeric table column // Test a select of a single numeric table column
@ -229,97 +138,55 @@ int SelectType(int, char*[])
using T = decltype(select(t.id).from(t)); using T = decltype(select(t.id).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>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test a select of an alias of a single numeric table column // Test a select of an alias of a single numeric table column
{ {
using T = decltype(select(t.id.as(alias::a)).from(t)); using T = decltype(select(t.id.as(alias::a)).from(t));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test an alias of a select of a single numeric table column // Test an alias of a select of a single numeric table column
{ {
using T = decltype(select(t.id).from(t).as(alias::b)); using T = decltype(select(t.id).from(t).as(alias::b));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "red to not be boolean");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(sqlpp::is_table<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::is_boolean_t<T>::value, "red to not be boolean");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test the column of an alias of a select of an alias of a single numeric table column // Test the column of an alias of a select of an alias of a single numeric table column
{ {
using T = decltype(select(t.id.as(alias::a)).from(t).as(alias::b)); using T = decltype(select(t.id.as(alias::a)).from(t).as(alias::b));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(sqlpp::is_table<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::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test the column of an alias of a select of a single numeric table column // Test the column of an alias of a select of a single numeric table column
{ {
using T = decltype(select(t.id).from(t).as(alias::b).id); using T = decltype(select(t.id).from(t).as(alias::b).id);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<T>::value, "type requirement");
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test an alias of a select of an alias of a single numeric table column // Test an alias of a select of an alias of a single numeric table column
{ {
using T = decltype(select(t.id.as(alias::a)).from(t).as(alias::b).a); using T = decltype(select(t.id.as(alias::a)).from(t).as(alias::b).a);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement"); static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement"); static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement"); static_assert(not sqlpp::is_table<T>::value, "type requirement");
static_assert(sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(sqlpp::must_not_update_t<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean_t<T>::value, "type requirement");
static_assert(not sqlpp::is_text_t<T>::value, "type requirement");
static_assert(not sqlpp::is_alias_t<T>::value, "type requirement");
static_assert(not sqlpp::is_table_t<T>::value, "type requirement");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test that all_of(tab) is expanded in select // Test that all_of(tab) is expanded in select
@ -362,17 +229,16 @@ int SelectType(int, char*[])
s.limit.set(30u); s.limit.set(30u);
s.limit.set(3u); s.limit.set(3u);
std::cerr << "------------------------\n"; std::cerr << "------------------------\n";
serialize(s, printer).str(); serialize(printer, s).str();
std::cerr << "------------------------\n"; std::cerr << "------------------------\n";
using T = decltype(s); using T = decltype(s);
static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }
// Test that select can be called with zero columns if it is used with dynamic columns. // Test that select can be called with zero columns if it is used with dynamic columns.
{ {
auto s = dynamic_select(db).dynamic_columns(); auto s = dynamic_select(db).dynamic_columns();
s.selected_columns.add(without_table_check(t.id)); s.selected_columns.add(without_table_check(t.id));
serialize(s, printer).str(); serialize(printer, s).str();
} }
{ {
@ -385,33 +251,24 @@ int SelectType(int, char*[])
// Test that verbatim_table compiles // Test that verbatim_table compiles
{ {
auto s = select(t.id).from(sqlpp::verbatim_table("my_unknown_table")); auto s = select(t.id).from(sqlpp::verbatim_table("my_unknown_table"));
serialize(s, printer).str(); serialize(printer, s).str();
} }
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::wrap_operand<int>::type; static_assert(sqlpp::is_numeric<decltype(t.id)>::value, "TabBar.id has to be a numeric");
static_assert(sqlpp::is_regular<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<T>::value, "T has to be an expression");
static_assert(sqlpp::is_numeric_t<T>::value, "T has to be numeric");
static_assert(sqlpp::is_numeric_t<decltype(t.id)>::value, "TabBar.id has to be a numeric");
((t.id + 7) + 4).asc(); ((t.id + 7) + 4).asc();
static_assert(sqlpp::is_boolean_t<decltype(t.boolNn != not(t.boolNn))>::value, static_assert(sqlpp::is_boolean<decltype(t.boolNn != not(t.boolNn))>::value,
"Comparison expression have to be boolean"); "Comparison expression have to be boolean");
!t.boolNn; !t.boolNn;
serialize(t.textN < "kaesekuchen", printer).str(); serialize(printer, t.textN < "kaesekuchen").str();
serialize(t.textN + "hallenhalma", printer).str(); serialize(printer, t.textN + "hallenhalma").str();
static_assert(sqlpp::must_not_insert_t<decltype(t.id)>::value, "id must not be inserted"); serialize(printer, t.id).str();
serialize(t.id, printer).str();
std::cerr << "\n" << sizeof(test::TabBar) << std::endl; std::cerr << "\n" << sizeof(test::TabBar) << std::endl;
static_assert(sqlpp::is_selectable_t<decltype(t.id)>::value, "id should be a named expression");
static_assert(sqlpp::is_selectable_t<decltype(t.id.as(alias::a))>::value,
"an alias of id should be a named expression");
static_assert(sqlpp::is_alias_t<decltype(t.id.as(alias::a))>::value, "an alias of id should be an alias");
auto l = t.as(alias::left); auto l = t.as(alias::left);
auto r = select(t.boolNn.as(alias::a)).from(t).where(t.boolNn == true).as(alias::right); auto r = select(t.boolNn.as(alias::a)).from(t).where(t.boolNn == true).as(alias::right);
static_assert(sqlpp::is_boolean_t<decltype(select(t.boolNn).from(t))>::value, "select(bool) has to be a bool"); static_assert(sqlpp::is_boolean<decltype(select(t.boolNn).from(t))>::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"); static_assert(sqlpp::is_boolean<decltype(select(r.a).from(r))>::value, "select(bool) has to be a bool");
auto s1 = sqlpp::select() auto s1 = sqlpp::select()
.flags(sqlpp::distinct, sqlpp::straight_join) .flags(sqlpp::distinct, sqlpp::straight_join)
.columns(l.boolNn, r.a) .columns(l.boolNn, r.a)