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/enable_as.h>
#include <sqlpp11/serialize.h>
namespace sqlpp
{
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>;
@ -50,13 +51,7 @@ namespace sqlpp
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
// used depending on the value of _condition.
template <typename Expr>
struct name_tag_of<dynamic_t<Expr>> : public name_tag_of<Expr>
{
};
// No value_type_of or name_tag_of defined for dynamic_t, to prevent its usage outside of select columns.
template <typename Expr>
struct nodes_of<dynamic_t<Expr>> : public nodes_of<Expr>

View File

@ -42,10 +42,14 @@ namespace sqlpp
public:
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);
}
};
#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

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

View File

@ -1,7 +1,7 @@
#pragma once
/*
* Copyright (c) 2013-2015, Roland Bock
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* 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.
*/
#include <sqlpp11/operator/as_expression.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/join.h>
namespace sqlpp
{
template <typename Expr>
struct alias_operators
template <typename Joinable>
struct enable_join
{
template <typename alias_provider>
as_expression<Expr, alias_provider> as(const alias_provider& /*unused*/) const
constexpr auto derived() const -> const Joinable&
{
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

View File

@ -29,7 +29,7 @@
#include <type_traits>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/dynamic.h>
#include <sqlpp11/select_column_traits.h>
namespace sqlpp
{
@ -76,24 +76,15 @@ namespace sqlpp
template <typename Select, typename NamedExpr>
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 =
detail::make_intersect_set_t<required_tables_of_t<NamedExpr>,
typename Select::_used_outer_tables>::size::value > 0;
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>;
};
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
template <typename Select, typename NamedExpr>

View File

@ -47,7 +47,6 @@ namespace sqlpp
struct from_t
{
using _traits = make_traits<no_value_t, tag::is_from>;
using _nodes = detail::type_vector<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(
assert_from_not_pre_join_t,
"from() argument is a pre join, please use an explicit on() condition or unconditionally()");
@ -94,7 +99,6 @@ namespace sqlpp
struct no_from_t
{
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
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,
"arguments for group_by() must be valid expressions");
SQLPP_PORTABLE_STATIC_ASSERT(assert_group_by_args_have_values_t,
"all arguments for group_by() must have values");
template <typename... Exprs>
struct check_group_by
{
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>
using check_group_by_t = typename check_group_by<Exprs...>::type;

View File

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

View File

@ -1,7 +1,7 @@
#pragma once
/*
Copyright (c) 2017, Roland Bock
Copyright (c) 2024, Roland Bock
All rights reserved.
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
{
#warning: need type tests
template <typename Expression, typename AliasProvider>
struct as_expression
{
@ -55,17 +56,7 @@ namespace sqlpp
Expression _expression;
};
template <typename Expression, typename AliasProvider>
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>;
};
// No value_type_of or name_tag_of defined for as_expression, to prevent its usage outside of select columns.
template <typename Expression, typename AliasProvider>
struct nodes_of<as_expression<Expression, AliasProvider>>
@ -73,11 +64,6 @@ namespace sqlpp
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>
Context& serialize(Context& context, const as_expression<Expression, AliasProvider>& t)
{
@ -97,4 +83,12 @@ namespace sqlpp
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

View File

@ -63,7 +63,10 @@ namespace sqlpp
};
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>
Context& serialize(Context& context, const parameterized_verbatim_t<ValueType, Expr>& t)

View File

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

View File

@ -27,12 +27,14 @@
*/
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/operator/as_expression.h>
#include <sqlpp11/dynamic.h>
#include <sqlpp11/field_spec.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/select_as.h>
#include <sqlpp11/select_column_traits.h>
#include <sqlpp11/table.h>
#include <tuple>
@ -84,7 +86,7 @@ namespace sqlpp
template <typename Select, typename Column>
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!
static constexpr bool _depends_on_outer_table =
@ -92,7 +94,7 @@ namespace sqlpp
0;
};
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(
assert_no_unknown_tables_in_selected_columns_t,
@ -108,7 +110,6 @@ namespace sqlpp
struct select_column_list_t
{
using _traits = typename detail::select_traits<Columns...>::_traits;
using _nodes = detail::type_vector<Columns...>;
using _data_t = std::tuple<Columns...>;
@ -215,30 +216,22 @@ namespace sqlpp
};
};
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>
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>
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>
{
};
SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable");
template <typename T>
struct check_selected_tuple;
@ -246,7 +239,7 @@ namespace sqlpp
struct check_selected_tuple<std::tuple<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>>;
};
template <typename T>
@ -265,7 +258,6 @@ namespace sqlpp
struct no_select_column_list_t
{
using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>;
using _nodes = detail::type_vector<>;
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
{
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
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");
template <typename Table>
struct check_update_table
@ -94,7 +99,6 @@ namespace sqlpp
struct no_single_table_t
{
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;

View File

@ -26,6 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/enable_join.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/table_alias.h>
#include <sqlpp11/all_of.h>
@ -36,7 +37,7 @@
namespace sqlpp
{
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>;
@ -51,42 +52,6 @@ namespace sqlpp
template <typename AliasProvider>
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>
_alias_t<AliasProvider> as(const AliasProvider& /*unused*/) const
{

View File

@ -26,8 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/operator/as_expression.h>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/enable_join.h>
#include <sqlpp11/table_columns.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/serialize.h>
@ -37,15 +36,9 @@
namespace sqlpp
{
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 _required_ctes = required_ctes_of<TableSpec>;
using _provided_tables = detail::type_set<AliasProvider>;
@ -54,42 +47,6 @@ namespace sqlpp
#warning: need to inherit?
//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>

View File

@ -37,8 +37,6 @@ namespace sqlpp
{
using _traits = make_traits<text, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr>;
trim_t(const Expr expr) : _expr(expr)
{
}
@ -52,6 +50,15 @@ namespace sqlpp
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>
Context& serialize(Context& context, const trim_t<Expr>& t)
{

View File

@ -28,14 +28,13 @@
#include <utility>
#include <sqlpp11/table.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/enable_join.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
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))
{
@ -47,43 +46,6 @@ namespace sqlpp
verbatim_table_alias_t& operator=(verbatim_table_alias_t&& rhs) = 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;
};
@ -100,7 +62,7 @@ namespace sqlpp
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))
{
@ -118,43 +80,6 @@ namespace sqlpp
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;
};

View File

@ -52,7 +52,6 @@ namespace sqlpp
struct where_t
{
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<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 <>
struct where_data_t<unconditional_t>
{
@ -83,7 +88,6 @@ namespace sqlpp
struct where_t<unconditional_t>
{
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
using _data_t = where_data_t<unconditional_t>;
@ -138,7 +142,6 @@ namespace sqlpp
struct no_where_t
{
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
using _data_t = no_data_t;

View File

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

View File

@ -34,15 +34,10 @@ function(test_compile name)
endif()
endfunction()
test_compile(any)
add_subdirectory(operator)
test_compile(aggregate_functions)
test_compile(arithmetic_expression)
test_compile(assign_expression)
test_compile(case_when)
test_compile(comparison_expression)
test_compile(dynamic)
test_compile(in_expression)
test_compile(logical_expression)
test_compile(result_row)
test_compile(select_as)
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>>;
// Selectable values.
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);
auto v_not_null = sqlpp::value(v);
const auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
// No value types for incomplete clauses
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.
*
* 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);
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>
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_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_maybe_null_alias = dynamic(true, sqlpp::value(sqlpp::compat::make_optional(v)).as(r_maybe_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);
static_assert(not sqlpp::has_value_type<decltype(v_not_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_maybe_null_alias)>::value, "");
static_assert(is_value_type<sqlpp::remove_dynamic_t<decltype(v_not_null)>, ValueType>::value, "");
static_assert(is_value_type<sqlpp::remove_dynamic_t<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_value_type<sqlpp::remove_dynamic_t<decltype(v_maybe_null_alias)>, OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_not_null), OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_maybe_null), OptValueType>::value, "");
static_assert(is_select_column_value_type<decltype(v_not_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 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.
*
* 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>>;
// 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);
// 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(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_not_null)))>::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.
static_assert(
@ -51,9 +50,17 @@ void test_any(Value v)
OptValueType>::value,
"");
#warning: test can be aliased
#warning: test has comparison operators
#warning: test nodes
// ANY expressions do not have `as` member function.
static_assert(not sqlpp::has_enabled_as<decltype(any(select(v_not_null)))>::value, "");
// 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()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2016, Roland Bock
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* 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(-opt_value)>, OptValueType>(), "");
#warning: test can be aliased
#warning: test has comparison operators
#warning: test nodes
// Arithmetic expressions enable the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(value + opt_value)>::value, "");
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>
@ -105,6 +114,17 @@ void test_modulus_expressions(Value v)
// Modulus combining optional with optional values
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>
@ -127,6 +147,17 @@ void test_concatenation_expressions(Value v)
// Concatenating optional with optional values
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()

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.
*
* 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,
"");
#warning: test can be aliased
#warning: test has comparison operators
// Assign expressions do not have the `as` member function.
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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2016, Roland Bock
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* 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_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.
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_not_null))>::value, "");
#warning: test can be aliased
#warning: test has comparison operators
#warning: test nodes
// Comparison expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(v_not_null == v_maybe_null)>::value, "");
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>
@ -118,10 +127,6 @@ void test_like(Value v)
// Compare nullable with nullable.
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()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2016, Roland Bock
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -23,14 +23,10 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MockDb.h"
#include "Sample.h"
#include <sqlpp11/sqlpp11.h>
namespace
{
auto db = MockDb{};
template <typename T>
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, select(v_maybe_null.as(sqlpp::alias::a))))>::value, "");
#warning: test can be aliased
#warning: test has comparison operators
#warning: test nodes
// IN expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
// 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()
{
// boolean
test_in_expression(bool{true});
#warning reactivate
#if 0
// integral
test_in_expression(int8_t{7});
test_in_expression(int16_t{7});
@ -111,5 +117,6 @@ int main()
// time_of_day
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.
*
* 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_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 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 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 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 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 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 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 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_maybe_bool<decltype(not(v_maybe_null))>::value, "");
#warning: test can be aliased
#warning: test has comparison operators
#warning: test nodes
// Logical expressions have the `as` member function.
static_assert(sqlpp::has_enabled_as<decltype(v_not_null and v_maybe_null)>::value, "");
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()

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);
// Optional selectable values.
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_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);
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
static_assert(sqlpp::has_name<decltype(bar.intN)>::value, "");
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

View File

@ -32,6 +32,9 @@ namespace
template <typename T, typename 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(sometimes);
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_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_same_type<decltype(select(v_maybe_null).as(column).sometimes.as(foo)), OptValueType>(), "");
static_assert(is_select_column_same_type<decltype(select(v_not_null).as(column).always.as(foo)), ValueType>(), "");
static_assert(is_select_column_same_type<decltype(select(v_maybe_null).as(column).sometimes.as(foo)), OptValueType>(), "");
// 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).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_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).always.as(foo)), ValueType>(), "");
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
@ -117,6 +120,8 @@ int main()
// boolean
test_select_as(bool{true});
#warning: reactivate
#if 0
// integral
test_select_as(int8_t{7});
test_select_as(int16_t{7});
@ -152,5 +157,6 @@ int main()
// time_of_day
test_select_as(std::chrono::microseconds{});
#endif
}

View File

@ -23,15 +23,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MockDb.h"
#include "Sample.h"
#include <sqlpp11/sqlpp11.h>
namespace
{
auto db = MockDb{};
}
SQLPP_ALIAS_PROVIDER(r_not_null);
SQLPP_ALIAS_PROVIDER(r_maybe_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_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_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(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 has comparison operators

View File

@ -93,7 +93,7 @@ namespace test
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;
};
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;
}
SQLPP_ALIAS_PROVIDER(cheese)
SQLPP_ALIAS_PROVIDER(param2);
SQLPP_ALIAS_PROVIDER(cheese);
SQLPP_ALIAS_PROVIDER(average);
SQLPP_ALIAS_PROVIDER(N);
int Select(int, char*[])
{
@ -63,11 +67,11 @@ int Select(int, char*[])
const auto t = test::TabBar{};
const auto tab_a = f.as(sqlpp::alias::a);
select(count(t.id));
select(sqlpp::count(1));
select(count(sqlpp::value(1)));
select(count(t.id).as(N));
select(sqlpp::count(1).as(N));
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))))
{
std::cout << row.a << std::endl;
@ -109,14 +113,14 @@ int Select(int, char*[])
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()
@ -130,7 +134,7 @@ int Select(int, char*[])
.offset(19u)
.limit(7u);
printer.reset();
std::cerr << serialize(stat, printer).str() << std::endl;
std::cerr << serialize(printer, stat).str() << std::endl;
auto s = sqlpp::select()
.columns(t.id)
@ -150,12 +154,12 @@ int Select(int, char*[])
}
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));
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;
}
@ -182,16 +186,16 @@ int Select(int, char*[])
}
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;
}
// checking #584
auto abs = db.prepare(select(t.alpha).from(t).where(sqlpp::parameterized_verbatim<sqlpp::unsigned_integral>(
"ABS(field1 -", sqlpp::parameter(t.alpha), ")") <=
auto abs = db.prepare(select(t.id).from(t).where(sqlpp::parameterized_verbatim<sqlpp::unsigned_integral>(
"ABS(field1 -", sqlpp::parameter(t.id), ")") <=
sqlpp::parameter(sqlpp::unsigned_integral(), param2)));
abs.params.alpha = 7;
abs.params.id = 7;
abs.params.param2 = 7;
return 0;

View File

@ -25,7 +25,6 @@
#include "MockDb.h"
#include "Sample.h"
#include "is_regular.h"
#include <iostream>
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/connection.h>
@ -53,175 +52,85 @@ int SelectType(int, char*[])
// Test a table
{
using T = typename std::decay<decltype(t)>::type;
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_selectable_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_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");
static_assert(not sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(sqlpp::is_table<T>::value, "type requirement");
}
// Test an alias of table
{
using T = decltype(t.as(alias::a));
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_selectable_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_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");
static_assert(not sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(sqlpp::is_table<T>::value, "type requirement");
}
// Test an integral column of an alias of table
{
using T = decltype(t.as(alias::a).id);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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(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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test an integral table column
{
using T = decltype(t.id);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
static_assert(not sqlpp::is_unsigned_integral_t<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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(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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(sqlpp::is_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_unsigned_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test an unsigned integral table column
{
using T = decltype(f.uIntN);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
static_assert(sqlpp::is_unsigned_integral_t<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(sqlpp::is_unsigned_integral<T>::value, "type requirement");
static_assert(not sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test a floating point table column
{
using T = decltype(f.doubleN);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
static_assert(sqlpp::is_floating_point_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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::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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_integral<T>::value, "type requirement");
static_assert(sqlpp::is_floating_point<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test a an alias of a numeric table column
{
using T = decltype(t.id.as(alias::a));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test a select of a single column without a from
{
using T = decltype(select(t.id));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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::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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// 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));
// 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_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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::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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test a select of an alias of a single numeric table column
{
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_expression_t<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::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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test an alias of a select of a single numeric table column
{
using T = decltype(select(t.id).from(t).as(alias::b));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "red to not be boolean");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(sqlpp::is_table<T>::value, "type requirement");
}
// 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));
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
static_assert(sqlpp::is_selectable_t<T>::value, "type requirement");
static_assert(not sqlpp::require_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_insert_t<T>::value, "type requirement");
static_assert(not sqlpp::must_not_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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(sqlpp::is_table<T>::value, "type requirement");
}
// 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);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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(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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// 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);
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
static_assert(sqlpp::is_expression_t<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(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");
static_assert(sqlpp::is_numeric<T>::value, "type requirement");
static_assert(not sqlpp::is_boolean<T>::value, "type requirement");
static_assert(not sqlpp::is_text<T>::value, "type requirement");
static_assert(not sqlpp::is_table<T>::value, "type requirement");
}
// Test that all_of(tab) is expanded in select
@ -362,17 +229,16 @@ int SelectType(int, char*[])
s.limit.set(30u);
s.limit.set(3u);
std::cerr << "------------------------\n";
serialize(s, printer).str();
serialize(printer, s).str();
std::cerr << "------------------------\n";
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.
{
auto s = dynamic_select(db).dynamic_columns();
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
{
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");
using T = sqlpp::wrap_operand<int>::type;
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");
static_assert(sqlpp::is_numeric<decltype(t.id)>::value, "TabBar.id has to be a numeric");
((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");
!t.boolNn;
serialize(t.textN < "kaesekuchen", printer).str();
serialize(t.textN + "hallenhalma", printer).str();
static_assert(sqlpp::must_not_insert_t<decltype(t.id)>::value, "id must not be inserted");
serialize(t.id, printer).str();
serialize(printer, t.textN < "kaesekuchen").str();
serialize(printer, t.textN + "hallenhalma").str();
serialize(printer, t.id).str();
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 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_t<decltype(select(r.a).from(r))>::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<decltype(select(r.a).from(r))>::value, "select(bool) has to be a bool");
auto s1 = sqlpp::select()
.flags(sqlpp::distinct, sqlpp::straight_join)
.columns(l.boolNn, r.a)