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

Better failure return type for cte

This commit is contained in:
rbock 2016-09-01 22:15:52 +02:00
parent 5d09b736b6
commit 39dec1ea39

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2013-2016, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -27,16 +27,16 @@
#ifndef SQLPP_CTE_H #ifndef SQLPP_CTE_H
#define SQLPP_CTE_H #define SQLPP_CTE_H
#include <sqlpp11/table_ref.h>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/expression.h> #include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h> #include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h> #include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/table_ref.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -133,6 +133,31 @@ namespace sqlpp
using type = member_t<cte_column_spec_t<FieldSpec>, column_t<AliasProvider, cte_column_spec_t<FieldSpec>>>; using type = member_t<cte_column_spec_t<FieldSpec>, column_t<AliasProvider, cte_column_spec_t<FieldSpec>>>;
}; };
template <typename Check, typename Union>
struct union_cte_impl
{
using type = Check;
};
template <typename Union>
struct union_cte_impl<consistent_t, Union>
{
using type = Union;
};
template <typename Check, typename Union>
using union_cte_impl_t = typename union_cte_impl<Check, Union>::type;
SQLPP_PORTABLE_STATIC_ASSERT(assert_cte_union_args_are_statements_t, "argument for union() must be a statement");
template <typename... T>
struct check_cte_union
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_statement_t<T>::value...>::value, assert_cte_union_args_are_statements_t>>;
};
template <typename... T>
using check_cte_union_t = typename check_cte_union<T...>::type;
template <typename AliasProvider, typename Statement, typename... FieldSpecs> template <typename AliasProvider, typename Statement, typename... FieldSpecs>
struct cte_t : public cte_base<AliasProvider, FieldSpecs>::type... struct cte_t : public cte_base<AliasProvider, FieldSpecs>::type...
{ {
@ -146,21 +171,12 @@ namespace sqlpp
using _column_tuple_t = std::tuple<column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>...>; using _column_tuple_t = std::tuple<column_t<AliasProvider, cte_column_spec_t<FieldSpecs>>...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2086629
// template <typename... T>
// using _check = logic::all_t<is_statement_t<T>::value...>;
template <typename... T>
struct _check : logic::all_t<is_statement_t<T>::value...>
{
};
using _result_row_t = result_row_t<void, FieldSpecs...>; using _result_row_t = result_row_t<void, FieldSpecs...>;
template <typename Rhs> template <typename Rhs>
auto union_distinct(Rhs rhs) const -> auto union_distinct(Rhs rhs) const
typename std::conditional<_check<Rhs>::value, -> union_cte_impl_t<check_cte_union_t<Rhs>,
cte_t<AliasProvider, cte_union_t<distinct_t, Statement, Rhs>, FieldSpecs...>, cte_t<AliasProvider, cte_union_t<distinct_t, Statement, Rhs>, FieldSpecs...>>
bad_statement>::type
{ {
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement"); static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select"); static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
@ -169,14 +185,13 @@ namespace sqlpp
static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value, static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value,
"both select statements in a union have to have the same result columns (type and name)"); "both select statements in a union have to have the same result columns (type and name)");
return _union_impl<void, distinct_t>(_check<Rhs>{}, rhs); return _union_impl<void, distinct_t>(check_cte_union_t<Rhs>{}, rhs);
} }
template <typename Rhs> template <typename Rhs>
auto union_all(Rhs rhs) const -> auto union_all(Rhs rhs) const
typename std::conditional<_check<Rhs>::value, -> union_cte_impl_t<check_cte_union_t<Rhs>,
cte_t<AliasProvider, cte_union_t<all_t, Statement, Rhs>, FieldSpecs...>, cte_t<AliasProvider, cte_union_t<all_t, Statement, Rhs>, FieldSpecs...>>
bad_statement>::type
{ {
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement"); static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select"); static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
@ -185,15 +200,15 @@ namespace sqlpp
static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value, static_assert(std::is_same<_result_row_t, get_result_row_t<Rhs>>::value,
"both select statements in a union have to have the same result columns (type and name)"); "both select statements in a union have to have the same result columns (type and name)");
return _union_impl<all_t>(_check<Rhs>{}, rhs); return _union_impl<all_t>(check_cte_union_t<Rhs>{}, rhs);
} }
private: private:
template <typename Flag, typename Rhs> template <typename Flag, typename Check, typename Rhs>
auto _union_impl(const std::false_type&, Rhs rhs) const -> bad_statement; auto _union_impl(Check, Rhs rhs) const -> Check;
template <typename Flag, typename Rhs> template <typename Flag, typename Rhs>
auto _union_impl(const std::true_type&, Rhs rhs) const auto _union_impl(consistent_t, Rhs rhs) const
-> cte_t<AliasProvider, cte_union_t<Flag, Statement, Rhs>, FieldSpecs...> -> cte_t<AliasProvider, cte_union_t<Flag, Statement, Rhs>, FieldSpecs...>
{ {
return cte_union_t<Flag, Statement, Rhs>{_statement, rhs}; return cte_union_t<Flag, Statement, Rhs>{_statement, rhs};