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

Removing more instances of wrap_operand

This commit is contained in:
Roland Bock 2024-07-14 12:09:00 +02:00
parent 87f4c348e9
commit 61030742b3
34 changed files with 208 additions and 1004 deletions

View File

@ -37,3 +37,5 @@ SQLPP_ALIAS_PROVIDER(max_price);
std::cout << row.max_price << '\n';
}
```

View File

@ -31,44 +31,13 @@
namespace sqlpp
{
struct avg_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "avg_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T avg;
T& operator()()
{
return avg;
}
const T& operator()() const
{
return avg;
}
};
};
};
template <typename Flag, typename Expr>
struct avg_t : public expression_operators<avg_t<Flag, Expr>, floating_point>,
public aggregate_function_operators<avg_t<Flag, Expr>>,
public alias_operators<avg_t<Flag, Expr>>
struct avg_t
{
using _traits = make_traits<floating_point, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::true_type;
using _is_aggregate_expression = std::true_type;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value,
"avg() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
using _auto_alias_t = avg_alias_t;
avg_t(Expr expr) : _expr(expr)
{
}
@ -82,6 +51,12 @@ namespace sqlpp
Expr _expr;
};
template <typename Flag, typename Expr>
struct value_type_of<avg_t<Flag, Expr>>
{
using type = sqlpp::force_optional_t<floating_point>;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const avg_t<Flag, Expr>& t, Context& context)
{
@ -97,20 +72,18 @@ namespace sqlpp
}
template <typename T>
auto avg(T t) -> avg_t<noop, wrap_operand_t<T>>
using check_avg_arg =
std::enable_if_t<(is_numeric<T>::value or is_boolean<T>::value) and not contains_aggregate_function_t<T>::value>;
template <typename T, typename = check_avg_arg<T>>
auto avg(T t) -> avg_t<noop, T>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"avg() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a numeric value expression as argument");
return {t};
return {std::move(t)};
}
template <typename T>
auto avg(const distinct_t& /*unused*/, T t) -> avg_t<distinct_t, wrap_operand_t<T>>
template <typename T, typename = check_avg_arg<T>>
auto avg(const distinct_t& /*unused*/, T t) -> avg_t<distinct_t, T>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"avg() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a numeric value expression as argument");
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -31,44 +31,14 @@
namespace sqlpp
{
struct sum_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "sum_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T sum;
T& operator()()
{
return sum;
}
const T& operator()() const
{
return sum;
}
};
};
};
template <typename Flag, typename Expr>
struct sum_t : public expression_operators<sum_t<Flag, Expr>, value_type_of_t<Expr>>,
public aggregate_function_operators<sum_t<Flag, Expr>>,
public alias_operators<sum_t<Flag, Expr>>
struct sum_t
{
using _traits = make_traits<value_type_of_t<Expr>, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr, aggregate_function>;
using _can_be_null = std::true_type;
using _is_aggregate_expression = std::true_type;
static_assert(is_noop<Flag>::value or std::is_same<distinct_t, Flag>::value,
"sum() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");
using _auto_alias_t = sum_alias_t;
sum_t(Expr expr) : _expr(expr)
{
}
@ -82,6 +52,13 @@ namespace sqlpp
Expr _expr;
};
template <typename Flag, typename Expr>
struct value_type_of<sum_t<Flag, Expr>>
{
using type = sqlpp::force_optional_t<
typename std::conditional<is_boolean<Expr>::value, integral, value_type_of_t<Expr>>::type>;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const sum_t<Flag, Expr>& t, Context& context)
{
@ -97,20 +74,18 @@ namespace sqlpp
}
template <typename T>
auto sum(T t) -> sum_t<noop, wrap_operand_t<T>>
using check_sum_arg =
std::enable_if_t<(is_numeric<T>::value or is_boolean<T>::value) and not contains_aggregate_function_t<T>::value>;
template <typename T, typename = check_sum_arg<T>>
auto sum(T t) -> sum_t<noop, T>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"sum() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
return {t};
return {std::move(t)};
}
template <typename T>
auto sum(const distinct_t& /*unused*/, T t) -> sum_t<distinct_t, wrap_operand_t<T>>
template <typename T, typename = check_sum_arg<T>>
auto sum(const distinct_t& /*unused*/, T t) -> sum_t<distinct_t, T>
{
static_assert(not contains_aggregate_function_t<wrap_operand_t<T>>::value,
"sum() cannot be used on an aggregate function");
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -26,7 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/detail/type_set.h>
@ -51,6 +51,11 @@ namespace sqlpp
Select _select;
};
template<typename Select>
struct value_type_of<any_t<Select>> : value_type_of<Select>
{
};
template <typename Context, typename Select>
Context& serialize(const any_t<Select>& t, Context& context)
{
@ -59,13 +64,13 @@ namespace sqlpp
return context;
}
template <typename T>
auto any(T t) -> any_t<wrap_operand_t<T>>
#warning: Need tests
template <typename Select>
using check_any_args = std::enable_if_t<is_statement_t<Select>::value and has_value_type<Select>::value>;
template <typename ...Policies, typename = check_any_args<statement_t<Policies...>>>
auto any(statement_t<Policies...> t) -> any_t<statement_t<Policies...>>
{
static_assert(is_select_t<wrap_operand_t<T>>::value, "any() requires a select expression as argument");
static_assert(is_expression_t<wrap_operand_t<T>>::value,
"any() requires a single column select expression as argument");
// FIXME: can we accept non-values like NULL here?
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -39,22 +39,20 @@ namespace sqlpp
template <typename Then, typename Else>
using check_case_else_t = static_combined_check_t<
static_check_t<is_expression_t<wrap_operand_t<Else>>::value, assert_case_else_expression_t>,
static_check_t<logic::any_t<is_sql_null_t<Then>::value,
is_sql_null_t<wrap_operand_t<Else>>::value,
std::is_same<value_type_of_t<Then>, value_type_of_t<wrap_operand_t<Else>>>::value>::value,
static_check_t<is_expression_t<Else>::value, assert_case_else_expression_t>,
static_check_t<values_are_comparable<Then, Else>::value,
assert_case_then_else_same_type_t>>;
SQLPP_PORTABLE_STATIC_ASSERT(assert_case_then_expression_t, "argument is not a value expression in then()");
template <typename Then>
using check_case_then_t =
static_check_t<logic::all_t<is_expression_t<wrap_operand_t<Then>>::value>::value, assert_case_then_expression_t>;
static_check_t<logic::all_t<is_expression_t<Then>::value>::value, assert_case_then_expression_t>;
SQLPP_PORTABLE_STATIC_ASSERT(assert_case_when_boolean_expression_t,
"argument is not a boolean expression in case_when()");
template <typename When>
using check_case_when_t = static_check_t<
logic::all_t<is_boolean_t<wrap_operand_t<When>>::value, is_expression_t<wrap_operand_t<When>>::value>::value,
logic::all_t<is_boolean<When>::value, is_expression_t<When>::value>::value,
assert_case_when_boolean_expression_t>;
template <typename When, typename Then, typename Else>
@ -120,7 +118,7 @@ namespace sqlpp
class case_when_t
{
template <typename Then>
auto _then_impl(consistent_t /*unused*/, Then t) -> case_then_t<When, wrap_operand_t<Then>>
auto _then_impl(consistent_t /*unused*/, Then t) -> case_then_t<When, Then>
{
return {_when, t};
}
@ -165,7 +163,7 @@ namespace sqlpp
namespace detail
{
template <typename When>
auto case_when_impl(consistent_t /*unused*/, When when) -> case_when_t<wrap_operand_t<When>>
auto case_when_impl(consistent_t /*unused*/, When when) -> case_when_t<When>
{
return {when};
}

View File

@ -27,13 +27,13 @@
*/
#include <sqlpp11/operator/as_expression.h>
#include <sqlpp11/operator/assign_expression.h>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/default_value.h>
#include <sqlpp11/null.h>
#include <sqlpp11/sort_order.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/assignment.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/wrong.h>
#include <sqlpp11/detail/type_set.h>
@ -74,10 +74,10 @@ namespace sqlpp
return _table{};
}
template <typename alias_provider>
as_expression<column_t, alias_provider> as(const alias_provider& /*unused*/) const
template <typename AliasProvider>
auto as(const AliasProvider& alias_provider) const -> as_expression<column_t, AliasProvider>
{
return {*this};
return as(*this, alias_provider);
}
sqlpp::compat::optional<column_t> if_(bool condition) const
@ -86,12 +86,9 @@ namespace sqlpp
}
template <typename T>
auto operator=(T t) const -> assignment_t<column_t, wrap_operand_t<T>>
auto operator=(T value) const -> assign_expression<column_t, T>
{
using rhs = wrap_operand_t<T>;
static_assert(_is_valid_assignment_operand<rhs>::value, "invalid rhs assignment operand");
return {*this, {rhs{t}}};
return assign(*this, std::move(value));
}
auto operator=(null_t /*unused*/) const -> assignment_t<column_t, null_t>

View File

@ -26,7 +26,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>

View File

@ -27,7 +27,7 @@
*/
#include <sqlpp11/data_types/parameter_value.h>
#include <sqlpp11/value_or_null.h>
#include <sqlpp11/value.h>
namespace sqlpp
{
@ -53,7 +53,7 @@ namespace sqlpp
return *this;
}
parameter_value_base& operator=(const value_or_null_t<DataType>& val)
parameter_value_base& operator=(const value_t<DataType>& val)
{
if (val._is_null)
{

View File

@ -1,200 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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/data_types/boolean.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/noop.h>
#include <sqlpp11/wrap_operand.h>
namespace sqlpp
{
template <typename Lhs, typename Rhs>
struct binary_expression_t<Lhs, op::equal_to, Rhs>
: public expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>, boolean>,
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
{
using _traits = make_traits<boolean, tag::is_expression>;
using _lhs_t = Lhs;
using _rhs_t = Rhs;
using _nodes = detail::type_vector<_lhs_t, _rhs_t>;
binary_expression_t(Lhs lhs, Rhs rhs) : _lhs(lhs), _rhs(rhs)
{
}
binary_expression_t(const binary_expression_t&) = default;
binary_expression_t(binary_expression_t&&) = default;
binary_expression_t& operator=(const binary_expression_t&) = default;
binary_expression_t& operator=(binary_expression_t&&) = default;
~binary_expression_t() = default;
_lhs_t _lhs;
_rhs_t _rhs;
};
template <typename Context, typename Lhs, typename Rhs>
Context& serialize(const binary_expression_t<Lhs, op::equal_to, Rhs>& t, Context& context)
{
context << "(";
serialize_operand(t._lhs, context);
context << "=";
serialize_operand(t._rhs, context);
context << ")";
return context;
}
template <typename Lhs, typename Rhs>
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>
: public expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>, boolean>,
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
{
using _traits = make_traits<boolean, tag::is_expression>;
using _lhs_t = Lhs;
using _rhs_t = Rhs;
using _nodes = detail::type_vector<_lhs_t, _rhs_t>;
binary_expression_t(Lhs lhs, Rhs rhs) : _lhs(lhs), _rhs(rhs)
{
}
binary_expression_t(const binary_expression_t&) = default;
binary_expression_t(binary_expression_t&&) = default;
binary_expression_t& operator=(const binary_expression_t&) = default;
binary_expression_t& operator=(binary_expression_t&&) = default;
~binary_expression_t() = default;
_lhs_t _lhs;
_rhs_t _rhs;
};
template <typename Context, typename Lhs, typename Rhs>
Context& serialize(const binary_expression_t<Lhs, op::not_equal_to, Rhs>& t, Context& context)
{
context << "(";
serialize_operand(t._lhs, context);
context << "<>";
serialize_operand(t._rhs, context);
context << ")";
return context;
}
template <typename Rhs>
struct unary_expression_t<op::logical_not, Rhs>
: public expression_operators<unary_expression_t<op::logical_not, Rhs>, boolean>,
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
{
using _traits = make_traits<boolean, tag::is_expression>;
using _nodes = detail::type_vector<Rhs>;
unary_expression_t(Rhs rhs) : _rhs(rhs)
{
}
unary_expression_t(const unary_expression_t&) = default;
unary_expression_t(unary_expression_t&&) = default;
unary_expression_t& operator=(const unary_expression_t&) = default;
unary_expression_t& operator=(unary_expression_t&&) = default;
~unary_expression_t() = default;
Rhs _rhs;
};
template <typename Context, typename Rhs>
Context& serialize(const unary_expression_t<op::logical_not, Rhs>& t, Context& context)
{
context << "(";
context << "NOT ";
serialize_operand(t._rhs, context);
context << ")";
return context;
}
template <typename Lhs, typename O, typename Rhs>
struct binary_expression_t : public expression_operators<binary_expression_t<Lhs, O, Rhs>, value_type_of_t<O>>,
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
{
using _traits = make_traits<value_type_of_t<O>, tag::is_expression>;
using _nodes = detail::type_vector<Lhs, Rhs>;
binary_expression_t(Lhs lhs, Rhs rhs) : _lhs(lhs), _rhs(rhs)
{
}
binary_expression_t(const binary_expression_t&) = default;
binary_expression_t(binary_expression_t&&) = default;
binary_expression_t& operator=(const binary_expression_t&) = default;
binary_expression_t& operator=(binary_expression_t&&) = default;
~binary_expression_t() = default;
Lhs _lhs;
Rhs _rhs;
};
template <typename Context, typename Lhs, typename O, typename Rhs>
Context& serialize(const binary_expression_t<Lhs, O, Rhs>& t, Context& context)
{
context << "(";
serialize_operand(t._lhs, context);
context << O::_name;
serialize_operand(t._rhs, context);
context << ")";
return context;
}
template <typename O, typename Rhs>
struct unary_expression_t : public expression_operators<unary_expression_t<O, Rhs>, value_type_of_t<O>>,
public alias_operators<unary_expression_t<O, Rhs>>
{
using _traits = make_traits<value_type_of_t<O>, tag::is_expression>;
using _nodes = detail::type_vector<Rhs>;
unary_expression_t(Rhs rhs) : _rhs(rhs)
{
}
unary_expression_t(const unary_expression_t&) = default;
unary_expression_t(unary_expression_t&&) = default;
unary_expression_t& operator=(const unary_expression_t&) = default;
unary_expression_t& operator=(unary_expression_t&&) = default;
~unary_expression_t() = default;
Rhs _rhs;
};
template <typename Context, typename O, typename Rhs>
Context& serialize(const unary_expression_t<O, Rhs>& t, Context& context)
{
context << "(";
context << O::_name;
serialize_operand(t._rhs, context);
context << ")";
return context;
}
} // namespace sqlpp

View File

@ -35,10 +35,6 @@
#include <sqlpp11/case.h>
#include <sqlpp11/lower.h>
#include <sqlpp11/upper.h>
#include <sqlpp11/in.h>
#include <sqlpp11/not_in.h>
#include <sqlpp11/is_null.h>
#include <sqlpp11/is_not_null.h>
#include <sqlpp11/any.h>
#include <sqlpp11/some.h>
#include <sqlpp11/value_type.h>
@ -46,7 +42,6 @@
#include <sqlpp11/parameterized_verbatim.h>
#include <sqlpp11/verbatim_table.h>
#include <sqlpp11/value.h>
#include <sqlpp11/value_or_null.h>
#include <sqlpp11/eval.h>
namespace sqlpp
@ -61,73 +56,6 @@ namespace sqlpp
return {context.str()};
}
template <typename Expression>
auto is_null(Expression e) -> decltype(e.is_null())
{
return e.is_null();
}
template <typename Expression>
auto is_not_null(Expression e) -> decltype(e.is_not_null())
{
return e.is_not_null();
}
template <typename Container>
struct value_list_t // to be used in .in() method
{
using _traits = make_traits<value_type_t<typename Container::value_type>, tag::is_expression>;
using _nodes = detail::type_vector<>;
using _container_t = Container;
value_list_t(_container_t container) : _container(container)
{
}
value_list_t(const value_list_t&) = default;
value_list_t(value_list_t&&) = default;
value_list_t& operator=(const value_list_t&) = default;
value_list_t& operator=(value_list_t&&) = default;
~value_list_t() = default;
_container_t _container;
};
template <typename Context, typename Container>
Context& serialize(const value_list_t<Container>& t, Context& context)
{
if (t._container.size() == 1)
{
return serialize(value(*begin(t._container)), context);
}
bool first = true;
for (const auto& entry : t._container)
{
if (first)
{
first = false;
}
else
{
context << ',';
}
serialize_operand(value(entry), context);
}
return context;
}
template <typename Container>
auto value_list(Container c) -> value_list_t<Container>
{
static_assert(
is_wrapped_value_t<wrap_operand_t<typename Container::value_type>>::value,
"value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
return {c};
}
template <typename T>
constexpr const char* get_sql_name(const T& /*unused*/)
{

View File

@ -26,7 +26,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>

View File

@ -26,7 +26,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>

View File

@ -1,118 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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/type_traits.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/in_fwd.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp
{
struct in_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "in_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T in;
};
};
};
template <typename Operand, typename... Args>
struct in_t : public expression_operators<in_t<Operand, Args...>, boolean>,
public alias_operators<in_t<Operand, Args...>>
{
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Operand, Args...>;
using _auto_alias_t = in_alias_t;
in_t(Operand operand, Args... args) : _operand(operand), _args(args...)
{
}
in_t(const in_t&) = default;
in_t(in_t&&) = default;
in_t& operator=(const in_t&) = default;
in_t& operator=(in_t&&) = default;
~in_t() = default;
Operand _operand;
std::tuple<Args...> _args;
};
template <typename Context, typename Operand, typename Arg, typename... Args>
Context& serialize(const in_t<Operand, Arg, Args...>& t, Context& context)
{
serialize(t._operand, context);
context << " IN(";
if (sizeof...(Args) == 0)
{
serialize(std::get<0>(t._args), context);
}
else
{
interpret_tuple(t._args, ',', context);
}
context << ')';
return context;
}
template <typename Context, typename Operand>
Context& serialize(const in_t<Operand>&, Context& context)
{
serialize(boolean_operand{false}, context);
return context;
}
template <typename Container>
struct value_list_t;
template <typename Context, typename Operand, typename Container>
Context& serialize(const in_t<Operand, value_list_t<Container>>& t, Context& context)
{
const auto& value_list = std::get<0>(t._args);
if (value_list._container.empty())
{
serialize(boolean_operand{false}, context);
}
else
{
serialize(t._operand, context);
context << " IN(";
serialize(value_list, context);
context << ')';
}
return context;
}
} // namespace sqlpp

View File

@ -28,7 +28,7 @@
#include <sqlpp11/default_value.h>
#include <sqlpp11/null.h>
#include <sqlpp11/value_or_null.h>
#include <sqlpp11/value.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/type_set.h>
@ -59,10 +59,9 @@ namespace sqlpp
using _is_insert_value = std::true_type;
using _column_t = Column;
using _pure_value_t = typename value_type_of_t<Column>::_cpp_value_type;
using _wrapped_value_t = wrap_operand_t<_pure_value_t>;
using _value_or_null_t = value_or_null_t<typename Column::_traits::_value_type>;
using _value_t = value_t<typename Column::_traits::_value_type>;
insert_value_t(_wrapped_value_t rhs)
insert_value_t(_pure_value_t rhs)
: _is_null(false), _is_default(false), _value(rhs._t)
{
}
@ -77,7 +76,7 @@ namespace sqlpp
{
}
insert_value_t(const _value_or_null_t& rhs)
insert_value_t(const _value_t& rhs)
: _is_null(rhs._is_null), _is_default(false), _value{rhs._value}
{
}
@ -90,7 +89,7 @@ namespace sqlpp
bool _is_null;
bool _is_default;
_wrapped_value_t _value;
_pure_value_t _value;
};
template <typename Context, typename ValueType>

View File

@ -88,7 +88,7 @@ namespace sqlpp
using type = static_combined_check_t<static_check_t<is_raw_table_t<T>::value, assert_into_arg_is_table>>;
};
template <typename T>
using check_into_t = typename check_into<wrap_operand_t<T>>::type;
using check_into_t = typename check_into<T>::type;
// NO INTO YET
struct no_into_t

View File

@ -1,79 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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/data_types/boolean.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp
{
struct is_not_null_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "is_not_null_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T is_not_null;
};
};
};
template <typename Operand>
struct is_not_null_t : public expression_operators<is_not_null_t<Operand>, boolean>,
public alias_operators<is_not_null_t<Operand>>
{
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable, tag::requires_parens>;
using _nodes = detail::type_vector<Operand>;
using _auto_alias_t = is_not_null_alias_t;
is_not_null_t(Operand operand) : _operand(operand)
{
}
is_not_null_t(const is_not_null_t&) = default;
is_not_null_t(is_not_null_t&&) = default;
is_not_null_t& operator=(const is_not_null_t&) = default;
is_not_null_t& operator=(is_not_null_t&&) = default;
~is_not_null_t() = default;
Operand _operand;
};
template <typename Context, typename Operand>
Context& serialize(const is_not_null_t<Operand>& t, Context& context)
{
serialize_operand(t._operand, context);
context << " IS NOT NULL";
return context;
}
} // namespace sqlpp

View File

@ -1,79 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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/data_types/boolean.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp
{
struct is_null_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "is_null_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T is_null;
};
};
};
template <typename Operand>
struct is_null_t : public expression_operators<is_null_t<Operand>, boolean>,
public alias_operators<is_null_t<Operand>>
{
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable, tag::requires_parens>;
using _nodes = detail::type_vector<Operand>;
using _auto_alias_t = is_null_alias_t;
is_null_t(Operand operand) : _operand(operand)
{
}
is_null_t(const is_null_t&) = default;
is_null_t(is_null_t&&) = default;
is_null_t& operator=(const is_null_t&) = default;
is_null_t& operator=(is_null_t&&) = default;
~is_null_t() = default;
Operand _operand;
};
template <typename Context, typename Operand>
Context& serialize(const is_null_t<Operand>& t, Context& context)
{
serialize_operand(t._operand, context);
context << " IS NULL";
return context;
}
} // namespace sqlpp

View File

@ -79,10 +79,10 @@ namespace sqlpp
struct check_limit
{
using type =
static_combined_check_t<static_check_t<is_unsigned_integral_t<T>::value, assert_limit_is_unsigned_integral>>;
static_combined_check_t<static_check_t<is_unsigned_integral<T>::value, assert_limit_is_unsigned_integral>>;
};
template <typename T>
using check_limit_t = typename check_limit<wrap_operand_t<T>>::type;
using check_limit_t = typename check_limit<T>::type;
struct no_limit_t
{
@ -109,9 +109,9 @@ namespace sqlpp
using _consistency_check = consistent_t;
template <typename Arg>
auto limit(Arg arg) const -> _new_statement_t<check_limit_t<Arg>, limit_t<wrap_operand_t<Arg>>>
auto limit(Arg arg) const -> _new_statement_t<check_limit_t<Arg>, limit_t<Arg>>
{
return _limit_impl(check_limit_t<Arg>{}, wrap_operand_t<Arg>{arg});
return _limit_impl(check_limit_t<Arg>{}, std::move(arg));
}
private:
@ -121,7 +121,7 @@ namespace sqlpp
template <typename Arg>
auto _limit_impl(consistent_t /*unused*/, Arg arg) const -> _new_statement_t<consistent_t, limit_t<Arg>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<Arg>{arg}};
return {static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<Arg>{std::move(arg)}};
}
};
};

View File

@ -26,43 +26,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/integral/data_type.h>
#include <sqlpp11/data_types/text/data_type.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
struct lower_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "lower_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T lower;
T& operator()()
{
return lower;
}
const T& operator()() const
{
return lower;
}
};
};
};
template <typename Flag, typename Expr>
struct lower_t : public expression_operators<lower_t<Flag, Expr>, text>, public alias_operators<lower_t<Flag, Expr>>
template <typename Expr>
struct lower_t
{
using _traits = make_traits<text, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr>;
using _auto_alias_t = lower_alias_t;
lower_t(const Expr expr) : _expr(expr)
{
}
@ -76,8 +51,8 @@ namespace sqlpp
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const lower_t<Flag, Expr>& t, Context& context)
template <typename Context, typename Expr>
Context& serialize(const lower_t<Expr>& t, Context& context)
{
context << "LOWER(";
serialize_operand(t._expr, context);
@ -85,11 +60,13 @@ namespace sqlpp
return context;
}
template <typename T>
auto lower(T t) -> lower_t<noop, wrap_operand_t<T>>
template<typename T>
using check_lower_args = std::enable_if_t<is_text<T>::value>;
template <typename T, typename = check_lower_args<T>>
auto lower(T t) -> lower_t<T>
{
static_assert(is_text_t<wrap_operand_t<T>>::value, "lower() requires a text expression as argument");
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -1,118 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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/type_traits.h>
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/in_fwd.h>
#include <sqlpp11/detail/type_set.h>
namespace sqlpp
{
struct not_in_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "not_in_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T not_in;
};
};
};
template <typename Operand, typename... Args>
struct not_in_t : public expression_operators<not_in_t<Operand, Args...>, boolean>,
public alias_operators<not_in_t<Operand, Args...>>
{
using _traits = make_traits<boolean, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Operand, Args...>;
using _auto_alias_t = not_in_alias_t;
not_in_t(Operand operand, Args... args) : _operand(operand), _args(args...)
{
}
not_in_t(const not_in_t&) = default;
not_in_t(not_in_t&&) = default;
not_in_t& operator=(const not_in_t&) = default;
not_in_t& operator=(not_in_t&&) = default;
~not_in_t() = default;
Operand _operand;
std::tuple<Args...> _args;
};
template <typename Context, typename Operand, typename Arg, typename... Args>
Context& serialize(const not_in_t<Operand, Arg, Args...>& t, Context& context)
{
serialize_operand(t._operand, context);
context << " NOT IN(";
if (sizeof...(Args) == 0)
{
serialize(std::get<0>(t._args), context);
}
else
{
interpret_tuple(t._args, ',', context);
}
context << ')';
return context;
}
template <typename Context, typename Operand>
Context& serialize(const not_in_t<Operand>&, Context& context)
{
serialize(boolean_operand{true}, context);
return context;
}
template <typename Container>
struct value_list_t;
template <typename Context, typename Operand, typename Container>
Context& serialize(const not_in_t<Operand, value_list_t<Container>>& t, Context& context)
{
const auto& value_list = std::get<0>(t._args);
if (value_list._container.empty())
{
serialize(boolean_operand{true}, context);
}
else
{
serialize(t._operand, context);
context << " NOT IN(";
serialize(value_list, context);
context << ')';
}
return context;
}
} // namespace sqlpp

View File

@ -78,10 +78,10 @@ namespace sqlpp
struct check_offset
{
using type =
static_combined_check_t<static_check_t<is_unsigned_integral_t<T>::value, assert_offset_is_unsigned_integral>>;
static_combined_check_t<static_check_t<is_unsigned_integral<T>::value, assert_offset_is_unsigned_integral>>;
};
template <typename T>
using check_offset_t = typename check_offset<wrap_operand_t<T>>::type;
using check_offset_t = typename check_offset<T>::type;
struct no_offset_t
{
@ -121,9 +121,9 @@ namespace sqlpp
using _consistency_check = consistent_t;
template <typename Arg>
auto offset(Arg arg) const -> _new_statement_t<check_offset_t<Arg>, offset_t<wrap_operand_t<Arg>>>
auto offset(Arg arg) const -> _new_statement_t<check_offset_t<Arg>, offset_t<Arg>>
{
return _offset_impl(check_offset_t<Arg>{}, wrap_operand_t<Arg>{arg});
return _offset_impl(check_offset_t<Arg>{}, std::move(arg));
}
private:
@ -133,7 +133,7 @@ namespace sqlpp
template <typename Arg>
auto _offset_impl(consistent_t /*unused*/, Arg arg) const -> _new_statement_t<consistent_t, offset_t<Arg>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<Arg>{arg}};
return {static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<Arg>{std::move(arg)}};
}
};
};

View File

@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace sqlpp
{
#warning: Need to add compound assingment as += etc.
template <typename L, typename R>
struct assign_expression
{

View File

@ -130,6 +130,54 @@ namespace sqlpp
static constexpr auto symbol = " NOT IN ";
};
#if 0 // original serialize implementation
template <typename Context, typename Operand, typename Arg, typename... Args>
Context& serialize(const in_t<Operand, Arg, Args...>& t, Context& context)
{
serialize(t._operand, context);
context << " IN(";
if (sizeof...(Args) == 0)
{
serialize(std::get<0>(t._args), context);
}
else
{
interpret_tuple(t._args, ',', context);
}
context << ')';
return context;
}
template <typename Context, typename Operand>
Context& serialize(const in_t<Operand>&, Context& context)
{
serialize(boolean_operand{false}, context);
return context;
}
template <typename Container>
struct value_list_t;
template <typename Context, typename Operand, typename Container>
Context& serialize(const in_t<Operand, value_list_t<Container>>& t, Context& context)
{
const auto& value_list = std::get<0>(t._args);
if (value_list._container.empty())
{
serialize(boolean_operand{false}, context);
}
else
{
serialize(t._operand, context);
context << " IN(";
serialize(value_list, context);
context << ')';
}
return context;
}
#endif
#warning: something.not_in(select(...)); should be suppported as is
template <typename L, typename... Args, typename = check_in_args<L, Args...>>
constexpr auto not_in(L l, std::tuple<Args...> args) -> in_expression<L, operator_not_in, std::tuple<Args...>>

View File

@ -42,7 +42,6 @@
#include <sqlpp11/for_update.h>
#include <sqlpp11/offset.h>
#include <sqlpp11/union.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/wrong.h>
namespace sqlpp

View File

@ -26,7 +26,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/char_sequence.h>
@ -51,6 +51,11 @@ namespace sqlpp
Select _select;
};
template<typename Select>
struct value_type_of<some_t<Select>> : value_type_of<Select>
{
};
template <typename Context, typename Select>
Context& serialize(const some_t<Select>& t, Context& context)
{
@ -59,13 +64,13 @@ namespace sqlpp
return context;
}
template <typename T>
auto some(T t) -> some_t<wrap_operand_t<T>>
#warning : Need tests
template <typename Select>
using check_some_args = std::enable_if_t<has_value_type<Select>::value>;
template <typename ... Policies, typename = check_some_args<statement_t<Policies...>>>
auto some(statement_t<Policies...> t) -> some_t<statement_t<Policies...>>
{
static_assert(is_select_t<wrap_operand_t<T>>::value,
"some() requires a single column select expression as argument");
static_assert(is_expression_t<wrap_operand_t<T>>::value,
"some() requires a single column select expression as argument");
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -27,43 +27,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/integral/data_type.h>
#include <sqlpp11/data_types/text/data_type.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
struct trim_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "trim_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T trim;
T& operator()()
{
return trim;
}
const T& operator()() const
{
return trim;
}
};
};
};
template <typename Flag, typename Expr>
struct trim_t : public expression_operators<trim_t<Flag, Expr>, text>, public alias_operators<trim_t<Flag, Expr>>
template <typename Expr>
struct trim_t
{
using _traits = make_traits<text, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr>;
using _auto_alias_t = trim_alias_t;
trim_t(const Expr expr) : _expr(expr)
{
}
@ -77,8 +52,8 @@ namespace sqlpp
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const trim_t<Flag, Expr>& t, Context& context)
template <typename Context, typename Expr>
Context& serialize(const trim_t<Expr>& t, Context& context)
{
context << "TRIM(";
serialize_operand(t._expr, context);
@ -86,11 +61,13 @@ namespace sqlpp
return context;
}
template <typename T>
auto trim(T t) -> trim_t<noop, wrap_operand_t<T>>
template<typename T>
using check_trim_args = std::enable_if_t<is_text<T>::value>;
template <typename T, typename = check_trim_args<T>>
auto trim(T t) -> trim_t<T>
{
static_assert(is_expression_t<wrap_operand_t<T>>::value, "trim() requires an expression as argument");
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -26,7 +26,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>

View File

@ -26,43 +26,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/integral/data_type.h>
#include <sqlpp11/data_types/text/data_type.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp
{
struct upper_alias_t
{
struct _alias_t
{
static constexpr const char _literal[] = "upper_";
using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
template <typename T>
struct _member_t
{
T upper;
T& operator()()
{
return upper;
}
const T& operator()() const
{
return upper;
}
};
};
};
template <typename Flag, typename Expr>
struct upper_t : public expression_operators<upper_t<Flag, Expr>, text>, public alias_operators<upper_t<Flag, Expr>>
template <typename Expr>
struct upper_t
{
using _traits = make_traits<text, tag::is_expression, tag::is_selectable>;
using _nodes = detail::type_vector<Expr>;
using _auto_alias_t = upper_alias_t;
upper_t(const Expr expr) : _expr(expr)
{
}
@ -76,8 +51,8 @@ namespace sqlpp
Expr _expr;
};
template <typename Context, typename Flag, typename Expr>
Context& serialize(const upper_t<Flag, Expr>& t, Context& context)
template <typename Context, typename Expr>
Context& serialize(const upper_t<Expr>& t, Context& context)
{
context << "UPPER(";
serialize_operand(t._expr, context);
@ -85,11 +60,13 @@ namespace sqlpp
return context;
}
template <typename T>
auto upper(T t) -> upper_t<noop, wrap_operand_t<T>>
template<typename T>
using check_upper_args = std::enable_if_t<is_text<T>::value>;
template <typename T, typename = check_upper_args<T>>
auto upper(T t) -> upper_t<T>
{
static_assert(is_text_t<wrap_operand_t<T>>::value, "upper() requires a text expression as argument");
return {t};
return {std::move(t)};
}
} // namespace sqlpp

View File

@ -28,7 +28,6 @@
#include <sqlpp11/expression_operators.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/wrap_operand.h>
namespace sqlpp
{

View File

@ -1,85 +0,0 @@
#pragma once
/*
* Copyright (c) 2013-2015, 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/null.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/wrap_operand.h>
namespace sqlpp
{
template <typename ValueType>
struct value_or_null_t
{
using _cpp_value_type = typename ValueType::_cpp_value_type;
using _traits = make_traits<ValueType, tag::is_expression>;
using _nodes = detail::type_vector<>;
value_or_null_t(_cpp_value_type value) : _value(value), _is_null(false)
{
}
value_or_null_t(const null_t& /*unused*/) : _value(), _is_null(true)
{
}
typename ValueType::_cpp_value_type _value;
bool _is_null;
};
template <typename Context, typename ValueType>
Context& serialize(const value_or_null_t<ValueType>& t, Context& context)
{
if (t._is_null)
{
context << "NULL";
}
else
{
serialize(wrap_operand_t<typename ValueType::_cpp_value_type>{t._value}, context);
}
return context;
}
template <typename T>
auto value_or_null(T t) -> value_or_null_t<value_type_of_t<wrap_operand_t<T>>>
{
static_assert(is_wrapped_value_t<wrap_operand_t<T>>::value,
"value_or_null() is to be called with non-sql-type like int, or string or null");
return {t};
}
template <typename ValueType>
auto value_or_null(null_t t) -> value_or_null_t<ValueType>
{
static_assert(is_value_type_t<ValueType>::value,
"value_or_null() is to be called with non-sql-type like int, or string");
return {t};
}
} // namespace sqlpp

View File

@ -26,7 +26,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>

View File

@ -28,7 +28,6 @@
#include <sqlpp11/assignment.h>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h>

View File

@ -41,7 +41,6 @@ void test_aggregate_functions(Value v)
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
using ValueType = sqlpp::value_type_of_t<Value>;
using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<Value>>;
// Aggregate of non-nullable
@ -53,13 +52,32 @@ void test_aggregate_functions(Value v)
static_assert(is_same_type<decltype(count(v_not_null)), sqlpp::integral>::value, "");
static_assert(is_same_type<decltype(max(v_maybe_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(min(v_maybe_null)), OptValueType>::value, "");
}
template <typename Value>
void test_numeric_aggregate_functions(Value v)
{
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));
using ValueType = typename std::conditional<std::is_same<Value, bool>::value, int, Value>::type;
using OptValueType = sqlpp::value_type_of_t<sqlpp::compat::optional<ValueType>>;
using OptFloat = sqlpp::value_type_of_t<sqlpp::compat::optional<float>>;
// Aggregate of non-nullable
static_assert(is_same_type<decltype(sum(v_not_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(avg(v_not_null)), OptFloat>::value, "");
// Aggregate of nullable
static_assert(is_same_type<decltype(sum(v_maybe_null)), OptValueType>::value, "");
static_assert(is_same_type<decltype(avg(v_maybe_null)), OptFloat>::value, "");
}
int main()
{
// boolean
test_aggregate_functions(bool{true});
test_numeric_aggregate_functions(bool{true});
// integral
test_aggregate_functions(int8_t{7});
@ -67,16 +85,29 @@ int main()
test_aggregate_functions(int32_t{7});
test_aggregate_functions(int64_t{7});
test_numeric_aggregate_functions(int8_t{7});
test_numeric_aggregate_functions(int16_t{7});
test_numeric_aggregate_functions(int32_t{7});
test_numeric_aggregate_functions(int64_t{7});
// unsigned integral
test_aggregate_functions(uint8_t{7});
test_aggregate_functions(uint16_t{7});
test_aggregate_functions(uint32_t{7});
test_aggregate_functions(uint64_t{7});
test_numeric_aggregate_functions(uint8_t{7});
test_numeric_aggregate_functions(uint16_t{7});
test_numeric_aggregate_functions(uint32_t{7});
test_numeric_aggregate_functions(uint64_t{7});
// floating point
test_aggregate_functions(float{7.7});
test_aggregate_functions(double{7.7});
test_numeric_aggregate_functions(float{7.7});
test_numeric_aggregate_functions(double{7.7});
// text
test_aggregate_functions('7');
test_aggregate_functions("seven");

View File

@ -41,8 +41,6 @@ namespace
template <typename Value>
void test_comparison_expression(Value v)
{
using OptValue = sqlpp::compat::optional<Value>;
auto v_not_null = sqlpp::value(v);
auto v_maybe_null = sqlpp::value(sqlpp::compat::make_optional(v));