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

Add more serialize tests for union and select

This commit is contained in:
Roland Bock 2024-10-05 11:46:11 +02:00
parent 957abef11a
commit 8cb8a5cbd9
8 changed files with 92 additions and 16 deletions

View File

@ -168,7 +168,7 @@ namespace sqlpp
{ {
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");
static_assert(has_result_row_t<Rhs>::value, "argument of a clause/union.has to be a (complete) select statement"); static_assert(has_result_row<Rhs>::value, "argument of a clause/union.has to be a (complete) select statement");
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 clause/union.have to have the same result columns (type and name)"); "both select statements in a clause/union.have to have the same result columns (type and name)");
@ -183,7 +183,7 @@ namespace sqlpp
{ {
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");
static_assert(has_result_row_t<Rhs>::value, "argument of a clause/union.has to be a (complete) select statement"); static_assert(has_result_row<Rhs>::value, "argument of a clause/union.has to be a (complete) select statement");
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 clause/union.have to have the same result columns (type and name)"); "both select statements in a clause/union.have to have the same result columns (type and name)");

View File

@ -91,8 +91,16 @@ namespace sqlpp
typename Rhs::_consistency_check>; typename Rhs::_consistency_check>;
}; };
template <typename Statement>
using _result_methods_t = typename Lhs::template _result_methods_t<Statement>;
}; };
template <typename Flag, typename Lhs, typename Rhs>
struct is_result_clause<union_t<Flag, Lhs, Rhs>> : public std::true_type
{
};
SQLPP_PORTABLE_STATIC_ASSERT(assert_union_args_are_statements_t, "arguments for union() must be statements"); SQLPP_PORTABLE_STATIC_ASSERT(assert_union_args_are_statements_t, "arguments for union() must be statements");
template <typename... T> template <typename... T>
struct check_union struct check_union
@ -134,8 +142,8 @@ namespace sqlpp
{ {
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");
static_assert(has_result_row_t<Rhs>::value, "argument of a clause/union.has to be a complete select statement"); static_assert(has_result_row<Rhs>::value, "argument of a clause/union.has to be a complete select statement");
static_assert(has_result_row_t<derived_statement_t<Policies>>::value, static_assert(has_result_row<derived_statement_t<Policies>>::value,
"left hand side argument of a clause/union.has to be a complete select statement or union"); "left hand side argument of a clause/union.has to be a complete select statement or union");
using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>; using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>;
@ -152,8 +160,8 @@ namespace sqlpp
{ {
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");
static_assert(has_result_row_t<Rhs>::value, "argument of a clause/union.has to be a (complete) select statement"); static_assert(has_result_row<Rhs>::value, "argument of a clause/union.has to be a (complete) select statement");
static_assert(has_result_row_t<derived_statement_t<Policies>>::value, static_assert(has_result_row<derived_statement_t<Policies>>::value,
"left hand side argument of a clause/union.has to be a (complete) select statement"); "left hand side argument of a clause/union.has to be a (complete) select statement");
using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>; using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>;

View File

@ -49,7 +49,7 @@ namespace sqlpp
}; };
template <typename Select> template <typename Select>
using check_exists_arg = ::sqlpp::enable_if_t<is_statement_t<Select>::value and has_result_row_t<Select>::value>; using check_exists_arg = ::sqlpp::enable_if_t<is_statement_t<Select>::value and has_result_row<Select>::value>;
template <typename Select> template <typename Select>
struct value_type_of<exists_expression<Select>> struct value_type_of<exists_expression<Select>>

View File

@ -126,7 +126,7 @@ namespace sqlpp
static constexpr bool _can_be_used_as_table() static constexpr bool _can_be_used_as_table()
{ {
#warning: reactivate #warning: reactivate
return has_result_row_t<_statement_t>::value and /*_required_tables::size::value == 0 and*/ return has_result_row<_statement_t>::value and /*_required_tables::size::value == 0 and*/
_required_ctes::size::value == 0; _required_ctes::size::value == 0;
} }

View File

@ -508,24 +508,19 @@ namespace sqlpp
using prepare_check_t = typename prepare_check<Context, T>::type; using prepare_check_t = typename prepare_check<Context, T>::type;
template <typename Statement, typename Enable = void> template <typename Statement, typename Enable = void>
struct has_result_row_impl struct has_result_row: public std::false_type
{ {
using type = std::false_type;
}; };
template <typename Statement> template <typename Statement>
struct has_result_row_impl< struct has_result_row<
Statement, Statement,
typename std::enable_if< typename std::enable_if<
not wrong_t<typename Statement::template _result_methods_t<Statement>::template _result_row_t<void>>::value, not wrong_t<typename Statement::template _result_methods_t<Statement>::template _result_row_t<void>>::value,
void>::type> void>::type>: public std::true_type
{ {
using type = std::true_type;
}; };
template <typename Statement>
using has_result_row_t = typename has_result_row_impl<Statement>::type;
template <typename Statement, typename Enable = void> template <typename Statement, typename Enable = void>
struct get_result_row_impl struct get_result_row_impl
{ {

View File

@ -40,6 +40,7 @@ create_test(insert_set)
create_test(limit) create_test(limit)
create_test(offset) create_test(offset)
create_test(order_by) create_test(order_by)
create_test(select)
create_test(select_columns) create_test(select_columns)
create_test(select_flags) create_test(select_flags)
create_test(union) create_test(union)

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2024, Roland Bock
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Sample.h"
#include "../compare.h"
#include <sqlpp11/sqlpp11.h>
int main(int, char* [])
{
const auto val = sqlpp::value(17);
const auto expr = sqlpp::value(17) + 4;
const auto foo = test::TabFoo{};
// Empty.
SQLPP_COMPARE(sqlpp::select(), "SELECT ");
// SELECT a value.
SQLPP_COMPARE(sqlpp::select(expr.as(foo.id)), "SELECT (17 + 4) AS id");
// SELECT FROM.
SQLPP_COMPARE(select(foo.id).from(foo).unconditionally(), "SELECT tab_foo.id FROM tab_foo");
SQLPP_COMPARE(select(foo.id, foo.textNnD).from(foo).unconditionally(), "SELECT tab_foo.id, tab_foo.text_nn_d FROM tab_foo");
SQLPP_COMPARE(sqlpp::select().columns(foo.id).from(foo).unconditionally(), "SELECT tab_foo.id FROM tab_foo");
SQLPP_COMPARE(sqlpp::select().flags(sqlpp::all).columns(foo.id).from(foo).unconditionally(), "SELECT ALL tab_foo.id FROM tab_foo");
// SELECT FROM WHERE.
SQLPP_COMPARE(select(foo.id).from(foo).where(true), "SELECT tab_foo.id FROM tab_foo WHERE 1");
SQLPP_COMPARE(select(foo.id).from(foo).where(foo.intN > 17), "SELECT tab_foo.id FROM tab_foo WHERE tab_foo.int_n > 17");
SQLPP_COMPARE(select(foo.id).from(foo).where(dynamic(false,foo.intN > 17)), "SELECT tab_foo.id FROM tab_foo");
// SELECT FROM WHERE GROUP BY HAVING.
SQLPP_COMPARE(select(count(foo.id)).from(foo).where(true).group_by(foo.intN).having(max(foo.id) < 100), "SELECT COUNT(tab_foo.id) FROM tab_foo WHERE 1 GROUP BY tab_foo.int_n HAVING MAX(tab_foo.id) < 100");
// SELECT FROM WHERE GROUP BY HAVING ORDER BY LIMIT OFFSET
SQLPP_COMPARE(select(count(foo.id)).from(foo).where(true).group_by(foo.intN).having(max(foo.id) < 100).order_by(foo.intN.asc()).limit(10).offset(3), "SELECT COUNT(tab_foo.id) FROM tab_foo WHERE 1 GROUP BY tab_foo.int_n HAVING MAX(tab_foo.id) < 100 ORDER BY tab_foo.int_n ASC LIMIT 10 OFFSET 3");
#warning: If there is group by, does it make sense to order by non-aggregates? Need to add checks for that.
#warning: need to add type tests, including executability
return 0;
}

View File

@ -42,5 +42,13 @@ int main(int, char* [])
.unconditionally() .unconditionally()
.union_distinct(select(f.id).from(f).unconditionally()), "SELECT tab_bar.id FROM tab_bar UNION DISTINCT SELECT tab_foo.id FROM tab_foo"); .union_distinct(select(f.id).from(f).unconditionally()), "SELECT tab_bar.id FROM tab_bar UNION DISTINCT SELECT tab_foo.id FROM tab_foo");
SQLPP_COMPARE(select(t.intN.as(f.id))
.from(t)
.unconditionally()
.union_distinct(select(f.id).from(f).unconditionally())
.union_all(select(t.id).from(t).unconditionally()),
"SELECT tab_bar.int_n AS id FROM tab_bar UNION DISTINCT SELECT tab_foo.id FROM tab_foo UNION ALL "
"SELECT tab_bar.id FROM tab_bar");
return 0; return 0;
} }