mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 12:51:13 +08:00
More tests
This commit is contained in:
parent
e3f95a8e69
commit
8e688f3c34
@ -74,8 +74,9 @@ namespace sqlpp
|
||||
template <typename Context, typename Select>
|
||||
Context& serialize(Context& context, const any_t<Select>& t)
|
||||
{
|
||||
context << "ANY";
|
||||
serialize_operand(context, t._select);
|
||||
context << "ANY (";
|
||||
serialize(context, t._select);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct plus
|
||||
{
|
||||
static constexpr auto symbol = " + ";
|
||||
};
|
||||
|
||||
struct minus
|
||||
{
|
||||
static constexpr auto symbol = " - ";
|
||||
};
|
||||
|
||||
struct multiplies
|
||||
{
|
||||
static constexpr auto symbol = " * ";
|
||||
};
|
||||
|
||||
struct divides
|
||||
{
|
||||
static constexpr auto symbol = " / ";
|
||||
};
|
||||
|
||||
struct negate
|
||||
{
|
||||
static constexpr auto symbol = "-";
|
||||
};
|
||||
|
||||
struct modulus
|
||||
{
|
||||
static constexpr auto symbol = " % ";
|
||||
};
|
||||
|
||||
struct concatenation
|
||||
{
|
||||
static constexpr auto symbol = " || ";
|
||||
};
|
||||
|
||||
#warning: mysql does not offer operator||, we need to fail compilation, but maybe offer the concat function in addition
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct arithmetic_expression : public enable_as<arithmetic_expression<L, Operator, R>>,
|
||||
@ -59,20 +94,54 @@ namespace sqlpp
|
||||
using check_arithmetic_args = ::sqlpp::enable_if_t<is_numeric<L>::value and is_numeric<R>::value>;
|
||||
|
||||
#warning: need to document that this is on purpose (not integral, or unsigned integral, or floating_point) because it is difficult to know for the library to know what the actual result type will be (it is difficult to guess in C++ already, and it is probably different from DB vendor to vendor).
|
||||
namespace detail
|
||||
{
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct result_type
|
||||
{
|
||||
using type = numeric;
|
||||
};
|
||||
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct result_type<sqlpp::optional<L>, Operator, R> : public result_type<L, Operator, R>{};
|
||||
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct result_type<L, Operator, sqlpp::optional<R>> : public result_type<L, Operator, R>{};
|
||||
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct result_type<sqlpp::optional<L>, Operator, sqlpp::optional<R>> : public result_type<L, Operator, R>{};
|
||||
|
||||
template <typename ValueType>
|
||||
struct result_type<ValueType, plus, ValueType>
|
||||
{
|
||||
using type = ValueType;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct result_type<ValueType, multiplies, ValueType>
|
||||
{
|
||||
using type = ValueType;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct result_type<L, divides, R>
|
||||
{
|
||||
using type = floating_point;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct value_type_of<arithmetic_expression<L, Operator, R>>
|
||||
: public detail::result_type<value_type_of_t<L>, Operator, value_type_of_t<R>>
|
||||
/*
|
||||
: public std::conditional<sqlpp::is_optional<value_type_of_t<L>>::value or
|
||||
sqlpp::is_optional<value_type_of_t<R>>::value,
|
||||
::sqlpp::optional<numeric>,
|
||||
numeric>
|
||||
*/
|
||||
{
|
||||
};
|
||||
|
||||
struct concatenation
|
||||
{
|
||||
static constexpr auto symbol = " || ";
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
struct value_type_of<arithmetic_expression<L, concatenation, R>>
|
||||
: public std::conditional<sqlpp::is_optional<value_type_of_t<L>>::value or
|
||||
@ -100,11 +169,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
|
||||
struct plus
|
||||
{
|
||||
static constexpr auto symbol = " + ";
|
||||
};
|
||||
|
||||
template <typename L, typename R, typename = check_arithmetic_args<L, R>>
|
||||
constexpr auto operator+(L l, R r) -> arithmetic_expression<L, plus, R>
|
||||
{
|
||||
@ -120,55 +184,30 @@ namespace sqlpp
|
||||
return {std::move(l), std::move(r)};
|
||||
}
|
||||
|
||||
struct minus
|
||||
{
|
||||
static constexpr auto symbol = " - ";
|
||||
};
|
||||
|
||||
template <typename L, typename R, typename = check_arithmetic_args<L, R>>
|
||||
constexpr auto operator-(L l, R r) -> arithmetic_expression<L, minus, R>
|
||||
{
|
||||
return {std::move(l), std::move(r)};
|
||||
}
|
||||
|
||||
struct multiplies
|
||||
{
|
||||
static constexpr auto symbol = " * ";
|
||||
};
|
||||
|
||||
template <typename L, typename R, typename = check_arithmetic_args<L, R>>
|
||||
constexpr auto operator*(L l, R r) -> arithmetic_expression<L, multiplies, R>
|
||||
{
|
||||
return {std::move(l), std::move(r)};
|
||||
}
|
||||
|
||||
struct divides
|
||||
{
|
||||
static constexpr auto symbol = " / ";
|
||||
};
|
||||
|
||||
template <typename L, typename R, typename = check_arithmetic_args<L, R>>
|
||||
constexpr auto operator/(L l, R r) -> arithmetic_expression<L, divides, R>
|
||||
{
|
||||
return {std::move(l), std::move(r)};
|
||||
}
|
||||
|
||||
struct negate
|
||||
{
|
||||
static constexpr auto symbol = "-";
|
||||
};
|
||||
|
||||
template <typename R, typename = check_arithmetic_args<R, R>>
|
||||
constexpr auto operator-(R r) -> arithmetic_expression<noop, divides, R>
|
||||
constexpr auto operator-(R r) -> arithmetic_expression<noop, negate, R>
|
||||
{
|
||||
return {{}, std::move(r)};
|
||||
}
|
||||
|
||||
struct modulus
|
||||
{
|
||||
static constexpr auto symbol = " % ";
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
using check_modulus_args = ::sqlpp::enable_if_t<(is_integral<L>::value or is_unsigned_integral<L>::value) and (is_integral<R>::value or is_unsigned_integral<R>::value)>;
|
||||
|
||||
|
@ -70,13 +70,6 @@ namespace sqlpp
|
||||
template <typename L, typename R1, typename R2>
|
||||
struct requires_parentheses<between_expression<L, R1, R2>> : public std::true_type{};
|
||||
|
||||
#warning: Need tests for between expressions
|
||||
template <typename L, typename R1, typename R2, typename = check_between_args<L, R1, R2>>
|
||||
constexpr auto between(L l, R1 r1, R2 r2) -> between_expression<L, R1, R2>
|
||||
{
|
||||
return {std::move(l), std::move(r1), std::move(r2)};
|
||||
}
|
||||
|
||||
template <typename Context, typename L, typename R1, typename R2>
|
||||
auto serialize(Context& context, const between_expression<L, R1, R2>& t) -> Context&
|
||||
{
|
||||
@ -88,4 +81,10 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
|
||||
template <typename L, typename R1, typename R2, typename = check_between_args<L, R1, R2>>
|
||||
constexpr auto between(L l, R1 r1, R2 r2) -> between_expression<L, R1, R2>
|
||||
{
|
||||
return {std::move(l), std::move(r1), std::move(r2)};
|
||||
}
|
||||
|
||||
} // namespace sqlpp
|
||||
|
@ -124,7 +124,7 @@ namespace sqlpp
|
||||
template <typename R, typename = check_bit_expression_args<R, R>>
|
||||
constexpr auto operator~(R r) -> bit_expression<noop, bit_not, R>
|
||||
{
|
||||
return {std::move(r)};
|
||||
return {{}, std::move(r)};
|
||||
}
|
||||
|
||||
struct bit_shift_left
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015-2015, Roland Bock
|
||||
* Copyright (c) 2015, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -160,11 +160,11 @@ namespace sqlpp
|
||||
Context& serialize(Context& context, const case_t<When, Then, Else>& t)
|
||||
{
|
||||
context << "CASE WHEN ";
|
||||
serialize(context, t._when);
|
||||
serialize_operand(context, t._when);
|
||||
context << " THEN ";
|
||||
serialize(context, t._then);
|
||||
serialize_operand(context, t._then);
|
||||
context << " ELSE ";
|
||||
serialize(context, t._else);
|
||||
serialize_operand(context, t._else);
|
||||
context << " END";
|
||||
return context;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sqlpp11/core/operator/comparison_expression.h>
|
||||
#include <sqlpp11/core/operator/between_expression.h>
|
||||
#include <sqlpp11/core/operator/in_expression.h>
|
||||
#include <sqlpp11/core/operator/sort_order_expression.h>
|
||||
#include <sqlpp11/core/type_traits.h>
|
||||
@ -102,6 +103,12 @@ namespace sqlpp
|
||||
return ::sqlpp::is_not_distinct_from(this->derived(), std::move(r));
|
||||
}
|
||||
|
||||
template <typename R1, typename R2>
|
||||
constexpr auto between(R1 r1, R2 r2) const -> between_expression<Expr, R1, R2>
|
||||
{
|
||||
return ::sqlpp::between(this->derived(), std::move(r1), std::move(r2));
|
||||
}
|
||||
|
||||
constexpr auto asc() const -> sort_order_expression<Expr>
|
||||
{
|
||||
return ::sqlpp::asc(this->derived());
|
||||
|
@ -36,6 +36,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct operator_in
|
||||
{
|
||||
static constexpr auto symbol = " IN";
|
||||
};
|
||||
|
||||
struct operator_not_in
|
||||
{
|
||||
static constexpr auto symbol = " NOT IN";
|
||||
};
|
||||
|
||||
template<typename L, typename Operator, typename Container>
|
||||
struct in_expression : public enable_as<in_expression<L, Operator, Container>>
|
||||
{
|
||||
@ -111,7 +121,7 @@ namespace sqlpp
|
||||
auto serialize(Context& context, const in_expression<L, Operator, std::tuple<Args...>>& t) -> Context&
|
||||
{
|
||||
serialize_operand(context, t._l);
|
||||
context << Operator::symbol << "(";
|
||||
context << Operator::symbol << " (";
|
||||
if (sizeof...(Args) == 1)
|
||||
{
|
||||
serialize(context, std::get<0>(t._r));
|
||||
@ -119,7 +129,7 @@ namespace sqlpp
|
||||
else
|
||||
{
|
||||
#warning: interpret_tuple arguments should take Context first, too
|
||||
interpret_tuple(t._r, ',', context);
|
||||
interpret_tuple(t._r, ", ", context);
|
||||
}
|
||||
context << ')';
|
||||
return context;
|
||||
@ -133,12 +143,14 @@ namespace sqlpp
|
||||
{
|
||||
if (t._r.empty())
|
||||
{
|
||||
return serialize(context, false);
|
||||
// SQL would normally treat this as a bug in the query.
|
||||
// IN requires one parameter at least.
|
||||
// But the statement "L NOT IN empty_set" is true, so let's treat this as a bool result.
|
||||
return serialize(context, std::is_same<Operator, operator_not_in>::value);
|
||||
}
|
||||
serialize(context, t._l);
|
||||
context << Operator::symbol
|
||||
<< "(";
|
||||
bool first = true;
|
||||
context << Operator::symbol << " (";
|
||||
bool first = true;
|
||||
for (const auto& entry : t._r)
|
||||
{
|
||||
if (first)
|
||||
@ -147,20 +159,22 @@ namespace sqlpp
|
||||
}
|
||||
else
|
||||
{
|
||||
context << ',';
|
||||
context << ", ";
|
||||
}
|
||||
|
||||
serialize(context, entry);
|
||||
if (t._r.size() == 1) {
|
||||
// A single entry does not need extra parentheses.
|
||||
serialize(context, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize_operand(context, entry);
|
||||
}
|
||||
}
|
||||
context << ')';
|
||||
return context;
|
||||
}
|
||||
|
||||
struct operator_in
|
||||
{
|
||||
static constexpr auto symbol = " IN";
|
||||
};
|
||||
|
||||
#warning: something.in(select(...)); should be suppported as is, need to test
|
||||
template <typename L, typename... Args, typename = check_in_args<L, Args...>>
|
||||
constexpr auto in(L l, std::tuple<Args...> args) -> in_expression<L, operator_in, std::tuple<Args...>>
|
||||
@ -182,11 +196,6 @@ namespace sqlpp
|
||||
return {std::move(l), std::move(args)};
|
||||
}
|
||||
|
||||
struct operator_not_in
|
||||
{
|
||||
static constexpr auto symbol = " NOT IN";
|
||||
};
|
||||
|
||||
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...>>
|
||||
{
|
||||
|
@ -35,6 +35,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct logical_and
|
||||
{
|
||||
static constexpr auto symbol = " AND ";
|
||||
};
|
||||
|
||||
struct logical_or
|
||||
{
|
||||
static constexpr auto symbol = " OR ";
|
||||
};
|
||||
|
||||
template <typename L, typename Operator, typename R>
|
||||
struct logical_expression : public enable_as<logical_expression<L, Operator, R>>
|
||||
{
|
||||
@ -87,6 +97,16 @@ namespace sqlpp
|
||||
return serialize_impl(context, t);
|
||||
}
|
||||
|
||||
template <typename Context, typename L, typename Operator, typename R1, typename R2>
|
||||
auto serialize(Context& context,
|
||||
const logical_expression<logical_expression<L, Operator, R1>, Operator, R2>& t) -> Context&
|
||||
{
|
||||
serialize(context, t._l);
|
||||
context << Operator::symbol;
|
||||
serialize_operand(context, t._r);
|
||||
return context;
|
||||
}
|
||||
|
||||
template <typename Context, typename L, typename Operator, typename R>
|
||||
auto serialize(Context& context, const logical_expression<L, Operator, dynamic_t<R>>& t) -> Context&
|
||||
{
|
||||
@ -99,11 +119,6 @@ namespace sqlpp
|
||||
return serialize(context, t._l);
|
||||
}
|
||||
|
||||
struct logical_and
|
||||
{
|
||||
static constexpr auto symbol = " AND ";
|
||||
};
|
||||
|
||||
#warning: need tests with dynamic AND/OR
|
||||
template <typename L, typename R, typename = check_logical_args<L, remove_dynamic_t<R>>>
|
||||
constexpr auto operator and(L l, R r) -> logical_expression<L, logical_and, R>
|
||||
@ -111,11 +126,6 @@ namespace sqlpp
|
||||
return {std::move(l), std::move(r)};
|
||||
}
|
||||
|
||||
struct logical_or
|
||||
{
|
||||
static constexpr auto symbol = " OR ";
|
||||
};
|
||||
|
||||
template <typename L, typename R, typename = check_logical_args<L, remove_dynamic_t<R>>>
|
||||
constexpr auto operator||(L l, R r) -> logical_expression<L, logical_or, R>
|
||||
{
|
||||
|
@ -79,7 +79,21 @@ namespace sqlpp
|
||||
{
|
||||
if (t._condition)
|
||||
{
|
||||
serialize(context, t._expr);
|
||||
serialize(context, t._expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
serialize(context, ::sqlpp::nullopt);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
template <typename Context, typename Select>
|
||||
Context& serialize_operand(Context& context, const dynamic_t<Select>& t)
|
||||
{
|
||||
if (t._condition)
|
||||
{
|
||||
serialize_operand(context, t._expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -97,6 +111,12 @@ namespace sqlpp
|
||||
return {condition, std::move(t)};
|
||||
}
|
||||
|
||||
template <typename L, typename Operator, typename R, typename = check_dynamic_args<L>>
|
||||
auto dynamic(bool condition, assign_expression<L, Operator, R> t) -> dynamic_t<assign_expression<L, Operator, R>>
|
||||
{
|
||||
return {condition, std::move(t)};
|
||||
}
|
||||
|
||||
template <typename Expr, typename = check_dynamic_args<Expr>>
|
||||
auto dynamic(bool condition, sort_order_expression<Expr> t) -> dynamic_t<sort_order_expression<Expr>>
|
||||
{
|
||||
|
@ -32,8 +32,8 @@ int main(int, char* [])
|
||||
{
|
||||
const auto val = sqlpp::value(17);
|
||||
|
||||
SQLPP_COMPARE(any(select(val.as(v))), "ANY(SELECT 17 AS v)");
|
||||
SQLPP_COMPARE(val == any(select(val.as(v))), "17 = ANY(SELECT 17 AS v)");
|
||||
SQLPP_COMPARE(any(select(val.as(v))), "ANY (SELECT 17 AS v)");
|
||||
SQLPP_COMPARE(val == any(select(val.as(v))), "17 = ANY (SELECT 17 AS v)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,173 +23,51 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include "../../include/test_helpers.h"
|
||||
|
||||
namespace
|
||||
int main(int, char* [])
|
||||
{
|
||||
template<typename A, typename B>
|
||||
constexpr bool is_same_type()
|
||||
{
|
||||
return std::is_same<A, B>::value;
|
||||
}
|
||||
}
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
SQLPP_ALIAS_PROVIDER(r_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_maybe_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_opt_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_opt_maybe_null);
|
||||
|
||||
template<typename Value>
|
||||
void test_arithmetic_expressions(Value v)
|
||||
{
|
||||
using ValueType = sqlpp::numeric;
|
||||
using OptValueType = ::sqlpp::optional<sqlpp::numeric>;
|
||||
|
||||
auto value = sqlpp::value(v);
|
||||
auto opt_value = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Arithmetically combining non-optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + value)>, ValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value - value)>, ValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value * value)>, ValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value / value)>, ValueType>(), "");
|
||||
|
||||
// Arithmetically combining non-optional with optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + opt_value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value - opt_value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value * opt_value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value / opt_value)>, OptValueType>(), "");
|
||||
|
||||
// Arithmetically combining optional with non-optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value - value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value * value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value / value)>, OptValueType>(), "");
|
||||
|
||||
// Arithmetically combining optional with optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + opt_value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value - opt_value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value * opt_value)>, OptValueType>(), "");
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value / opt_value)>, OptValueType>(), "");
|
||||
|
||||
// Same with negate.
|
||||
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>(), "");
|
||||
|
||||
// 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>
|
||||
void test_modulus_expressions(Value v)
|
||||
{
|
||||
using ValueType = sqlpp::numeric;
|
||||
using OptValueType = ::sqlpp::optional<sqlpp::numeric>;
|
||||
|
||||
auto value = sqlpp::value(v);
|
||||
auto opt_value = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Modulus combining non-optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value % value)>, ValueType>(), "");
|
||||
|
||||
// Modulus combining non-optional with optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value % opt_value)>, OptValueType>(), "");
|
||||
|
||||
// Modulus combining optional with non-optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value % value)>, OptValueType>(), "");
|
||||
|
||||
// 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>
|
||||
void test_concatenation_expressions(Value v)
|
||||
{
|
||||
using ValueType = sqlpp::text;
|
||||
using OptValueType = ::sqlpp::optional<sqlpp::text>;
|
||||
|
||||
auto value = sqlpp::value(v);
|
||||
auto opt_value = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Concatenating non-optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + value)>, ValueType>(), "");
|
||||
|
||||
// Concatenating non-optional with optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(value + opt_value)>, OptValueType>(), "");
|
||||
|
||||
// Concatenating optional with non-optional values
|
||||
static_assert(is_same_type<sqlpp::value_type_of_t<decltype(opt_value + value)>, OptValueType>(), "");
|
||||
|
||||
// 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()
|
||||
{
|
||||
// integral
|
||||
test_arithmetic_expressions(int8_t{7});
|
||||
test_arithmetic_expressions(int16_t{7});
|
||||
test_arithmetic_expressions(int32_t{7});
|
||||
test_arithmetic_expressions(int64_t{7});
|
||||
test_modulus_expressions(int8_t{7});
|
||||
test_modulus_expressions(int16_t{7});
|
||||
test_modulus_expressions(int32_t{7});
|
||||
test_modulus_expressions(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_arithmetic_expressions(uint8_t{7});
|
||||
test_arithmetic_expressions(uint16_t{7});
|
||||
test_arithmetic_expressions(uint32_t{7});
|
||||
test_arithmetic_expressions(uint64_t{7});
|
||||
test_modulus_expressions(uint8_t{7});
|
||||
test_modulus_expressions(uint16_t{7});
|
||||
test_modulus_expressions(uint32_t{7});
|
||||
test_modulus_expressions(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_arithmetic_expressions(float{7.7});
|
||||
test_arithmetic_expressions(double{7.7});
|
||||
|
||||
// text
|
||||
test_concatenation_expressions('7');
|
||||
test_concatenation_expressions("seven");
|
||||
test_concatenation_expressions(std::string("seven"));
|
||||
test_concatenation_expressions(::sqlpp::string_view("seven"));
|
||||
const auto val = sqlpp::value(1);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
// Operands are enclosed in parenheses where required.
|
||||
SQLPP_COMPARE(val + val, "1 + 1");
|
||||
SQLPP_COMPARE(val - val, "1 - 1");
|
||||
SQLPP_COMPARE(val * val, "1 * 1");
|
||||
SQLPP_COMPARE(val / val, "1 / 1");
|
||||
SQLPP_COMPARE(val % val, "1 % 1");
|
||||
|
||||
SQLPP_COMPARE(val + expr, "1 + (17 + 4)");
|
||||
SQLPP_COMPARE(val - expr, "1 - (17 + 4)");
|
||||
SQLPP_COMPARE(val * expr, "1 * (17 + 4)");
|
||||
SQLPP_COMPARE(val / expr, "1 / (17 + 4)");
|
||||
SQLPP_COMPARE(val % expr, "1 % (17 + 4)");
|
||||
|
||||
SQLPP_COMPARE(expr + val, "(17 + 4) + 1");
|
||||
SQLPP_COMPARE(expr - val, "(17 + 4) - 1");
|
||||
SQLPP_COMPARE(expr * val, "(17 + 4) * 1");
|
||||
SQLPP_COMPARE(expr / val, "(17 + 4) / 1");
|
||||
SQLPP_COMPARE(expr % val, "(17 + 4) % 1");
|
||||
|
||||
SQLPP_COMPARE(expr + expr, "(17 + 4) + (17 + 4)");
|
||||
SQLPP_COMPARE(expr - expr, "(17 + 4) - (17 + 4)");
|
||||
SQLPP_COMPARE(expr * expr, "(17 + 4) * (17 + 4)");
|
||||
SQLPP_COMPARE(expr / expr, "(17 + 4) / (17 + 4)");
|
||||
SQLPP_COMPARE(expr % expr, "(17 + 4) % (17 + 4)");
|
||||
|
||||
// Same for unary expressions.
|
||||
SQLPP_COMPARE(-val, "-1");
|
||||
SQLPP_COMPARE(-expr, "-(17 + 4)");
|
||||
|
||||
const auto text = sqlpp::value("a");
|
||||
const auto text_expr = sqlpp::value("b") + "c";
|
||||
|
||||
// Same for concatenation.
|
||||
SQLPP_COMPARE(text + text, "'a' || 'a'");
|
||||
SQLPP_COMPARE(text + text_expr, "'a' || ('b' || 'c')");
|
||||
SQLPP_COMPARE(text_expr + text, "('b' || 'c') || 'a'");
|
||||
SQLPP_COMPARE(text_expr + text_expr, "('b' || 'c') || ('b' || 'c')");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,96 +23,24 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
SQLPP_ALIAS_PROVIDER(cheese);
|
||||
SQLPP_ALIAS_PROVIDER(v);
|
||||
|
||||
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)
|
||||
int main(int, char* [])
|
||||
{
|
||||
using ValueType = sqlpp::value_type_of_t<Value>;
|
||||
using OptValueType = ::sqlpp::optional<ValueType>;
|
||||
const auto val = sqlpp::value(17);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(::sqlpp::make_optional(v));
|
||||
auto v_dynamic_not_null = dynamic(true, sqlpp::value(v));
|
||||
auto v_dynamic_maybe_null = dynamic(true, sqlpp::value(::sqlpp::make_optional(v)));
|
||||
SQLPP_COMPARE(val.as(v), "17 AS v");
|
||||
SQLPP_COMPARE(expr.as(v), "(17 + 4) AS 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, "");
|
||||
SQLPP_COMPARE(dynamic(true, val).as(v), "17 AS v");
|
||||
SQLPP_COMPARE(dynamic(true, expr).as(v), "(17 + 4) AS v");
|
||||
|
||||
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, "");
|
||||
SQLPP_COMPARE(dynamic(false, val).as(v), "NULL AS v");
|
||||
SQLPP_COMPARE(dynamic(false, expr).as(v), "NULL AS v");
|
||||
|
||||
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, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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::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{});
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,110 +23,26 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "MockDb.h"
|
||||
#include "../compare.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
namespace
|
||||
int main(int, char* [])
|
||||
{
|
||||
auto db = MockDb{};
|
||||
constexpr auto t = test::TabFoo{};
|
||||
const auto val = sqlpp::value(17);
|
||||
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
// Operands in assignments are enclosed in parentheses as required.
|
||||
SQLPP_COMPARE(t.id = val, "id = 17");
|
||||
SQLPP_COMPARE(t.id = val + 4, "id = (17 + 4)");
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::boolean>>;
|
||||
// Active dynamic assignments are just as above.
|
||||
SQLPP_COMPARE(dynamic(true, t.id = val), "id = 17");
|
||||
SQLPP_COMPARE(dynamic(true, t.id = val + 4), "id = (17 + 4)");
|
||||
|
||||
// This should be skipped by insert and update and should therefore never be called.
|
||||
SQLPP_COMPARE(dynamic(false, t.id = val), "NULL");
|
||||
SQLPP_COMPARE(dynamic(false, t.id = val + 4), "NULL");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Column, typename Value>
|
||||
void test_assign_expression(const Column& col, const Value& v)
|
||||
{
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
using ValueType = decltype(v_not_null);
|
||||
using OptValueType = decltype(v_maybe_null);
|
||||
|
||||
// Assignments have no value
|
||||
static_assert(not sqlpp::has_value_type<decltype(col = sqlpp::default_value)>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(col = v_not_null)>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(col = v_maybe_null)>::value, "");
|
||||
|
||||
// Assignments have no name
|
||||
static_assert(not sqlpp::has_name<decltype(col = sqlpp::default_value)>::value, "");
|
||||
static_assert(not sqlpp::has_name<decltype(col = v_not_null)>::value, "");
|
||||
static_assert(not sqlpp::has_name<decltype(col = v_maybe_null)>::value, "");
|
||||
|
||||
// Assignment nodes
|
||||
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = sqlpp::default_value)>,
|
||||
sqlpp::detail::type_vector<Column, sqlpp::default_value_t>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = v_not_null)>,
|
||||
sqlpp::detail::type_vector<Column, ValueType>>::value,
|
||||
"");
|
||||
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(col = v_maybe_null)>,
|
||||
sqlpp::detail::type_vector<Column, OptValueType>>::value,
|
||||
"");
|
||||
|
||||
// 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
|
||||
#warning: test that non-default columns cannot be assigned to default_value
|
||||
|
||||
int main()
|
||||
{
|
||||
const auto bar = test::TabBar{};
|
||||
const auto foo = test::TabFoo{};
|
||||
const auto date_time = test::TabDateTime{};
|
||||
|
||||
// boolean
|
||||
test_assign_expression(foo.boolN, bool{true});
|
||||
|
||||
// integral
|
||||
test_assign_expression(foo.intN, int8_t{7});
|
||||
test_assign_expression(foo.intN, int16_t{7});
|
||||
test_assign_expression(foo.intN, int32_t{7});
|
||||
test_assign_expression(foo.intN, int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_assign_expression(foo.uIntN, uint8_t{7});
|
||||
test_assign_expression(foo.uIntN, uint16_t{7});
|
||||
test_assign_expression(foo.uIntN, uint32_t{7});
|
||||
test_assign_expression(foo.uIntN, uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_assign_expression(foo.doubleN, float{7.7});
|
||||
test_assign_expression(foo.doubleN, double{7.7});
|
||||
|
||||
// text
|
||||
test_assign_expression(bar.textN, '7');
|
||||
test_assign_expression(bar.textN, "seven");
|
||||
test_assign_expression(bar.textN, std::string("seven"));
|
||||
test_assign_expression(bar.textN, ::sqlpp::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_assign_expression(foo.blobN, std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_assign_expression(date_time.dayPointN, ::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_assign_expression(date_time.timePointN, ::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_assign_expression(date_time.timePointN, minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_assign_expression(date_time.timeOfDayN, std::chrono::microseconds{});
|
||||
}
|
||||
|
||||
|
@ -23,91 +23,24 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
namespace
|
||||
int main(int, char* [])
|
||||
{
|
||||
auto db = MockDb{};
|
||||
const auto val = sqlpp::value(1);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
// Operands are enclosed in parenheses where required
|
||||
SQLPP_COMPARE(val.between(val, val), "1 BETWEEN 1 AND 1");
|
||||
SQLPP_COMPARE(val.between(val, expr), "1 BETWEEN 1 AND (17 + 4)");
|
||||
SQLPP_COMPARE(val.between(expr, val), "1 BETWEEN (17 + 4) AND 1");
|
||||
SQLPP_COMPARE(val.between(expr, expr), "1 BETWEEN (17 + 4) AND (17 + 4)");
|
||||
SQLPP_COMPARE(expr.between(val, val), "(17 + 4) BETWEEN 1 AND 1");
|
||||
SQLPP_COMPARE(expr.between(val, expr), "(17 + 4) BETWEEN 1 AND (17 + 4)");
|
||||
SQLPP_COMPARE(expr.between(expr, val), "(17 + 4) BETWEEN (17 + 4) AND 1");
|
||||
SQLPP_COMPARE(expr.between(expr, expr), "(17 + 4) BETWEEN (17 + 4) AND (17 + 4)");
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::boolean>>;
|
||||
SQLPP_COMPARE(val.between(val, val) and true, "(1 BETWEEN 1 AND 1) AND 1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_between_expression(Value v)
|
||||
{
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Variations of nullable and non-nullable values
|
||||
static_assert(is_bool<decltype(between(v_not_null, v_not_null, v_not_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_not_null, v_not_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_not_null, v_maybe_null, v_not_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_not_null, v_maybe_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_not_null, v_not_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_not_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_maybe_null, v_not_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(between(v_maybe_null, v_maybe_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Between expressions have the `as` member function.
|
||||
static_assert(sqlpp::has_enabled_as<decltype(between(v_not_null, v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Between expressions do not enable comparison member functions.
|
||||
static_assert(not sqlpp::has_enabled_comparison<decltype(between(v_not_null, v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Between expressions have their arguments as nodes.
|
||||
using L = typename std::decay<decltype(v_not_null)>::type;
|
||||
using M = Value;
|
||||
using R = typename std::decay<decltype(v_maybe_null)>::type;
|
||||
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(between(v_not_null, v, v_maybe_null))>, sqlpp::detail::type_vector<L, M, R>>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_between_expression(bool{true});
|
||||
|
||||
// integral
|
||||
test_between_expression(int8_t{7});
|
||||
test_between_expression(int16_t{7});
|
||||
test_between_expression(int32_t{7});
|
||||
test_between_expression(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_between_expression(uint8_t{7});
|
||||
test_between_expression(uint16_t{7});
|
||||
test_between_expression(uint32_t{7});
|
||||
test_between_expression(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_between_expression(float{7.7});
|
||||
test_between_expression(double{7.7});
|
||||
|
||||
// text
|
||||
test_between_expression('7');
|
||||
test_between_expression("seven");
|
||||
test_between_expression(std::string("seven"));
|
||||
test_between_expression(::sqlpp::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_between_expression(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_between_expression(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_between_expression(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_between_expression(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_between_expression(std::chrono::microseconds{});
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,123 +23,42 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
namespace
|
||||
int main(int, char* [])
|
||||
{
|
||||
auto db = MockDb{};
|
||||
const auto val = sqlpp::value(1);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
template <typename T>
|
||||
using is_integral = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::integral>;
|
||||
// Operands are enclosed in parentheses where required.
|
||||
SQLPP_COMPARE(val & val, "1 & 1");
|
||||
SQLPP_COMPARE(val | val, "1 | 1");
|
||||
SQLPP_COMPARE(val ^ val, "1 ^ 1");
|
||||
SQLPP_COMPARE(val << val, "1 << 1");
|
||||
SQLPP_COMPARE(val >> val, "1 >> 1");
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_integral = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::integral>>;
|
||||
SQLPP_COMPARE(val & expr, "1 & (17 + 4)");
|
||||
SQLPP_COMPARE(val | expr, "1 | (17 + 4)");
|
||||
SQLPP_COMPARE(val ^ expr, "1 ^ (17 + 4)");
|
||||
SQLPP_COMPARE(val << expr, "1 << (17 + 4)");
|
||||
SQLPP_COMPARE(val >> expr, "1 >> (17 + 4)");
|
||||
|
||||
SQLPP_COMPARE(expr & val, "(17 + 4) & 1");
|
||||
SQLPP_COMPARE(expr | val, "(17 + 4) | 1");
|
||||
SQLPP_COMPARE(expr ^ val, "(17 + 4) ^ 1");
|
||||
SQLPP_COMPARE(expr << val, "(17 + 4) << 1");
|
||||
SQLPP_COMPARE(expr >> val, "(17 + 4) >> 1");
|
||||
|
||||
SQLPP_COMPARE(expr & expr, "(17 + 4) & (17 + 4)");
|
||||
SQLPP_COMPARE(expr | expr, "(17 + 4) | (17 + 4)");
|
||||
SQLPP_COMPARE(expr ^ expr, "(17 + 4) ^ (17 + 4)");
|
||||
SQLPP_COMPARE(expr << expr, "(17 + 4) << (17 + 4)");
|
||||
SQLPP_COMPARE(expr >> expr, "(17 + 4) >> (17 + 4)");
|
||||
|
||||
// Same for unary operators
|
||||
SQLPP_COMPARE(~val, "~1");
|
||||
SQLPP_COMPARE(~expr, "~(17 + 4)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_bit_expression(Value v)
|
||||
{
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_integral<decltype(v_not_null << v_not_null)>::value, "");
|
||||
static_assert(is_integral<decltype(v_not_null >> v_not_null)>::value, "");
|
||||
static_assert(is_integral<decltype(v_not_null | v_not_null)>::value, "");
|
||||
static_assert(is_integral<decltype(v_not_null & v_not_null)>::value, "");
|
||||
static_assert(is_integral<decltype(v_not_null ^ v_not_null)>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_integral<decltype(v_not_null << v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_not_null >> v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_not_null | v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_not_null & v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_not_null ^ v_maybe_null)>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null << v_not_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null >> v_not_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null | v_not_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null & v_not_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null ^ v_not_null)>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null << v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null >> v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null | v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null & v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(v_maybe_null ^ v_maybe_null)>::value, "");
|
||||
|
||||
// Compare with null.
|
||||
static_assert(is_integral<decltype(~v_not_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(~v_maybe_null)>::value, "");
|
||||
|
||||
// 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(~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(~v_not_null)>, sqlpp::detail::type_vector<sqlpp::noop, L>>::value, "");
|
||||
}
|
||||
|
||||
template <typename Left, typename Right>
|
||||
void test_bit_shift_expression(Left l, Right r)
|
||||
{
|
||||
auto l_not_null = sqlpp::value(l);
|
||||
auto l_maybe_null = sqlpp::value(::sqlpp::make_optional(l));
|
||||
auto r_not_null = sqlpp::value(r);
|
||||
auto r_maybe_null = sqlpp::value(::sqlpp::make_optional(r));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_integral<decltype(l_not_null << r_not_null)>::value, "");
|
||||
static_assert(is_integral<decltype(l_not_null >> r_not_null)>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_integral<decltype(l_not_null << r_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(l_not_null >> r_maybe_null)>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_integral<decltype(l_maybe_null << r_not_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(l_maybe_null >> r_not_null)>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_integral<decltype(l_maybe_null << r_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_integral<decltype(l_maybe_null >> r_maybe_null)>::value, "");
|
||||
|
||||
// Comparison expressions have the `as` member function.
|
||||
static_assert(sqlpp::has_enabled_as<decltype(l_not_null << r_maybe_null)>::value, "");
|
||||
|
||||
// Comparison expressions do not enable comparison member functions.
|
||||
static_assert(not sqlpp::has_enabled_comparison<decltype(l_not_null << r_maybe_null)>::value, "");
|
||||
|
||||
// Comparison expressions have their arguments as nodes.
|
||||
using L = typename std::decay<decltype(l_not_null)>::type;
|
||||
using R = typename std::decay<decltype(r_maybe_null)>::type;
|
||||
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(l_not_null << r_maybe_null)>, sqlpp::detail::type_vector<L, R>>::value, "");
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// bit expression require integral operands
|
||||
test_bit_expression(int8_t{7});
|
||||
test_bit_expression(int16_t{7});
|
||||
test_bit_expression(int32_t{7});
|
||||
test_bit_expression(int64_t{7});
|
||||
|
||||
// bit shift operations can have unsigned rhs operands
|
||||
test_bit_shift_expression(int8_t{7}, uint8_t{7});
|
||||
test_bit_shift_expression(int8_t{7}, uint16_t{7});
|
||||
test_bit_shift_expression(int8_t{7}, uint32_t{7});
|
||||
test_bit_shift_expression(int8_t{7}, uint64_t{7});
|
||||
}
|
||||
|
||||
|
@ -23,90 +23,26 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
template<typename T, typename Value>
|
||||
using is_same_type = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::value_type_of_t<Value>>;
|
||||
SQLPP_ALIAS_PROVIDER(v);
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
template <typename Value>
|
||||
void test_case_expression(Value v)
|
||||
int main(int, char* [])
|
||||
{
|
||||
auto c_not_null = sqlpp::value(true);
|
||||
auto c_maybe_null = sqlpp::value(::sqlpp::make_optional(false));
|
||||
const auto cond = sqlpp::value(true);
|
||||
const auto val = sqlpp::value(11);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
|
||||
// Case operands use parentheses where required.
|
||||
SQLPP_COMPARE(case_when(cond).then(val).else_(val), "CASE WHEN 1 THEN 11 ELSE 11 END");
|
||||
SQLPP_COMPARE(case_when(cond).then(val).else_(expr), "CASE WHEN 1 THEN 11 ELSE (17 + 4) END");
|
||||
SQLPP_COMPARE(case_when(cond).then(expr).else_(val), "CASE WHEN 1 THEN (17 + 4) ELSE 11 END");
|
||||
SQLPP_COMPARE(case_when(cond).then(expr).else_(expr), "CASE WHEN 1 THEN (17 + 4) ELSE (17 + 4) END");
|
||||
SQLPP_COMPARE(case_when(false or cond).then(val).else_(val), "CASE WHEN (0 OR 1) THEN 11 ELSE 11 END");
|
||||
SQLPP_COMPARE(case_when(false or cond).then(val).else_(expr), "CASE WHEN (0 OR 1) THEN 11 ELSE (17 + 4) END");
|
||||
SQLPP_COMPARE(case_when(false or cond).then(expr).else_(val), "CASE WHEN (0 OR 1) THEN (17 + 4) ELSE 11 END");
|
||||
SQLPP_COMPARE(case_when(false or cond).then(expr).else_(expr), "CASE WHEN (0 OR 1) THEN (17 + 4) ELSE (17 + 4) END");
|
||||
|
||||
using ValueType = sqlpp::value_type_of_t<decltype(v_not_null)>;
|
||||
using OptValueType = sqlpp::value_type_of_t<decltype(v_maybe_null)>;
|
||||
|
||||
// Variations of nullable and non-nullable values
|
||||
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_not_null).else_(v_not_null)), ValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_not_null).else_(v_maybe_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_maybe_null).else_(v_not_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_not_null).then(v_maybe_null).else_(v_maybe_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_not_null).else_(v_not_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_not_null).else_(v_maybe_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_maybe_null).else_(v_not_null)), OptValueType>::value, "");
|
||||
static_assert(is_same_type<decltype(case_when(c_maybe_null).then(v_maybe_null).else_(v_maybe_null)), OptValueType>::value, "");
|
||||
|
||||
// Incomplete case expressions have no value.
|
||||
static_assert(not sqlpp::has_value_type<decltype(case_when(c_not_null))>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(case_when(c_not_null).then(v_not_null))>::value, "");
|
||||
|
||||
// Case expressions have the `as` member function.
|
||||
static_assert(sqlpp::has_enabled_as<decltype(case_when(c_not_null).then(v_not_null).else_(v_not_null))>::value, "");
|
||||
|
||||
// Case expressions enable comparison member functions.
|
||||
static_assert(sqlpp::has_enabled_comparison<decltype(case_when(c_not_null).then(v_not_null).else_(v_not_null))>::value, "");
|
||||
|
||||
// Between expressions have their arguments as nodes.
|
||||
using L = typename std::decay<decltype(c_not_null)>::type;
|
||||
using M = 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(case_when(c_not_null).then(v_not_null).else_(v_maybe_null))>, sqlpp::detail::type_vector<L, M, R>>::value, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_case_expression(bool{true});
|
||||
|
||||
// integral
|
||||
test_case_expression(int8_t{7});
|
||||
test_case_expression(int16_t{7});
|
||||
test_case_expression(int32_t{7});
|
||||
test_case_expression(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_case_expression(uint8_t{7});
|
||||
test_case_expression(uint16_t{7});
|
||||
test_case_expression(uint32_t{7});
|
||||
test_case_expression(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_case_expression(float{7.7});
|
||||
test_case_expression(double{7.7});
|
||||
|
||||
// text
|
||||
test_case_expression('7');
|
||||
test_case_expression("seven");
|
||||
test_case_expression(std::string("seven"));
|
||||
test_case_expression(::sqlpp::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_case_expression(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_case_expression(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_case_expression(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_case_expression(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_case_expression(std::chrono::microseconds{});
|
||||
}
|
||||
|
||||
|
@ -23,159 +23,57 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "MockDb.h"
|
||||
#include "Sample.h"
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
namespace
|
||||
int main(int, char* [])
|
||||
{
|
||||
auto db = MockDb{};
|
||||
const auto val = sqlpp::value(1);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
// Operands are enclosed in parentheses where required.
|
||||
SQLPP_COMPARE(val < val, "1 < 1");
|
||||
SQLPP_COMPARE(val <= val, "1 <= 1");
|
||||
SQLPP_COMPARE(val == val, "1 = 1");
|
||||
SQLPP_COMPARE(val != val, "1 <> 1");
|
||||
SQLPP_COMPARE(val >= val, "1 >= 1");
|
||||
SQLPP_COMPARE(val > val, "1 > 1");
|
||||
SQLPP_COMPARE(val.is_distinct_from(val), "1 IS DISTINCT FROM 1");
|
||||
SQLPP_COMPARE(val.is_not_distinct_from(val), "1 IS NOT DISTINCT FROM 1");
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::boolean>>;
|
||||
SQLPP_COMPARE(val < expr, "1 < (17 + 4)");
|
||||
SQLPP_COMPARE(val <= expr, "1 <= (17 + 4)");
|
||||
SQLPP_COMPARE(val == expr, "1 = (17 + 4)");
|
||||
SQLPP_COMPARE(val != expr, "1 <> (17 + 4)");
|
||||
SQLPP_COMPARE(val >= expr, "1 >= (17 + 4)");
|
||||
SQLPP_COMPARE(val > expr, "1 > (17 + 4)");
|
||||
SQLPP_COMPARE(val.is_distinct_from(expr), "1 IS DISTINCT FROM (17 + 4)");
|
||||
SQLPP_COMPARE(val.is_not_distinct_from(expr), "1 IS NOT DISTINCT FROM (17 + 4)");
|
||||
|
||||
SQLPP_COMPARE(expr < val, "(17 + 4) < 1");
|
||||
SQLPP_COMPARE(expr <= val, "(17 + 4) <= 1");
|
||||
SQLPP_COMPARE(expr == val, "(17 + 4) = 1");
|
||||
SQLPP_COMPARE(expr != val, "(17 + 4) <> 1");
|
||||
SQLPP_COMPARE(expr >= val, "(17 + 4) >= 1");
|
||||
SQLPP_COMPARE(expr > val, "(17 + 4) > 1");
|
||||
SQLPP_COMPARE(expr.is_distinct_from(val), "(17 + 4) IS DISTINCT FROM 1");
|
||||
SQLPP_COMPARE(expr.is_not_distinct_from(val), "(17 + 4) IS NOT DISTINCT FROM 1");
|
||||
|
||||
SQLPP_COMPARE(expr < expr, "(17 + 4) < (17 + 4)");
|
||||
SQLPP_COMPARE(expr <= expr, "(17 + 4) <= (17 + 4)");
|
||||
SQLPP_COMPARE(expr == expr, "(17 + 4) = (17 + 4)");
|
||||
SQLPP_COMPARE(expr != expr, "(17 + 4) <> (17 + 4)");
|
||||
SQLPP_COMPARE(expr >= expr, "(17 + 4) >= (17 + 4)");
|
||||
SQLPP_COMPARE(expr > expr, "(17 + 4) > (17 + 4)");
|
||||
SQLPP_COMPARE(expr.is_distinct_from(expr), "(17 + 4) IS DISTINCT FROM (17 + 4)");
|
||||
SQLPP_COMPARE(expr.is_not_distinct_from(expr), "(17 + 4) IS NOT DISTINCT FROM (17 + 4)");
|
||||
|
||||
// Same for unary operators
|
||||
SQLPP_COMPARE(val.is_null(), "1 IS NULL");
|
||||
SQLPP_COMPARE(val.is_not_null(), "1 IS NOT NULL");
|
||||
|
||||
SQLPP_COMPARE(expr.is_null(), "(17 + 4) IS NULL");
|
||||
SQLPP_COMPARE(expr.is_not_null(), "(17 + 4) IS NOT NULL");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_comparison_expression(Value v)
|
||||
{
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
#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, "");
|
||||
static_assert(is_bool<decltype(v_not_null <= v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null == v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null != v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null == v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null >= v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(v_not_null > v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_not_null, v_not_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_not_null < v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null <= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null != v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null >= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_not_null > v_maybe_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_not_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_not_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null < v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null <= v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null != v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null >= v_not_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null > v_not_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_maybe_null, v_not_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_maybe_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null < v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null <= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null != v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null == v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null >= v_maybe_null)>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null > v_maybe_null)>::value, "");
|
||||
static_assert(is_bool<decltype(is_distinct_from(v_maybe_null, v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_distinct_from(v_maybe_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare with null.
|
||||
static_assert(is_bool<decltype(is_null(v_not_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_null(v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_null(v_maybe_null))>::value, "");
|
||||
static_assert(is_bool<decltype(is_not_null(v_not_null))>::value, "");
|
||||
|
||||
// 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::nullopt_t>>::value, "");
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
void test_like(Value v)
|
||||
{
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(like(v_not_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_not_null, v_maybe_null))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_not_null))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(like(v_maybe_null, v_maybe_null))>::value, "");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_comparison_expression(bool{true});
|
||||
|
||||
// integral
|
||||
test_comparison_expression(int8_t{7});
|
||||
test_comparison_expression(int16_t{7});
|
||||
test_comparison_expression(int32_t{7});
|
||||
test_comparison_expression(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_comparison_expression(uint8_t{7});
|
||||
test_comparison_expression(uint16_t{7});
|
||||
test_comparison_expression(uint32_t{7});
|
||||
test_comparison_expression(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_comparison_expression(float{7.7});
|
||||
test_comparison_expression(double{7.7});
|
||||
|
||||
// text
|
||||
test_comparison_expression('7');
|
||||
test_comparison_expression("seven");
|
||||
test_comparison_expression(std::string("seven"));
|
||||
test_comparison_expression(::sqlpp::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_comparison_expression(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_comparison_expression(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_comparison_expression(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_comparison_expression(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_comparison_expression(std::chrono::microseconds{});
|
||||
|
||||
// text
|
||||
test_like('7');
|
||||
test_like("seven");
|
||||
test_like(std::string("seven"));
|
||||
test_like(::sqlpp::string_view("seven"));
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,75 +23,16 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
SQLPP_ALIAS_PROVIDER(r_not_null);
|
||||
SQLPP_ALIAS_PROVIDER(r_maybe_null);
|
||||
SQLPP_ALIAS_PROVIDER(v);
|
||||
|
||||
template <typename Value>
|
||||
void test_exists(Value v)
|
||||
int main(int, char* [])
|
||||
{
|
||||
// Selectable values.
|
||||
const auto v_not_null = sqlpp::value(v).as(r_not_null);
|
||||
const auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v)).as(r_maybe_null);
|
||||
const auto val = sqlpp::value(17);
|
||||
|
||||
// EXISTS expression can be used in basic comparison expressions, which use remove_exists_t to look inside.
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(exists(select(v_not_null)))>, sqlpp::boolean>::value, "");
|
||||
static_assert(std::is_same<sqlpp::value_type_of_t<decltype(exists(select(v_maybe_null)))>, sqlpp::boolean>::value, "");
|
||||
SQLPP_COMPARE(exists(select(val.as(v))), "EXISTS (SELECT 17 AS v)");
|
||||
|
||||
// EXISTS expressions enable `as` member function.
|
||||
static_assert(sqlpp::has_enabled_as<decltype(exists(select(v_not_null)))>::value, "");
|
||||
|
||||
// EXISTS expressions do not enable comparison member functions.
|
||||
static_assert(not sqlpp::has_enabled_comparison<decltype(exists(select(v_not_null)))>::value, "");
|
||||
|
||||
// EXISTS expressions have the SELECT as node.
|
||||
using S = decltype(select(v_not_null));
|
||||
static_assert(std::is_same<sqlpp::nodes_of_t<decltype(exists(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.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// boolean
|
||||
test_exists(bool{true});
|
||||
|
||||
// integral
|
||||
test_exists(int8_t{7});
|
||||
test_exists(int16_t{7});
|
||||
test_exists(int32_t{7});
|
||||
test_exists(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_exists(uint8_t{7});
|
||||
test_exists(uint16_t{7});
|
||||
test_exists(uint32_t{7});
|
||||
test_exists(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_exists(float{7.7});
|
||||
test_exists(double{7.7});
|
||||
|
||||
// text
|
||||
test_exists('7');
|
||||
test_exists("seven");
|
||||
test_exists(std::string("seven"));
|
||||
test_exists(::sqlpp::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_exists(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_exists(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_exists(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_exists(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_exists(std::chrono::microseconds{});
|
||||
}
|
||||
|
||||
|
@ -23,101 +23,38 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
namespace
|
||||
SQLPP_ALIAS_PROVIDER(v);
|
||||
|
||||
int main(int, char* [])
|
||||
{
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
const auto val = sqlpp::value(17);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
using expr_t = typename std::decay<decltype(expr)>::type;
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::boolean>>;
|
||||
// IN expression with single select or other singe expression: No extra parentheses.
|
||||
SQLPP_COMPARE(val.in(val), "17 IN (17)");
|
||||
SQLPP_COMPARE(val.in(expr), "17 IN (17 + 4)");
|
||||
SQLPP_COMPARE(val.in(select(val.as(v))), "17 IN (SELECT 17 AS v)");
|
||||
|
||||
SQLPP_COMPARE(val.not_in(val), "17 NOT IN (17)");
|
||||
SQLPP_COMPARE(val.not_in(expr), "17 NOT IN (17 + 4)");
|
||||
SQLPP_COMPARE(val.not_in(select(val.as(v))), "17 NOT IN (SELECT 17 AS v)");
|
||||
|
||||
// IN expressions with multiple arguments require inner parentheses.
|
||||
SQLPP_COMPARE(val.in(1, select(val.as(v))), "17 IN (1, (SELECT 17 AS v))");
|
||||
SQLPP_COMPARE(val.in(std::vector<int>{17, 18, 19}), "17 IN (17, 18, 19)");
|
||||
SQLPP_COMPARE(val.in(std::vector<expr_t>{expr, expr, expr}), "17 IN ((17 + 4), (17 + 4), (17 + 4))");
|
||||
|
||||
SQLPP_COMPARE(val.not_in(1, select(val.as(v))), "17 NOT IN (1, (SELECT 17 AS v))");
|
||||
SQLPP_COMPARE(val.not_in(std::vector<int>{17, 18, 19}), "17 NOT IN (17, 18, 19)");
|
||||
SQLPP_COMPARE(val.not_in(std::vector<expr_t>{expr, expr, expr}), "17 NOT IN ((17 + 4), (17 + 4), (17 + 4))");
|
||||
|
||||
// IN expressions with no arguments would be an error in SQL, but the library interprets the intent gracefully.
|
||||
SQLPP_COMPARE(val.in(std::vector<expr_t>{}), "0");
|
||||
SQLPP_COMPARE(val.not_in(std::vector<expr_t>{}), "1");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
void test_in_expression(Value v)
|
||||
{
|
||||
using OptValue = ::sqlpp::optional<Value>;
|
||||
|
||||
auto v_not_null = sqlpp::value(v);
|
||||
auto v_maybe_null = sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// Compare non-nullable with non-nullable.
|
||||
static_assert(is_bool<decltype(in(v_not_null, std::make_tuple(v_not_null, v_not_null)))>::value, "");
|
||||
static_assert(is_bool<decltype(in(v_not_null, std::vector<Value>{}))>::value, "");
|
||||
static_assert(is_bool<decltype(in(v_not_null, select(v_not_null.as(sqlpp::alias::a))))>::value, "");
|
||||
|
||||
// Compare non-nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(in(v_not_null, std::make_tuple(v_not_null, v_maybe_null)))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_not_null, std::vector<OptValue>{}))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_not_null, select(v_maybe_null.as(sqlpp::alias::a))))>::value, "");
|
||||
|
||||
// Compare nullable with non-nullable.
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::make_tuple(v_not_null, v_not_null)))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::vector<Value>{}))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, select(v_not_null.as(sqlpp::alias::a))))>::value, "");
|
||||
|
||||
// Compare nullable with nullable.
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::make_tuple(v_not_null, v_maybe_null)))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, std::vector<OptValue>{}))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(in(v_maybe_null, select(v_maybe_null.as(sqlpp::alias::a))))>::value, "");
|
||||
|
||||
// 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::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});
|
||||
test_in_expression(int32_t{7});
|
||||
test_in_expression(int64_t{7});
|
||||
|
||||
// unsigned integral
|
||||
test_in_expression(uint8_t{7});
|
||||
test_in_expression(uint16_t{7});
|
||||
test_in_expression(uint32_t{7});
|
||||
test_in_expression(uint64_t{7});
|
||||
|
||||
// floating point
|
||||
test_in_expression(float{7.7});
|
||||
test_in_expression(double{7.7});
|
||||
|
||||
// text
|
||||
test_in_expression('7');
|
||||
test_in_expression("seven");
|
||||
test_in_expression(std::string("seven"));
|
||||
test_in_expression(::sqlpp::string_view("seven"));
|
||||
|
||||
// blob
|
||||
test_in_expression(std::vector<uint8_t>{});
|
||||
|
||||
// date
|
||||
test_in_expression(::sqlpp::chrono::day_point{});
|
||||
|
||||
// timestamp
|
||||
test_in_expression(::sqlpp::chrono::microsecond_point{});
|
||||
using minute_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;
|
||||
test_in_expression(minute_point{});
|
||||
|
||||
// time_of_day
|
||||
test_in_expression(std::chrono::microseconds{});
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -23,74 +23,66 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
namespace
|
||||
int main(int, char* [])
|
||||
{
|
||||
template <typename T>
|
||||
using is_bool = std::is_same<sqlpp::value_type_of_t<T>, sqlpp::boolean>;
|
||||
const auto val = sqlpp::value(true);
|
||||
const auto expr = sqlpp::value(17) > 15;
|
||||
|
||||
template <typename T>
|
||||
using is_maybe_bool = std::is_same<sqlpp::value_type_of_t<T>, ::sqlpp::optional<sqlpp::boolean>>;
|
||||
// Operands are enclosed in parenheses where required
|
||||
SQLPP_COMPARE(val and val, "1 AND 1");
|
||||
SQLPP_COMPARE(val and expr, "1 AND (17 > 15)");
|
||||
SQLPP_COMPARE(expr and val, "(17 > 15) AND 1");
|
||||
SQLPP_COMPARE(expr and expr, "(17 > 15) AND (17 > 15)");
|
||||
|
||||
SQLPP_COMPARE(val or val, "1 OR 1");
|
||||
SQLPP_COMPARE(val or expr, "1 OR (17 > 15)");
|
||||
SQLPP_COMPARE(expr or val, "(17 > 15) OR 1");
|
||||
SQLPP_COMPARE(expr or expr, "(17 > 15) OR (17 > 15)");
|
||||
|
||||
SQLPP_COMPARE(not val, "NOT 1");
|
||||
SQLPP_COMPARE(not expr, "NOT (17 > 15)");
|
||||
|
||||
// Chains are not nested in parentheses.
|
||||
SQLPP_COMPARE(val and val and val and val and val, "1 AND 1 AND 1 AND 1 AND 1");
|
||||
SQLPP_COMPARE(val or val or val or val or val, "1 OR 1 OR 1 OR 1 OR 1");
|
||||
|
||||
// Broken chains use parentheses for the respective blocks.
|
||||
SQLPP_COMPARE((val and val and val) or (val and val), "(1 AND 1 AND 1) OR (1 AND 1)");
|
||||
SQLPP_COMPARE((val or val or val) and (val or val), "(1 OR 1 OR 1) AND (1 OR 1)");
|
||||
|
||||
// NOT is not chained gracefully, but hey, don't do that anyways.
|
||||
SQLPP_COMPARE(not not not val, "NOT (NOT (NOT 1))");
|
||||
|
||||
// Operands are enclosed in parenheses where required or completely dropped if inactive
|
||||
SQLPP_COMPARE(val and dynamic(true, val), "1 AND 1");
|
||||
SQLPP_COMPARE(val and dynamic(true, expr), "1 AND (17 > 15)");
|
||||
SQLPP_COMPARE(expr and dynamic(true, val), "(17 > 15) AND 1");
|
||||
SQLPP_COMPARE(expr and dynamic(true, expr), "(17 > 15) AND (17 > 15)");
|
||||
|
||||
SQLPP_COMPARE(val or dynamic(true, val), "1 OR 1");
|
||||
SQLPP_COMPARE(val or dynamic(true, expr), "1 OR (17 > 15)");
|
||||
SQLPP_COMPARE(expr or dynamic(true, val), "(17 > 15) OR 1");
|
||||
SQLPP_COMPARE(expr or dynamic(true, expr), "(17 > 15) OR (17 > 15)");
|
||||
|
||||
SQLPP_COMPARE(val and dynamic(false, val), "1");
|
||||
SQLPP_COMPARE(val and dynamic(false, expr), "1");
|
||||
SQLPP_COMPARE(expr and dynamic(false, val), "17 > 15");
|
||||
SQLPP_COMPARE(expr and dynamic(false, expr), "17 > 15");
|
||||
|
||||
SQLPP_COMPARE(val or dynamic(false, val), "1");
|
||||
SQLPP_COMPARE(val or dynamic(false, expr), "1");
|
||||
SQLPP_COMPARE(expr or dynamic(false, val), "17 > 15");
|
||||
SQLPP_COMPARE(expr or dynamic(false, expr), "17 > 15");
|
||||
|
||||
// Chained partially dynamic expressions
|
||||
SQLPP_COMPARE(val and dynamic(true, val) and expr, "1 AND 1 AND (17 > 15)");
|
||||
SQLPP_COMPARE(val and dynamic(false, val) and expr, "1 AND (17 > 15)");
|
||||
|
||||
SQLPP_COMPARE(val or dynamic(true, val) or expr, "1 OR 1 OR (17 > 15)");
|
||||
SQLPP_COMPARE(val or dynamic(false, val) or expr, "1 OR (17 > 15)");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
void test_logical_expression(Value v)
|
||||
{
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(::sqlpp::make_optional(v));
|
||||
|
||||
// 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, "");
|
||||
|
||||
// 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, "");
|
||||
|
||||
// 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, "");
|
||||
|
||||
// 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, "");
|
||||
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null and dynamic(true, v_maybe_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(v_maybe_null or dynamic(true, v_maybe_null))>::value, "");
|
||||
|
||||
// not.
|
||||
static_assert(is_bool<decltype(not(v_not_null))>::value, "");
|
||||
static_assert(is_maybe_bool<decltype(not(v_maybe_null))>::value, "");
|
||||
|
||||
// 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()
|
||||
{
|
||||
// boolean
|
||||
test_logical_expression(bool{true});
|
||||
}
|
||||
|
||||
|
@ -23,91 +23,24 @@
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../compare.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#warning: implement serialize instead of type tests here!
|
||||
template<typename Value>
|
||||
void test_as_expression(Value v)
|
||||
int main(int, char* [])
|
||||
{
|
||||
using ValueType = sqlpp::value_type_of_t<Value>;
|
||||
using OptValueType = ::sqlpp::optional<ValueType>;
|
||||
const auto val = sqlpp::value(1);
|
||||
const auto expr = sqlpp::value(17) + 4;
|
||||
|
||||
auto v_not_null= sqlpp::value(v);
|
||||
auto v_maybe_null= sqlpp::value(::sqlpp::make_optional(v));
|
||||
// Operands are enclosed in parentheses where required.
|
||||
SQLPP_COMPARE(val.asc(), "1 ASC");
|
||||
SQLPP_COMPARE(val.desc(), "1 DESC");
|
||||
SQLPP_COMPARE(val.order(sqlpp::sort_type::asc), "1 ASC");
|
||||
SQLPP_COMPARE(val.order(sqlpp::sort_type::desc), "1 DESC");
|
||||
|
||||
// Sort order expressions have no value.
|
||||
static_assert(not sqlpp::has_value_type<decltype(v_not_null.asc())>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(v_not_null.desc())>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(v_not_null.order(sqlpp::sort_type::asc))>::value, "");
|
||||
SQLPP_COMPARE(expr.asc(), "(17 + 4) ASC");
|
||||
SQLPP_COMPARE(expr.desc(), "(17 + 4) DESC");
|
||||
SQLPP_COMPARE(expr.order(sqlpp::sort_type::asc), "(17 + 4) ASC");
|
||||
SQLPP_COMPARE(expr.order(sqlpp::sort_type::desc), "(17 + 4) DESC");
|
||||
|
||||
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.asc())>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.desc())>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(v_maybe_null.order(sqlpp::sort_type::asc))>::value, "");
|
||||
|
||||
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_not_null.asc()))>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_not_null.desc()))>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_not_null.order(sqlpp::sort_type::asc)))>::value, "");
|
||||
|
||||
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_maybe_null.asc()))>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_maybe_null.desc()))>::value, "");
|
||||
static_assert(not sqlpp::has_value_type<decltype(dynamic(true, v_maybe_null.order(sqlpp::sort_type::asc)))>::value, "");
|
||||
|
||||
// Sort order expressions have no name.
|
||||
static_assert(not sqlpp::has_name<decltype(v_not_null.asc())>::value, "");
|
||||
static_assert(not sqlpp::has_name<decltype(v_maybe_null.asc())>::value, "");
|
||||
static_assert(not sqlpp::has_name<decltype(dynamic(true, v_not_null.asc()))>::value, "");
|
||||
static_assert(not sqlpp::has_name<decltype(dynamic(true, v_maybe_null.asc()))>::value, "");
|
||||
|
||||
// Sort order expression do not enable the `as` member function.
|
||||
static_assert(not sqlpp::has_enabled_as<decltype(v_not_null.asc())>::value, "");
|
||||
|
||||
// Sort order expressions do not enable comparison member functions.
|
||||
static_assert(not sqlpp::has_enabled_comparison<decltype(v_not_null.asc())>::value, "");
|
||||
|
||||
// Sort order 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.asc())>, sqlpp::detail::type_vector<L>>::value, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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::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{});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user