mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Prevent unconditional joins, and naked bool in where() or boolean expressions
- `.from(t1, t2)` produces an unconditional join if you forget to add a condition in the .where() sqlpp11 therefore now deprecates unconditional joins. - more often than not, writing something like `where(name == "doe")`, you meant to write `where(t.name == "doe")`. It is hard to find bugs when the former expression compiles because you happen to have a variable `name` in the current scope as well. sqlpp11 therefore now deprecates `.where(bool)` and disallows raw bool values boolean expression like `something and bool` wrap bools in sqlpp::value(), if you REALLY want a bool value here
This commit is contained in:
parent
6e60dc6630
commit
5e96551f83
@ -31,6 +31,8 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
struct bad_statement
|
struct bad_statement
|
||||||
{
|
{
|
||||||
|
static constexpr bool value = false;
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
bad_statement(T&&...)
|
bad_statement(T&&...)
|
||||||
{
|
{
|
||||||
|
@ -40,21 +40,21 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R>
|
template <typename L, typename R>
|
||||||
struct return_type_and<L, R, binary_operand_check_t<L, is_boolean_t, R, is_boolean_t>>
|
struct return_type_and<L, R, unwrapped_binary_operand_check_t<L, is_boolean_t, R, is_boolean_t>>
|
||||||
{
|
{
|
||||||
using check = consistent_t;
|
using check = consistent_t;
|
||||||
using type = logical_and_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
using type = logical_and_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, typename R>
|
template <typename L, typename R>
|
||||||
struct return_type_or<L, R, binary_operand_check_t<L, is_boolean_t, R, is_boolean_t>>
|
struct return_type_or<L, R, unwrapped_binary_operand_check_t<L, is_boolean_t, R, is_boolean_t>>
|
||||||
{
|
{
|
||||||
using check = consistent_t;
|
using check = consistent_t;
|
||||||
using type = logical_or_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
using type = logical_or_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Defer>
|
template <typename T, typename Defer>
|
||||||
struct return_type_not<T, Defer, unary_operand_check_t<T, is_boolean_t>>
|
struct return_type_not<T, Defer, unwrapped_unary_operand_check_t<T, is_boolean_t>>
|
||||||
{
|
{
|
||||||
using check = consistent_t;
|
using check = consistent_t;
|
||||||
using type = logical_not_t<wrap_operand_t<T>>;
|
using type = logical_not_t<wrap_operand_t<T>>;
|
||||||
|
120
include/sqlpp11/dynamic_join.h
Normal file
120
include/sqlpp11/dynamic_join.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2015, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_DYNAMIC_JOIN_H
|
||||||
|
#define SQLPP_DYNAMIC_JOIN_H
|
||||||
|
|
||||||
|
#include <sqlpp11/join_types.h>
|
||||||
|
#include <sqlpp11/on.h>
|
||||||
|
#include <sqlpp11/noop.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template <typename JoinType, typename Rhs, typename On = noop>
|
||||||
|
struct dynamic_join_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, tag::is_table, tag::is_dynamic_join>;
|
||||||
|
using _nodes = detail::type_vector<Rhs>;
|
||||||
|
using _can_be_null = std::false_type;
|
||||||
|
|
||||||
|
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
|
||||||
|
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
|
||||||
|
static_assert(is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
||||||
|
|
||||||
|
static_assert(required_tables_of<dynamic_join_t>::size::value == 0,
|
||||||
|
"joined tables must not depend on other tables");
|
||||||
|
|
||||||
|
template <typename OnT>
|
||||||
|
using set_on_t = dynamic_join_t<JoinType, Rhs, OnT>;
|
||||||
|
|
||||||
|
template <typename... Expr>
|
||||||
|
auto on(Expr... expr) -> set_on_t<on_t<void, Expr...>>
|
||||||
|
{
|
||||||
|
static_assert(is_noop<On>::value, "cannot call on() twice for a single join()");
|
||||||
|
static_assert(logic::all_t<is_expression_t<Expr>::value...>::value,
|
||||||
|
"at least one argument is not an expression in on()");
|
||||||
|
|
||||||
|
return {_rhs, {std::tuple<Expr...>{expr...}, {}}};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto unconditionally() -> set_on_t<on_t<void, unconditional_t>>
|
||||||
|
{
|
||||||
|
static_assert(is_noop<On>::value, "cannot call on() twice for a single join()");
|
||||||
|
return {_rhs, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
Rhs _rhs;
|
||||||
|
On _on;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Context, typename JoinType, typename Rhs, typename On>
|
||||||
|
struct serializer_t<Context, dynamic_join_t<JoinType, Rhs, On>>
|
||||||
|
{
|
||||||
|
using _serialize_check = serialize_check_of<Context, Rhs, On>;
|
||||||
|
using T = dynamic_join_t<JoinType, Rhs, On>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
static_assert(not is_noop<On>::value, "joined tables require on()");
|
||||||
|
context << " JOIN ";
|
||||||
|
serialize(t._rhs, context);
|
||||||
|
serialize(t._on, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Table>
|
||||||
|
dynamic_join_t<inner_join_t, Table> dynamic_join(Table table)
|
||||||
|
{
|
||||||
|
return {table, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Table>
|
||||||
|
dynamic_join_t<inner_join_t, Table> dynamic_inner_join(Table table)
|
||||||
|
{
|
||||||
|
return {table, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Table>
|
||||||
|
dynamic_join_t<outer_join_t, Table> outer_join(Table table)
|
||||||
|
{
|
||||||
|
return {table, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Table>
|
||||||
|
dynamic_join_t<left_outer_join_t, Table> left_outer_join(Table table)
|
||||||
|
{
|
||||||
|
return {table, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Table>
|
||||||
|
dynamic_join_t<right_outer_join_t, Table> right_outer_join(Table table)
|
||||||
|
{
|
||||||
|
return {table, {}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -35,9 +35,16 @@
|
|||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
#include <sqlpp11/detail/sum.h>
|
#include <sqlpp11/detail/sum.h>
|
||||||
#include <sqlpp11/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/dynamic_join.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
|
#ifdef SQLPP_ALLOW_UNCONDITIONAL_JOIN
|
||||||
|
constexpr bool allow_unconditional_from = 1;
|
||||||
|
#else
|
||||||
|
constexpr bool allow_unconditional_from = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
// FROM DATA
|
// FROM DATA
|
||||||
template <typename Database, typename... Tables>
|
template <typename Database, typename... Tables>
|
||||||
struct from_data_t
|
struct from_data_t
|
||||||
@ -77,35 +84,40 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Table>
|
template <typename DynamicJoin>
|
||||||
void add(Table table)
|
void add(DynamicJoin dynamicJoin)
|
||||||
{
|
{
|
||||||
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
||||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
static_assert(
|
||||||
|
is_dynamic_join_t<DynamicJoin>::value or (allow_unconditional_from and is_table_t<DynamicJoin>::value),
|
||||||
|
"invalid argument in from::add(), or #define ALLOW_UNCONDITIONAL_JOIN "
|
||||||
|
"for a grace period of using tables here");
|
||||||
using _known_tables =
|
using _known_tables =
|
||||||
detail::make_joined_set_t<provided_tables_of<Tables>...>; // Hint: Joins contain more than one table
|
detail::make_joined_set_t<provided_tables_of<Tables>...>; // Hint: Joins contain more than one table
|
||||||
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198
|
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/feedback/details/2173198
|
||||||
// using _known_table_names = detail::transform_set_t<name_of, _known_tables>;
|
// using _known_table_names = detail::transform_set_t<name_of, _known_tables>;
|
||||||
using _known_table_names = detail::make_name_of_set_t<_known_tables>;
|
using _known_table_names = detail::make_name_of_set_t<_known_tables>;
|
||||||
static_assert(not detail::is_element_of<typename Table::_alias_t, _known_table_names>::value,
|
using _joined_tables = provided_tables_of<DynamicJoin>;
|
||||||
|
using _joined_table_names = detail::make_name_of_set_t<_joined_tables>;
|
||||||
|
static_assert(detail::is_disjunct_from<_joined_table_names, _known_table_names>::value,
|
||||||
"Must not use the same table name twice in from()");
|
"Must not use the same table name twice in from()");
|
||||||
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Table>;
|
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, DynamicJoin>;
|
||||||
_serialize_check::_();
|
_serialize_check::_();
|
||||||
|
|
||||||
using ok = logic::all_t<_is_dynamic::value, is_table_t<Table>::value, _serialize_check::type::value>;
|
using ok = logic::all_t<_is_dynamic::value, is_table_t<DynamicJoin>::value, _serialize_check::type::value>;
|
||||||
|
|
||||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
_add_impl(dynamicJoin, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Table>
|
template <typename DynamicJoin>
|
||||||
void _add_impl(Table table, const std::true_type&)
|
void _add_impl(DynamicJoin dynamicJoin, const std::true_type&)
|
||||||
{
|
{
|
||||||
return _data._dynamic_tables.emplace_back(from_table(table));
|
return _data._dynamic_tables.emplace_back(from_table(dynamicJoin));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Table>
|
template <typename DynamicJoin>
|
||||||
void _add_impl(Table table, const std::false_type&);
|
void _add_impl(DynamicJoin dynamicJoin, const std::false_type&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_data_t _data;
|
_data_t _data;
|
||||||
@ -210,12 +222,15 @@ namespace sqlpp
|
|||||||
|
|
||||||
using _consistency_check = consistent_t;
|
using _consistency_check = consistent_t;
|
||||||
|
|
||||||
template <typename... Tables>
|
template <typename Table, typename... Tables>
|
||||||
auto from(Tables... tables) const -> _new_statement_t<_check<Tables...>, from_t<void, from_table_t<Tables>...>>
|
auto from(Table table, Tables... tables) const
|
||||||
|
-> _new_statement_t<_check<Table, Tables...>, from_t<void, from_table_t<Table>, from_table_t<Tables>...>>
|
||||||
{
|
{
|
||||||
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in from()");
|
static_assert(_check<Table, Tables...>::value, "at least one argument is not a table or join in from()");
|
||||||
static_assert(sizeof...(Tables), "at least one table or join argument required in from()");
|
static_assert(sizeof...(Tables) == 0 or ::sqlpp::allow_unconditional_from,
|
||||||
return _from_impl<void>(_check<Tables...>{}, tables...);
|
"unconditional join is deprecated, please use explicit joins or #define ALLOW_UNCONDITIONAL_JOIN "
|
||||||
|
"for a grace period");
|
||||||
|
return _from_impl<void>(_check<Table, Tables...>{}, table, tables...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Tables>
|
template <typename... Tables>
|
||||||
@ -225,6 +240,10 @@ namespace sqlpp
|
|||||||
static_assert(not std::is_same<_database_t, void>::value,
|
static_assert(not std::is_same<_database_t, void>::value,
|
||||||
"dynamic_from must not be called in a static statement");
|
"dynamic_from must not be called in a static statement");
|
||||||
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in from()");
|
static_assert(_check<Tables...>::value, "at least one argument is not a table or join in from()");
|
||||||
|
static_assert(
|
||||||
|
sizeof...(Tables) == 1 or ::sqlpp::allow_unconditional_from,
|
||||||
|
"unconditional join is deprecated, please use explicit joins or #define SQLPP_ALLOW_UNCONDITIONAL_JOIN "
|
||||||
|
"for a grace period");
|
||||||
return _from_impl<_database_t>(_check<Tables...>{}, tables...);
|
return _from_impl<_database_t>(_check<Tables...>{}, tables...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,42 +27,12 @@
|
|||||||
#ifndef SQLPP_JOIN_H
|
#ifndef SQLPP_JOIN_H
|
||||||
#define SQLPP_JOIN_H
|
#define SQLPP_JOIN_H
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/join_types.h>
|
||||||
#include <sqlpp11/on.h>
|
#include <sqlpp11/on.h>
|
||||||
#include <sqlpp11/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct inner_join_t
|
|
||||||
{
|
|
||||||
template <typename Lhs, typename Rhs>
|
|
||||||
using _provided_outer_tables =
|
|
||||||
detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
|
||||||
|
|
||||||
static constexpr const char* _name = " INNER ";
|
|
||||||
};
|
|
||||||
struct outer_join_t
|
|
||||||
{
|
|
||||||
template <typename Lhs, typename Rhs>
|
|
||||||
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
|
||||||
|
|
||||||
static constexpr const char* _name = " OUTER ";
|
|
||||||
};
|
|
||||||
struct left_outer_join_t
|
|
||||||
{
|
|
||||||
template <typename Lhs, typename Rhs>
|
|
||||||
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
|
||||||
|
|
||||||
static constexpr const char* _name = " LEFT OUTER ";
|
|
||||||
};
|
|
||||||
struct right_outer_join_t
|
|
||||||
{
|
|
||||||
template <typename Lhs, typename Rhs>
|
|
||||||
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
|
||||||
|
|
||||||
static constexpr const char* _name = " RIGHT OUTER ";
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
template <typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
||||||
struct join_t
|
struct join_t
|
||||||
{
|
{
|
||||||
@ -93,6 +63,11 @@ namespace sqlpp
|
|||||||
return {_lhs, _rhs, {std::tuple<Expr...>{expr...}, {}}};
|
return {_lhs, _rhs, {std::tuple<Expr...>{expr...}, {}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto unconditionally() -> set_on_t<on_t<void, unconditional_t>>
|
||||||
|
{
|
||||||
|
return {_lhs, _rhs, {}};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
join_t<inner_join_t, join_t, T> join(T t)
|
join_t<inner_join_t, join_t, T> join(T t)
|
||||||
{
|
{
|
||||||
|
65
include/sqlpp11/join_types.h
Normal file
65
include/sqlpp11/join_types.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2015, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_JOIN_TYPES_H
|
||||||
|
#define SQLPP_JOIN_TYPES_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
struct inner_join_t
|
||||||
|
{
|
||||||
|
template <typename Lhs, typename Rhs>
|
||||||
|
using _provided_outer_tables =
|
||||||
|
detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
||||||
|
|
||||||
|
static constexpr const char* _name = " INNER ";
|
||||||
|
};
|
||||||
|
struct outer_join_t
|
||||||
|
{
|
||||||
|
template <typename Lhs, typename Rhs>
|
||||||
|
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||||
|
|
||||||
|
static constexpr const char* _name = " OUTER ";
|
||||||
|
};
|
||||||
|
struct left_outer_join_t
|
||||||
|
{
|
||||||
|
template <typename Lhs, typename Rhs>
|
||||||
|
using _provided_outer_tables = detail::make_joined_set_t<provided_tables_of<Lhs>, provided_outer_tables_of<Rhs>>;
|
||||||
|
|
||||||
|
static constexpr const char* _name = " LEFT OUTER ";
|
||||||
|
};
|
||||||
|
struct right_outer_join_t
|
||||||
|
{
|
||||||
|
template <typename Lhs, typename Rhs>
|
||||||
|
using _provided_outer_tables = detail::make_joined_set_t<provided_outer_tables_of<Lhs>, provided_tables_of<Rhs>>;
|
||||||
|
|
||||||
|
static constexpr const char* _name = " RIGHT OUTER ";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -30,6 +30,7 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/interpretable_list.h>
|
#include <sqlpp11/interpretable_list.h>
|
||||||
|
#include <sqlpp11/unconditional.h>
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -72,6 +73,25 @@ namespace sqlpp
|
|||||||
interpretable_list_t<Database> _dynamic_expressions;
|
interpretable_list_t<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct on_t<void, unconditional_t>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, tag::is_on>;
|
||||||
|
using _nodes = detail::type_vector<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Context>
|
||||||
|
struct serializer_t<Context, on_t<void, unconditional_t>>
|
||||||
|
{
|
||||||
|
using _serialize_check = consistent_t;
|
||||||
|
using T = on_t<void, unconditional_t>;
|
||||||
|
|
||||||
|
static Context& _(const T&, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Context, typename Database, typename... Expressions>
|
template <typename Context, typename Database, typename... Expressions>
|
||||||
struct serializer_t<Context, on_t<Database, Expressions...>>
|
struct serializer_t<Context, on_t<Database, Expressions...>>
|
||||||
{
|
{
|
||||||
@ -82,11 +102,12 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
return context;
|
return context;
|
||||||
context << " ON ";
|
context << " ON (";
|
||||||
interpret_tuple(t._expressions, " AND ", context);
|
interpret_tuple(t._expressions, " AND ", context);
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
context << " AND ";
|
context << " AND ";
|
||||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||||
|
context << " )";
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -38,13 +38,16 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, template <typename> class Pred>
|
template <typename T, template <typename> class Pred>
|
||||||
struct unary_operand_check<T, Pred, detail::enable_if_t<Pred<wrap_operand_t<T>>::value>>
|
struct unary_operand_check<T, Pred, detail::enable_if_t<Pred<T>::value>>
|
||||||
{
|
{
|
||||||
using type = void;
|
using type = void;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, template <typename> class Pred>
|
template <typename T, template <typename> class Pred>
|
||||||
using unary_operand_check_t = typename unary_operand_check<T, Pred>::type;
|
using unary_operand_check_t = typename unary_operand_check<wrap_operand_t<T>, Pred>::type;
|
||||||
|
|
||||||
|
template <typename T, template <typename> class Pred>
|
||||||
|
using unwrapped_unary_operand_check_t = typename unary_operand_check<T, Pred>::type;
|
||||||
|
|
||||||
template <typename L,
|
template <typename L,
|
||||||
template <typename> class LPred,
|
template <typename> class LPred,
|
||||||
@ -56,17 +59,17 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, template <typename> class LPred, typename R, template <typename> class RPred>
|
template <typename L, template <typename> class LPred, typename R, template <typename> class RPred>
|
||||||
struct binary_operand_check<L,
|
struct binary_operand_check<L, LPred, R, RPred, detail::enable_if_t<LPred<L>::value and RPred<R>::value>>
|
||||||
LPred,
|
|
||||||
R,
|
|
||||||
RPred,
|
|
||||||
detail::enable_if_t<LPred<wrap_operand_t<L>>::value and RPred<wrap_operand_t<R>>::value>>
|
|
||||||
{
|
{
|
||||||
using type = void;
|
using type = void;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename L, template <typename> class LPred, typename R, template <typename> class RPred>
|
template <typename L, template <typename> class LPred, typename R, template <typename> class RPred>
|
||||||
using binary_operand_check_t = typename binary_operand_check<L, LPred, R, RPred>::type;
|
using binary_operand_check_t =
|
||||||
|
typename binary_operand_check<wrap_operand_t<L>, LPred, wrap_operand_t<L>, RPred>::type;
|
||||||
|
|
||||||
|
template <typename L, template <typename> class LPred, typename R, template <typename> class RPred>
|
||||||
|
using unwrapped_binary_operand_check_t = typename binary_operand_check<L, LPred, R, RPred>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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,
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#include <sqlpp11/column_fwd.h>
|
#include <sqlpp11/column_fwd.h>
|
||||||
#include <sqlpp11/interpret.h>
|
#include <sqlpp11/interpret.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/join.h>
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
@ -41,7 +42,6 @@ namespace sqlpp
|
|||||||
template <typename AliasProvider, typename Table, typename... ColumnSpec>
|
template <typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||||
struct table_alias_t : public ColumnSpec::_alias_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
struct table_alias_t : public ColumnSpec::_alias_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||||
{
|
{
|
||||||
// FIXME: Need to add join functionality
|
|
||||||
using _traits = make_traits<value_type_of<Table>,
|
using _traits = make_traits<value_type_of<Table>,
|
||||||
tag::is_table,
|
tag::is_table,
|
||||||
tag::is_alias,
|
tag::is_alias,
|
||||||
@ -60,6 +60,36 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
join_t<inner_join_t, table_alias_t, T> join(T t) const
|
||||||
|
{
|
||||||
|
return {*this, t, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
join_t<inner_join_t, table_alias_t, T> inner_join(T t) const
|
||||||
|
{
|
||||||
|
return {*this, t, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
join_t<outer_join_t, table_alias_t, T> outer_join(T t) const
|
||||||
|
{
|
||||||
|
return {*this, t, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
join_t<left_outer_join_t, table_alias_t, T> left_outer_join(T t) const
|
||||||
|
{
|
||||||
|
return {*this, t, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
join_t<right_outer_join_t, table_alias_t, T> right_outer_join(T t) const
|
||||||
|
{
|
||||||
|
return {*this, t, {}};
|
||||||
|
}
|
||||||
|
|
||||||
Table _table;
|
Table _table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,6 +164,7 @@ namespace sqlpp
|
|||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_table)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_table)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_raw_table)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_raw_table)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_join)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_join)
|
||||||
|
SQLPP_VALUE_TRAIT_GENERATOR(is_dynamic_join)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_pseudo_table)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_pseudo_table)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_column)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_column)
|
||||||
SQLPP_VALUE_TRAIT_GENERATOR(is_select)
|
SQLPP_VALUE_TRAIT_GENERATOR(is_select)
|
||||||
|
36
include/sqlpp11/unconditional.h
Normal file
36
include/sqlpp11/unconditional.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2015, Roland Bock
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLPP_UNCONDITIONAL_H
|
||||||
|
#define SQLPP_UNCONDITIONAL_H
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
struct unconditional_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
@ -33,6 +33,7 @@
|
|||||||
#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/unconditional.h>
|
||||||
#include <sqlpp11/logic.h>
|
#include <sqlpp11/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -153,6 +154,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SQLPP_ALLOW_NAKED_BOOL_EXPRESSION
|
||||||
template <>
|
template <>
|
||||||
struct where_data_t<void, bool>
|
struct where_data_t<void, bool>
|
||||||
{
|
{
|
||||||
@ -214,8 +216,70 @@ namespace sqlpp
|
|||||||
using _consistency_check = consistent_t;
|
using _consistency_check = consistent_t;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_t, "where expression required, e.g. where(true)");
|
template <>
|
||||||
|
struct where_data_t<void, unconditional_t>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// WHERE() UNCONDITIONALLY
|
||||||
|
template <>
|
||||||
|
struct where_t<void, unconditional_t>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, tag::is_where>;
|
||||||
|
using _nodes = detail::type_vector<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = where_data_t<void, unconditional_t>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
|
||||||
|
_impl_t() = default;
|
||||||
|
_impl_t(const _data_t& data) : _data(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base template to be inherited by the statement
|
||||||
|
template <typename Policies>
|
||||||
|
struct _base_t
|
||||||
|
{
|
||||||
|
using _data_t = where_data_t<void, unconditional_t>;
|
||||||
|
|
||||||
|
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
|
||||||
|
template <typename... Args>
|
||||||
|
_base_t(Args&&... args)
|
||||||
|
: where{std::forward<Args>(args)...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
_impl_t<Policies> where;
|
||||||
|
_impl_t<Policies>& operator()()
|
||||||
|
{
|
||||||
|
return where;
|
||||||
|
}
|
||||||
|
const _impl_t<Policies>& operator()() const
|
||||||
|
{
|
||||||
|
return where;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.where)
|
||||||
|
{
|
||||||
|
return t.where;
|
||||||
|
}
|
||||||
|
|
||||||
|
using _consistency_check = consistent_t;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_t, "calling where() or uncontionally() required");
|
||||||
|
|
||||||
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_expressions_t,
|
SQLPP_PORTABLE_STATIC_ASSERT(assert_where_expressions_t,
|
||||||
"at least one argument is not a boolean expression in where()");
|
"at least one argument is not a boolean expression in where()");
|
||||||
@ -328,10 +392,28 @@ namespace sqlpp
|
|||||||
assert_where_t,
|
assert_where_t,
|
||||||
consistent_t>::type;
|
consistent_t>::type;
|
||||||
|
|
||||||
|
#ifdef SQLPP_ALLOW_NAKED_BOOL_EXPRESSION
|
||||||
|
template <typename T = void>
|
||||||
auto where(bool b) const -> _new_statement_t<std::true_type, where_t<void, bool>>
|
auto where(bool b) const -> _new_statement_t<std::true_type, where_t<void, bool>>
|
||||||
{
|
{
|
||||||
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, bool>{b}};
|
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, bool>{b}};
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
template <typename T = void>
|
||||||
|
auto where(bool b) const -> bad_statement
|
||||||
|
{
|
||||||
|
static_assert(
|
||||||
|
wrong_t<T>::value,
|
||||||
|
"where(bool) is deprecated, please use unconditionally() or #define SQLPP_ALLOW_NAKED_BOOL_EXPRESSION "
|
||||||
|
"for a grace period");
|
||||||
|
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, bool>{b}};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto unconditionally() const -> _new_statement_t<std::true_type, where_t<void, unconditional_t>>
|
||||||
|
{
|
||||||
|
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, unconditional_t>{}};
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Expressions>
|
template <typename... Expressions>
|
||||||
auto where(Expressions... expressions) const
|
auto where(Expressions... expressions) const
|
||||||
@ -387,6 +469,7 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SQLPP_ALLOW_NAKED_BOOL_EXPRESSION
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
struct serializer_t<Context, where_data_t<void, bool>>
|
struct serializer_t<Context, where_data_t<void, bool>>
|
||||||
{
|
{
|
||||||
@ -400,6 +483,19 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Context>
|
||||||
|
struct serializer_t<Context, where_data_t<void, unconditional_t>>
|
||||||
|
{
|
||||||
|
using _serialize_check = consistent_t;
|
||||||
|
using T = where_data_t<void, unconditional_t>;
|
||||||
|
|
||||||
|
static Context& _(const T&, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
auto where(T&&... t) -> decltype(statement_t<void, no_where_t<false>>().where(std::forward<T>(t)...))
|
auto where(T&&... t) -> decltype(statement_t<void, no_where_t<false>>().where(std::forward<T>(t)...))
|
||||||
|
@ -36,7 +36,7 @@ int main()
|
|||||||
static_assert(sqlpp::can_be_null_t<decltype(t.alpha)>::value, "t.alpha can be null");
|
static_assert(sqlpp::can_be_null_t<decltype(t.alpha)>::value, "t.alpha can be null");
|
||||||
static_assert(not sqlpp::null_is_trivial_value_t<decltype(t.alpha)>::value, "t.alpha does not say null_is_trivial");
|
static_assert(not sqlpp::null_is_trivial_value_t<decltype(t.alpha)>::value, "t.alpha does not say null_is_trivial");
|
||||||
|
|
||||||
for (const auto& row : edb(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : edb(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
||||||
static_assert(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
static_assert(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
||||||
|
@ -34,4 +34,5 @@ test_compile(where)
|
|||||||
test_compile(insert)
|
test_compile(insert)
|
||||||
test_compile(date)
|
test_compile(date)
|
||||||
test_compile(date_time)
|
test_compile(date_time)
|
||||||
|
test_compile(unwrapped_bool)
|
||||||
|
|
||||||
|
@ -75,51 +75,53 @@ namespace
|
|||||||
// If there is no group_by, we can select whatever we want
|
// If there is no group_by, we can select whatever we want
|
||||||
void no_group_by()
|
void no_group_by()
|
||||||
{
|
{
|
||||||
run_check(select(all_of(t)).from(t).where(true));
|
run_check(select(all_of(t)).from(t).unconditionally());
|
||||||
run_check(select(t.alpha).from(t).where(true));
|
run_check(select(t.alpha).from(t).unconditionally());
|
||||||
run_check(select(count(t.alpha)).from(t).where(true));
|
run_check(select(count(t.alpha)).from(t).unconditionally());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a dynamic group_by, we can still select whatever we want
|
// If there is a dynamic group_by, we can still select whatever we want
|
||||||
// because there is no way of knowing which expressions might have been added dynamically
|
// because there is no way of knowing which expressions might have been added dynamically
|
||||||
void dynamic_group_by()
|
void dynamic_group_by()
|
||||||
{
|
{
|
||||||
run_check(select(all_of(t)).from(t).where(true));
|
run_check(select(all_of(t)).from(t).unconditionally());
|
||||||
run_check(select(t.alpha).from(t).where(true));
|
run_check(select(t.alpha).from(t).unconditionally());
|
||||||
run_check(select(count(t.alpha)).from(t).where(true));
|
run_check(select(count(t.alpha)).from(t).unconditionally());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a static group_by, selected columns must be made of group_by expressions, or aggregate expression (e.g.
|
// If there is a static group_by, selected columns must be made of group_by expressions, or aggregate expression (e.g.
|
||||||
// count(t.id)) or values to be valid
|
// count(t.id)) or values to be valid
|
||||||
void static_group_by_ok()
|
void static_group_by_ok()
|
||||||
{
|
{
|
||||||
run_check(select(t.alpha).from(t).where(true).group_by(t.alpha));
|
run_check(select(t.alpha).from(t).unconditionally().group_by(t.alpha));
|
||||||
run_check(select((t.alpha + 42).as(whatever)).from(t).where(true).group_by(t.alpha));
|
run_check(select((t.alpha + 42).as(whatever)).from(t).unconditionally().group_by(t.alpha));
|
||||||
run_check(select((t.alpha + 42).as(whatever)).from(t).where(true).group_by(t.alpha, t.alpha + t.delta * 17));
|
run_check(select((t.alpha + 42).as(whatever)).from(t).unconditionally().group_by(t.alpha, t.alpha + t.delta * 17));
|
||||||
run_check(
|
run_check(select((t.alpha + t.delta * 17).as(whatever))
|
||||||
select((t.alpha + t.delta * 17).as(whatever)).from(t).where(true).group_by(t.alpha, t.alpha + t.delta * 17));
|
.from(t)
|
||||||
run_check(select((t.beta + "fortytwo").as(whatever)).from(t).where(true).group_by(t.beta));
|
.unconditionally()
|
||||||
|
.group_by(t.alpha, t.alpha + t.delta * 17));
|
||||||
|
run_check(select((t.beta + "fortytwo").as(whatever)).from(t).unconditionally().group_by(t.beta));
|
||||||
|
|
||||||
run_check(select(avg(t.alpha)).from(t).where(true).group_by(t.beta));
|
run_check(select(avg(t.alpha)).from(t).unconditionally().group_by(t.beta));
|
||||||
run_check(select(count(t.alpha)).from(t).where(true).group_by(t.beta));
|
run_check(select(count(t.alpha)).from(t).unconditionally().group_by(t.beta));
|
||||||
run_check(select(max(t.alpha)).from(t).where(true).group_by(t.beta));
|
run_check(select(max(t.alpha)).from(t).unconditionally().group_by(t.beta));
|
||||||
run_check(select(min(t.alpha)).from(t).where(true).group_by(t.beta));
|
run_check(select(min(t.alpha)).from(t).unconditionally().group_by(t.beta));
|
||||||
run_check(select(sum(t.alpha)).from(t).where(true).group_by(t.beta));
|
run_check(select(sum(t.alpha)).from(t).unconditionally().group_by(t.beta));
|
||||||
|
|
||||||
run_check(select((t.alpha + count(t.delta)).as(whatever)).from(t).where(true).group_by(t.alpha));
|
run_check(select((t.alpha + count(t.delta)).as(whatever)).from(t).unconditionally().group_by(t.alpha));
|
||||||
|
|
||||||
run_check(select(sqlpp::value(1).as(whatever)).from(t).where(true).group_by(t.alpha));
|
run_check(select(sqlpp::value(1).as(whatever)).from(t).unconditionally().group_by(t.alpha));
|
||||||
run_check(select(sqlpp::value("whatever").as(whatever)).from(t).where(true).group_by(t.alpha));
|
run_check(select(sqlpp::value("whatever").as(whatever)).from(t).unconditionally().group_by(t.alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failures with static group_by and selected non-aggregates or incorrect aggregates
|
// Failures with static group_by and selected non-aggregates or incorrect aggregates
|
||||||
void static_group_by_nok()
|
void static_group_by_nok()
|
||||||
{
|
{
|
||||||
run_check<sqlpp::assert_aggregates_t>(select(t.beta).from(t).where(true).group_by(t.alpha));
|
run_check<sqlpp::assert_aggregates_t>(select(t.beta).from(t).unconditionally().group_by(t.alpha));
|
||||||
run_check<sqlpp::assert_aggregates_t>(
|
run_check<sqlpp::assert_aggregates_t>(
|
||||||
select((t.alpha + t.delta).as(whatever)).from(t).where(true).group_by(t.alpha));
|
select((t.alpha + t.delta).as(whatever)).from(t).unconditionally().group_by(t.alpha));
|
||||||
run_check<sqlpp::assert_aggregates_t>(
|
run_check<sqlpp::assert_aggregates_t>(
|
||||||
select((t.alpha + t.delta).as(whatever)).from(t).where(true).group_by(t.alpha, t.alpha + t.delta * 17));
|
select((t.alpha + t.delta).as(whatever)).from(t).unconditionally().group_by(t.alpha, t.alpha + t.delta * 17));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
115
test_static_asserts/unwrapped_bool.cpp
Normal file
115
test_static_asserts/unwrapped_bool.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015-2016, 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 <iostream>
|
||||||
|
#include "MockDb.h"
|
||||||
|
#include "Sample.h"
|
||||||
|
#include <sqlpp11/sqlpp11.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr auto t = test::TabBar{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct wrap
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void print_type_on_error(std::true_type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void print_type_on_error(std::false_type)
|
||||||
|
{
|
||||||
|
wrap<T>::_print_me_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Assert, typename Lhs, typename Rhs>
|
||||||
|
void and_check(const Lhs& lhs, const Rhs& rhs)
|
||||||
|
{
|
||||||
|
using ReturnType = decltype(lhs and rhs);
|
||||||
|
using ExpectedReturnType =
|
||||||
|
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_expression<sqlpp::boolean>>::value>;
|
||||||
|
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||||
|
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Assert, typename Lhs, typename Rhs>
|
||||||
|
void or_check(const Lhs& lhs, const Rhs& rhs)
|
||||||
|
{
|
||||||
|
using ReturnType = decltype(lhs or rhs);
|
||||||
|
using ExpectedReturnType =
|
||||||
|
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_expression<sqlpp::boolean>>::value>;
|
||||||
|
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||||
|
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Assert, typename Lhs>
|
||||||
|
void not_check(const Lhs& lhs)
|
||||||
|
{
|
||||||
|
using ReturnType = decltype(not lhs);
|
||||||
|
using ExpectedReturnType =
|
||||||
|
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_expression<sqlpp::boolean>>::value>;
|
||||||
|
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||||
|
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Assert, typename Condition>
|
||||||
|
void where_check(const Condition& condition)
|
||||||
|
{
|
||||||
|
using ReturnType = decltype(sqlpp::where(condition));
|
||||||
|
using ExpectedReturnType =
|
||||||
|
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
|
||||||
|
print_type_on_error<ReturnType>(ExpectedReturnType{});
|
||||||
|
static_assert(ExpectedReturnType::value, "Unexpected return type");
|
||||||
|
}
|
||||||
|
|
||||||
|
void boolean()
|
||||||
|
{
|
||||||
|
and_check<sqlpp::consistent_t>(t.gamma, t.gamma);
|
||||||
|
and_check<sqlpp::assert_valid_operands>(t.gamma, true);
|
||||||
|
// and_check<sqlpp::assert_valid_operands>(true, t.gamma); // Cannot currently do that
|
||||||
|
|
||||||
|
or_check<sqlpp::consistent_t>(t.gamma, t.gamma);
|
||||||
|
or_check<sqlpp::assert_valid_operands>(t.gamma, true);
|
||||||
|
// or_check<sqlpp::assert_valid_operands>(true, t.gamma); // Cannot currently do that
|
||||||
|
|
||||||
|
not_check<sqlpp::consistent_t>(t.gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
void where()
|
||||||
|
{
|
||||||
|
where_check<sqlpp::consistent_t>(t.gamma);
|
||||||
|
where_check<sqlpp::bad_statement>(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, char* [])
|
||||||
|
{
|
||||||
|
boolean();
|
||||||
|
where();
|
||||||
|
}
|
@ -31,7 +31,6 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr auto t = test::TabBar{};
|
constexpr auto t = test::TabBar{};
|
||||||
constexpr auto f = test::TabFoo{};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void print_type_on_error(std::true_type)
|
void print_type_on_error(std::true_type)
|
||||||
|
@ -40,7 +40,7 @@ int DateTime(int, char* [])
|
|||||||
{
|
{
|
||||||
std::cout << row.now;
|
std::cout << row.now;
|
||||||
}
|
}
|
||||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
std::cout << row.colDayPoint;
|
std::cout << row.colDayPoint;
|
||||||
std::cout << row.colTimePoint;
|
std::cout << row.colTimePoint;
|
||||||
|
@ -197,7 +197,7 @@ int Function(int, char* [])
|
|||||||
static_assert(not sqlpp::is_numeric_t<TT>::value, "type requirement");
|
static_assert(not sqlpp::is_numeric_t<TT>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_text_t<TT>::value, "type requirement");
|
static_assert(not sqlpp::is_text_t<TT>::value, "type requirement");
|
||||||
|
|
||||||
if (false and db(select(exists(select(t.alpha).from(t).where(true)))).front().exists)
|
if (false and db(select(exists(select(t.alpha).from(t).unconditionally()))).front().exists)
|
||||||
{ /* do something */
|
{ /* do something */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +286,7 @@ int Function(int, char* [])
|
|||||||
static_assert(sqlpp::is_integral_t<TT>::value, "type requirement");
|
static_assert(sqlpp::is_integral_t<TT>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_floating_point_t<TT>::value, "type requirement");
|
static_assert(not sqlpp::is_floating_point_t<TT>::value, "type requirement");
|
||||||
|
|
||||||
if (false and db(select(count(t.alpha)).from(t).where(true)).front().count > 0)
|
if (false and db(select(count(t.alpha)).from(t).unconditionally()).front().count > 0)
|
||||||
{ /* do something */
|
{ /* do something */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,7 +444,7 @@ int Function(int, char* [])
|
|||||||
static_assert(std::is_same<decltype(sqlpp::tvin("test")), sqlpp::tvin_arg_t<sqlpp::text_operand>>::value,
|
static_assert(std::is_same<decltype(sqlpp::tvin("test")), sqlpp::tvin_arg_t<sqlpp::text_operand>>::value,
|
||||||
"text values are accepted and wrapped");
|
"text values are accepted and wrapped");
|
||||||
|
|
||||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<decltype(sqlpp::tvin(row.alpha)),
|
static_assert(std::is_same<decltype(sqlpp::tvin(row.alpha)),
|
||||||
sqlpp::tvin_arg_t<typename std::remove_const<decltype(row.alpha)>::type>>::value,
|
sqlpp::tvin_arg_t<typename std::remove_const<decltype(row.alpha)>::type>>::value,
|
||||||
|
@ -178,10 +178,9 @@ int Interpret(int, char* [])
|
|||||||
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).str();
|
serialize(avg(sqlpp::distinct, t.alpha - 7), printer).str();
|
||||||
serialize(sum(sqlpp::distinct, t.alpha + 7), printer).str();
|
serialize(sum(sqlpp::distinct, t.alpha + 7), printer).str();
|
||||||
|
|
||||||
serialize(select(all_of(t)).from(t).where(true), printer).str();
|
serialize(select(all_of(t)).from(t).unconditionally(), printer).str();
|
||||||
serialize(select(all_of(t)).from(t).where(false), printer).str();
|
|
||||||
|
|
||||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
serialize(row.alpha, printer);
|
serialize(row.alpha, printer);
|
||||||
serialize(row.beta, printer);
|
serialize(row.beta, printer);
|
||||||
@ -201,8 +200,8 @@ int Interpret(int, char* [])
|
|||||||
std::cerr << serialize(x, printer).str() << std::endl;
|
std::cerr << serialize(x, printer).str() << std::endl;
|
||||||
|
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).where(true))), printer)
|
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).unconditionally())),
|
||||||
.str() << std::endl;
|
printer).str() << std::endl;
|
||||||
|
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in()), printer).str() << std::endl;
|
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in()), printer).str() << std::endl;
|
||||||
@ -214,7 +213,7 @@ int Interpret(int, char* [])
|
|||||||
auto s = schema_qualified_table(schema, t).as(sqlpp::alias::x);
|
auto s = schema_qualified_table(schema, t).as(sqlpp::alias::x);
|
||||||
|
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(select(all_of(s)).from(s).where(true), printer).str() << std::endl;
|
std::cerr << serialize(select(all_of(s)).from(s).unconditionally(), printer).str() << std::endl;
|
||||||
|
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(sqlpp::case_when(true).then(t.alpha).else_(t.alpha + 1).as(t.beta), printer).str()
|
std::cerr << serialize(sqlpp::case_when(true).then(t.alpha).else_(t.alpha + 1).as(t.beta), printer).str()
|
||||||
|
@ -60,7 +60,7 @@ int Remove(int, char* [])
|
|||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(r, printer).str() << std::endl;
|
std::cerr << serialize(r, printer).str() << std::endl;
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cerr << serialize(remove_from(t).where(true), printer).str() << std::endl;
|
std::cerr << serialize(remove_from(t).unconditionally(), printer).str() << std::endl;
|
||||||
|
|
||||||
db(r);
|
db(r);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ int Result(int, char* [])
|
|||||||
static_assert(not sqlpp::null_is_trivial_value_t<decltype(t.alpha)>::value, "t.alpha does not say null_is_trivial");
|
static_assert(not sqlpp::null_is_trivial_value_t<decltype(t.alpha)>::value, "t.alpha does not say null_is_trivial");
|
||||||
|
|
||||||
// Using a non-enforcing db
|
// Using a non-enforcing db
|
||||||
for (const auto& row : db(select(all_of(t), t.beta.like("")).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t), t.beta.like("")).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
||||||
static_assert(sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value, "row.alpha interprets null_is_trivial");
|
static_assert(sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value, "row.alpha interprets null_is_trivial");
|
||||||
@ -64,14 +64,14 @@ int Result(int, char* [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
sqlpp::select((t.alpha + 1).as(t.alpha)).flags(sqlpp::all).from(t);
|
sqlpp::select((t.alpha + 1).as(t.alpha)).flags(sqlpp::all).from(t);
|
||||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
||||||
static_assert(sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value, "row.alpha interprets null_is_trivial");
|
static_assert(sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value, "row.alpha interprets null_is_trivial");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using a non-enforcing db
|
// Using a non-enforcing db
|
||||||
for (const auto& row : edb(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : edb(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
||||||
static_assert(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
static_assert(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
||||||
@ -79,7 +79,7 @@ int Result(int, char* [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
sqlpp::select((t.alpha + 1).as(t.alpha)).flags(sqlpp::all).from(t);
|
sqlpp::select((t.alpha + 1).as(t.alpha)).flags(sqlpp::all).from(t);
|
||||||
for (const auto& row : edb(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : edb(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
static_assert(sqlpp::can_be_null_t<decltype(row.alpha)>::value, "row.alpha can be null");
|
||||||
static_assert(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
static_assert(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
template <typename Db, typename Column>
|
template <typename Db, typename Column>
|
||||||
int64_t getColumn(Db&& db, const Column& column)
|
int64_t getColumn(Db&& db, const Column& column)
|
||||||
{
|
{
|
||||||
auto result = db(select(column.as(sqlpp::alias::a)).from(column.table()).where(true));
|
auto result = db(select(column.as(sqlpp::alias::a)).from(column.table()).unconditionally());
|
||||||
if (not result.empty())
|
if (not result.empty())
|
||||||
return result.front().a;
|
return result.front().a;
|
||||||
else
|
else
|
||||||
@ -59,14 +59,14 @@ int Select(int, char* [])
|
|||||||
std::cout << row.a << std::endl;
|
std::cout << row.a << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
int64_t a = row.alpha;
|
int64_t a = row.alpha;
|
||||||
const std::string b = row.beta;
|
const std::string b = row.beta;
|
||||||
std::cout << a << ", " << b << std::endl;
|
std::cout << a << ", " << b << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& row : db(select(all_of(t).as(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t).as(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
int64_t a = row.tabBar.alpha;
|
int64_t a = row.tabBar.alpha;
|
||||||
const std::string b = row.tabBar.beta;
|
const std::string b = row.tabBar.beta;
|
||||||
@ -82,19 +82,19 @@ int Select(int, char* [])
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& row :
|
for (const auto& row :
|
||||||
db(select(all_of(t), all_of(f)).from(t.join(f).on(t.alpha > f.omega and not t.gamma)).where(true)))
|
db(select(all_of(t), all_of(f)).from(t.join(f).on(t.alpha > f.omega and not t.gamma)).unconditionally()))
|
||||||
{
|
{
|
||||||
std::cout << row.alpha << std::endl;
|
std::cout << row.alpha << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& row : db(select(all_of(t), all_of(f))
|
for (const auto& row : db(select(all_of(t), all_of(f))
|
||||||
.from(t.join(f).on(t.alpha > f.omega).join(tab_a).on(t.alpha == tab_a.omega))
|
.from(t.join(f).on(t.alpha > f.omega).join(tab_a).on(t.alpha == tab_a.omega))
|
||||||
.where(true)))
|
.unconditionally()))
|
||||||
{
|
{
|
||||||
std::cout << row.alpha << std::endl;
|
std::cout << row.alpha << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& row : db(select(count(t.alpha), avg(t.alpha)).from(t).where(true)))
|
for (const auto& row : db(select(count(t.alpha), avg(t.alpha)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
std::cout << row.count << std::endl;
|
std::cout << row.count << std::endl;
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ int Select(int, char* [])
|
|||||||
.dynamic_offset();
|
.dynamic_offset();
|
||||||
s.select_flags.add(sqlpp::distinct);
|
s.select_flags.add(sqlpp::distinct);
|
||||||
s.selected_columns.add(f.omega);
|
s.selected_columns.add(f.omega);
|
||||||
s.from.add(f);
|
s.from.add(dynamic_join(f).unconditionally());
|
||||||
s.where.add(t.alpha > 7);
|
s.where.add(t.alpha > 7);
|
||||||
s.having.add(t.alpha > 7);
|
s.having.add(t.alpha > 7);
|
||||||
s.limit.set(3);
|
s.limit.set(3);
|
||||||
@ -165,7 +165,7 @@ int Select(int, char* [])
|
|||||||
select(sqlpp::value(7).as(t.alpha));
|
select(sqlpp::value(7).as(t.alpha));
|
||||||
|
|
||||||
for (const auto& row :
|
for (const auto& row :
|
||||||
db(select(sqlpp::case_when(true).then(sqlpp::null).else_(sqlpp::null).as(t.beta)).from(t).where(true)))
|
db(select(sqlpp::case_when(true).then(sqlpp::null).else_(sqlpp::null).as(t.beta)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
std::cerr << row.beta << std::endl;
|
std::cerr << row.beta << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ int SelectType(int, char* [])
|
|||||||
t.alpha.as(alias::a) // index 12
|
t.alpha.as(alias::a) // index 12
|
||||||
)
|
)
|
||||||
.from(t)
|
.from(t)
|
||||||
.where(true)); // next index is 13
|
.unconditionally()); // next index is 13
|
||||||
using ResultRow = typename Select::_result_methods_t<Select>::template _result_row_t<MockDb>;
|
using ResultRow = typename Select::_result_methods_t<Select>::template _result_row_t<MockDb>;
|
||||||
using IndexSequence = ResultRow::_field_index_sequence;
|
using IndexSequence = ResultRow::_field_index_sequence;
|
||||||
static_assert(std::is_same<IndexSequence, sqlpp::detail::field_index_sequence<13, 0, 1, 2, 3, 4, 8, 12>>::value,
|
static_assert(std::is_same<IndexSequence, sqlpp::detail::field_index_sequence<13, 0, 1, 2, 3, 4, 8, 12>>::value,
|
||||||
@ -318,15 +318,16 @@ int SelectType(int, char* [])
|
|||||||
"select with identical columns(name/value_type) need to have identical result_types");
|
"select with identical columns(name/value_type) need to have identical result_types");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
for (const auto& row : db(select(all_of(t)).from(t).unconditionally()))
|
||||||
{
|
{
|
||||||
int64_t a = row.alpha;
|
int64_t a = row.alpha;
|
||||||
std::cout << a << std::endl;
|
std::cout << a << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto s = dynamic_select(db, all_of(t)).dynamic_from().dynamic_where().dynamic_limit().dynamic_offset();
|
auto s = dynamic_select(db, all_of(t)).dynamic_from(t).dynamic_where().dynamic_limit().dynamic_offset();
|
||||||
s.from.add(t);
|
#warning : Need to test the deprecated stuff
|
||||||
|
s.from.add(dynamic_join(f).on(f.omega > t.alpha));
|
||||||
s.where.add_ntc(t.alpha > 7 and t.alpha == any(select(t.alpha).from(t).where(t.alpha < 3)));
|
s.where.add_ntc(t.alpha > 7 and t.alpha == any(select(t.alpha).from(t).where(t.alpha < 3)));
|
||||||
s.limit.set(30);
|
s.limit.set(30);
|
||||||
s.limit.set(3);
|
s.limit.set(3);
|
||||||
@ -376,7 +377,7 @@ int SelectType(int, char* [])
|
|||||||
auto s1 = sqlpp::select()
|
auto s1 = sqlpp::select()
|
||||||
.flags(sqlpp::distinct, sqlpp::straight_join)
|
.flags(sqlpp::distinct, sqlpp::straight_join)
|
||||||
.columns(l.gamma, r.a)
|
.columns(l.gamma, r.a)
|
||||||
.from(r, t, l)
|
.from(r.join(t).unconditionally().join(l).unconditionally())
|
||||||
.where(t.beta == "hello world" and select(t.gamma).from(t)) // .as(alias::right))
|
.where(t.beta == "hello world" and select(t.gamma).from(t)) // .as(alias::right))
|
||||||
.group_by(l.gamma, r.a)
|
.group_by(l.gamma, r.a)
|
||||||
.having(r.a != true)
|
.having(r.a != true)
|
||||||
|
@ -37,23 +37,23 @@ int Union(int, char* [])
|
|||||||
const auto t = test::TabBar{};
|
const auto t = test::TabBar{};
|
||||||
const auto f = test::TabFoo{};
|
const auto f = test::TabFoo{};
|
||||||
|
|
||||||
db(select(t.alpha).from(t).where(true).union_distinct(select(f.epsilon.as(t.alpha)).from(f).where(true)));
|
db(select(t.alpha).from(t).unconditionally().union_distinct(select(f.epsilon.as(t.alpha)).from(f).unconditionally()));
|
||||||
db(select(t.alpha).from(t).where(true).union_all(select(f.epsilon.as(t.alpha)).from(f).where(true)));
|
db(select(t.alpha).from(t).unconditionally().union_all(select(f.epsilon.as(t.alpha)).from(f).unconditionally()));
|
||||||
|
|
||||||
auto u = select(t.alpha)
|
auto u = select(t.alpha)
|
||||||
.from(t)
|
.from(t)
|
||||||
.where(true)
|
.unconditionally()
|
||||||
.union_all(select(f.epsilon.as(t.alpha)).from(f).where(true))
|
.union_all(select(f.epsilon.as(t.alpha)).from(f).unconditionally())
|
||||||
.as(sqlpp::alias::u);
|
.as(sqlpp::alias::u);
|
||||||
|
|
||||||
db(select(all_of(u)).from(u).where(true).union_all(select(t.delta.as(t.alpha)).from(t).where(true)));
|
db(select(all_of(u)).from(u).unconditionally().union_all(select(t.delta.as(t.alpha)).from(t).unconditionally()));
|
||||||
db(select(u.alpha).from(u).where(true).union_all(select(t.delta.as(t.alpha)).from(t).where(true)));
|
db(select(u.alpha).from(u).unconditionally().union_all(select(t.delta.as(t.alpha)).from(t).unconditionally()));
|
||||||
|
|
||||||
db(select(t.alpha)
|
db(select(t.alpha)
|
||||||
.from(t)
|
.from(t)
|
||||||
.where(true)
|
.unconditionally()
|
||||||
.union_all(select(t.alpha).from(t).where(true))
|
.union_all(select(t.alpha).from(t).unconditionally())
|
||||||
.union_all(select(t.alpha).from(t).where(true)));
|
.union_all(select(t.alpha).from(t).unconditionally()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -63,11 +63,11 @@ int Update(int, char* [])
|
|||||||
|
|
||||||
db(u);
|
db(u);
|
||||||
|
|
||||||
db(update(t).set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4")).where(true));
|
db(update(t).set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4")).unconditionally());
|
||||||
db(update(t).set(t.delta = sqlpp::null).where(true));
|
db(update(t).set(t.delta = sqlpp::null).unconditionally());
|
||||||
db(update(t).set(t.delta = sqlpp::default_value).where(true));
|
db(update(t).set(t.delta = sqlpp::default_value).unconditionally());
|
||||||
|
|
||||||
db(update(t).set(t.delta += t.alpha * 2, t.beta += " and cake").where(true));
|
db(update(t).set(t.delta += t.alpha * 2, t.beta += " and cake").unconditionally());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -38,16 +38,16 @@ int With(int, char* [])
|
|||||||
|
|
||||||
auto x = sqlpp::cte(sqlpp::alias::x).as(select(all_of(t)).from(t));
|
auto x = sqlpp::cte(sqlpp::alias::x).as(select(all_of(t)).from(t));
|
||||||
|
|
||||||
db(with(x)(select(x.alpha).from(x).where(true)));
|
db(with(x)(select(x.alpha).from(x).unconditionally()));
|
||||||
|
|
||||||
auto y0 = sqlpp::cte(sqlpp::alias::y).as(select(all_of(t)).from(t));
|
auto y0 = sqlpp::cte(sqlpp::alias::y).as(select(all_of(t)).from(t));
|
||||||
auto y = y0.union_all(select(all_of(y0)).from(y0).where(false));
|
auto y = y0.union_all(select(all_of(y0)).from(y0).unconditionally());
|
||||||
|
|
||||||
std::cout << serialize(y, printer).str() << std::endl;
|
std::cout << serialize(y, printer).str() << std::endl;
|
||||||
printer.reset();
|
printer.reset();
|
||||||
std::cout << serialize(from_table(y), printer).str() << std::endl;
|
std::cout << serialize(from_table(y), printer).str() << std::endl;
|
||||||
|
|
||||||
db(with(y)(select(y.alpha).from(y).where(true)));
|
db(with(y)(select(y.alpha).from(y).unconditionally()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user