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
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
|
||||
template <typename... T>
|
||||
bad_statement(T&&...)
|
||||
{
|
||||
|
@ -40,21 +40,21 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
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 type = logical_and_t<wrap_operand_t<L>, wrap_operand_t<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 type = logical_or_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
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 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/detail/sum.h>
|
||||
#include <sqlpp11/policy_update.h>
|
||||
#include <sqlpp11/dynamic_join.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
#ifdef SQLPP_ALLOW_UNCONDITIONAL_JOIN
|
||||
constexpr bool allow_unconditional_from = 1;
|
||||
#else
|
||||
constexpr bool allow_unconditional_from = 0;
|
||||
#endif
|
||||
|
||||
// FROM DATA
|
||||
template <typename Database, typename... Tables>
|
||||
struct from_data_t
|
||||
@ -77,35 +84,40 @@ namespace sqlpp
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Table>
|
||||
void add(Table table)
|
||||
template <typename DynamicJoin>
|
||||
void add(DynamicJoin dynamicJoin)
|
||||
{
|
||||
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 =
|
||||
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
|
||||
// using _known_table_names = detail::transform_set_t<name_of, _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()");
|
||||
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::_();
|
||||
|
||||
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:
|
||||
template <typename Table>
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
template <typename DynamicJoin>
|
||||
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>
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
template <typename DynamicJoin>
|
||||
void _add_impl(DynamicJoin dynamicJoin, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
@ -210,12 +222,15 @@ namespace sqlpp
|
||||
|
||||
using _consistency_check = consistent_t;
|
||||
|
||||
template <typename... Tables>
|
||||
auto from(Tables... tables) const -> _new_statement_t<_check<Tables...>, from_t<void, from_table_t<Tables>...>>
|
||||
template <typename Table, typename... 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(sizeof...(Tables), "at least one table or join argument required in from()");
|
||||
return _from_impl<void>(_check<Tables...>{}, tables...);
|
||||
static_assert(_check<Table, Tables...>::value, "at least one argument is not a table or join in from()");
|
||||
static_assert(sizeof...(Tables) == 0 or ::sqlpp::allow_unconditional_from,
|
||||
"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>
|
||||
@ -225,6 +240,10 @@ namespace sqlpp
|
||||
static_assert(not std::is_same<_database_t, void>::value,
|
||||
"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(
|
||||
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...);
|
||||
}
|
||||
|
||||
|
@ -27,42 +27,12 @@
|
||||
#ifndef SQLPP_JOIN_H
|
||||
#define SQLPP_JOIN_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/join_types.h>
|
||||
#include <sqlpp11/on.h>
|
||||
#include <sqlpp11/noop.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 ";
|
||||
};
|
||||
|
||||
template <typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
||||
struct join_t
|
||||
{
|
||||
@ -93,6 +63,11 @@ namespace sqlpp
|
||||
return {_lhs, _rhs, {std::tuple<Expr...>{expr...}, {}}};
|
||||
}
|
||||
|
||||
auto unconditionally() -> set_on_t<on_t<void, unconditional_t>>
|
||||
{
|
||||
return {_lhs, _rhs, {}};
|
||||
}
|
||||
|
||||
template <typename 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/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/unconditional.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -72,6 +73,25 @@ namespace sqlpp
|
||||
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>
|
||||
struct serializer_t<Context, on_t<Database, Expressions...>>
|
||||
{
|
||||
@ -82,11 +102,12 @@ namespace sqlpp
|
||||
{
|
||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ON ";
|
||||
context << " ON (";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
context << " )";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
@ -38,13 +38,16 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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> class LPred,
|
||||
@ -56,17 +59,17 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template <typename L, template <typename> class LPred, typename R, template <typename> class RPred>
|
||||
struct binary_operand_check<L,
|
||||
LPred,
|
||||
R,
|
||||
RPred,
|
||||
detail::enable_if_t<LPred<wrap_operand_t<L>>::value and RPred<wrap_operand_t<R>>::value>>
|
||||
struct binary_operand_check<L, LPred, R, RPred, detail::enable_if_t<LPred<L>::value and RPred<R>::value>>
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2016, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,6 +30,7 @@
|
||||
#include <sqlpp11/column_fwd.h>
|
||||
#include <sqlpp11/interpret.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/join.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
@ -41,7 +42,6 @@ namespace sqlpp
|
||||
template <typename AliasProvider, typename Table, typename... 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>,
|
||||
tag::is_table,
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -164,6 +164,7 @@ namespace sqlpp
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_table)
|
||||
SQLPP_VALUE_TRAIT_GENERATOR(is_raw_table)
|
||||
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_column)
|
||||
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/interpret_tuple.h>
|
||||
#include <sqlpp11/interpretable_list.h>
|
||||
#include <sqlpp11/unconditional.h>
|
||||
#include <sqlpp11/logic.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -153,6 +154,7 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef SQLPP_ALLOW_NAKED_BOOL_EXPRESSION
|
||||
template <>
|
||||
struct where_data_t<void, bool>
|
||||
{
|
||||
@ -214,8 +216,70 @@ namespace sqlpp
|
||||
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,
|
||||
"at least one argument is not a boolean expression in where()");
|
||||
@ -328,10 +392,28 @@ namespace sqlpp
|
||||
assert_where_t,
|
||||
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>>
|
||||
{
|
||||
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>
|
||||
auto where(Expressions... expressions) const
|
||||
@ -387,6 +469,7 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SQLPP_ALLOW_NAKED_BOOL_EXPRESSION
|
||||
template <typename Context>
|
||||
struct serializer_t<Context, where_data_t<void, bool>>
|
||||
{
|
||||
@ -400,6 +483,19 @@ namespace sqlpp
|
||||
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>
|
||||
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(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(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
||||
|
@ -34,4 +34,5 @@ test_compile(where)
|
||||
test_compile(insert)
|
||||
test_compile(date)
|
||||
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
|
||||
void no_group_by()
|
||||
{
|
||||
run_check(select(all_of(t)).from(t).where(true));
|
||||
run_check(select(t.alpha).from(t).where(true));
|
||||
run_check(select(count(t.alpha)).from(t).where(true));
|
||||
run_check(select(all_of(t)).from(t).unconditionally());
|
||||
run_check(select(t.alpha).from(t).unconditionally());
|
||||
run_check(select(count(t.alpha)).from(t).unconditionally());
|
||||
}
|
||||
|
||||
// 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
|
||||
void dynamic_group_by()
|
||||
{
|
||||
run_check(select(all_of(t)).from(t).where(true));
|
||||
run_check(select(t.alpha).from(t).where(true));
|
||||
run_check(select(count(t.alpha)).from(t).where(true));
|
||||
run_check(select(all_of(t)).from(t).unconditionally());
|
||||
run_check(select(t.alpha).from(t).unconditionally());
|
||||
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.
|
||||
// count(t.id)) or values to be valid
|
||||
void static_group_by_ok()
|
||||
{
|
||||
run_check(select(t.alpha).from(t).where(true).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).where(true).group_by(t.alpha, t.alpha + t.delta * 17));
|
||||
run_check(
|
||||
select((t.alpha + t.delta * 17).as(whatever)).from(t).where(true).group_by(t.alpha, t.alpha + t.delta * 17));
|
||||
run_check(select((t.beta + "fortytwo").as(whatever)).from(t).where(true).group_by(t.beta));
|
||||
run_check(select(t.alpha).from(t).unconditionally().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).unconditionally().group_by(t.alpha, t.alpha + t.delta * 17));
|
||||
run_check(select((t.alpha + t.delta * 17).as(whatever))
|
||||
.from(t)
|
||||
.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(count(t.alpha)).from(t).where(true).group_by(t.beta));
|
||||
run_check(select(max(t.alpha)).from(t).where(true).group_by(t.beta));
|
||||
run_check(select(min(t.alpha)).from(t).where(true).group_by(t.beta));
|
||||
run_check(select(sum(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).unconditionally().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).unconditionally().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("whatever").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).unconditionally().group_by(t.alpha));
|
||||
}
|
||||
|
||||
// Failures with static group_by and selected non-aggregates or incorrect aggregates
|
||||
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>(
|
||||
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>(
|
||||
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
|
||||
{
|
||||
constexpr auto t = test::TabBar{};
|
||||
constexpr auto f = test::TabFoo{};
|
||||
|
||||
template <typename T>
|
||||
void print_type_on_error(std::true_type)
|
||||
|
@ -40,7 +40,7 @@ int DateTime(int, char* [])
|
||||
{
|
||||
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.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_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 */
|
||||
}
|
||||
}
|
||||
@ -286,7 +286,7 @@ int Function(int, char* [])
|
||||
static_assert(sqlpp::is_integral_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 */
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
"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)),
|
||||
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(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).where(false), printer).str();
|
||||
serialize(select(all_of(t)).from(t).unconditionally(), 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.beta, printer);
|
||||
@ -201,8 +200,8 @@ int Interpret(int, char* [])
|
||||
std::cerr << serialize(x, printer).str() << std::endl;
|
||||
|
||||
printer.reset();
|
||||
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).where(true))), printer)
|
||||
.str() << std::endl;
|
||||
std::cerr << serialize(select(all_of(t)).from(t).where(t.alpha.in(select(f.epsilon).from(f).unconditionally())),
|
||||
printer).str() << std::endl;
|
||||
|
||||
printer.reset();
|
||||
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);
|
||||
|
||||
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();
|
||||
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();
|
||||
std::cerr << serialize(r, printer).str() << std::endl;
|
||||
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);
|
||||
|
||||
|
@ -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");
|
||||
|
||||
// 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::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);
|
||||
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::null_is_trivial_value_t<decltype(row.alpha)>::value, "row.alpha interprets null_is_trivial");
|
||||
}
|
||||
|
||||
// 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(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);
|
||||
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(not sqlpp::null_is_trivial_value_t<decltype(row.alpha)>::value,
|
||||
|
@ -35,7 +35,7 @@
|
||||
template <typename Db, typename 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())
|
||||
return result.front().a;
|
||||
else
|
||||
@ -59,14 +59,14 @@ int Select(int, char* [])
|
||||
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;
|
||||
const std::string b = row.beta;
|
||||
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;
|
||||
const std::string b = row.tabBar.beta;
|
||||
@ -82,19 +82,19 @@ int Select(int, char* [])
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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))
|
||||
.where(true)))
|
||||
.unconditionally()))
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -146,7 +146,7 @@ int Select(int, char* [])
|
||||
.dynamic_offset();
|
||||
s.select_flags.add(sqlpp::distinct);
|
||||
s.selected_columns.add(f.omega);
|
||||
s.from.add(f);
|
||||
s.from.add(dynamic_join(f).unconditionally());
|
||||
s.where.add(t.alpha > 7);
|
||||
s.having.add(t.alpha > 7);
|
||||
s.limit.set(3);
|
||||
@ -165,7 +165,7 @@ int Select(int, char* [])
|
||||
select(sqlpp::value(7).as(t.alpha));
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ int SelectType(int, char* [])
|
||||
t.alpha.as(alias::a) // index 12
|
||||
)
|
||||
.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 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,
|
||||
@ -318,15 +318,16 @@ int SelectType(int, char* [])
|
||||
"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;
|
||||
std::cout << a << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
auto s = dynamic_select(db, all_of(t)).dynamic_from().dynamic_where().dynamic_limit().dynamic_offset();
|
||||
s.from.add(t);
|
||||
auto s = dynamic_select(db, all_of(t)).dynamic_from(t).dynamic_where().dynamic_limit().dynamic_offset();
|
||||
#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.limit.set(30);
|
||||
s.limit.set(3);
|
||||
@ -376,7 +377,7 @@ int SelectType(int, char* [])
|
||||
auto s1 = sqlpp::select()
|
||||
.flags(sqlpp::distinct, sqlpp::straight_join)
|
||||
.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))
|
||||
.group_by(l.gamma, r.a)
|
||||
.having(r.a != true)
|
||||
|
@ -37,23 +37,23 @@ int Union(int, char* [])
|
||||
const auto t = test::TabBar{};
|
||||
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).where(true).union_all(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).unconditionally().union_all(select(f.epsilon.as(t.alpha)).from(f).unconditionally()));
|
||||
|
||||
auto u = select(t.alpha)
|
||||
.from(t)
|
||||
.where(true)
|
||||
.union_all(select(f.epsilon.as(t.alpha)).from(f).where(true))
|
||||
.unconditionally()
|
||||
.union_all(select(f.epsilon.as(t.alpha)).from(f).unconditionally())
|
||||
.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(u.alpha).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).unconditionally().union_all(select(t.delta.as(t.alpha)).from(t).unconditionally()));
|
||||
|
||||
db(select(t.alpha)
|
||||
.from(t)
|
||||
.where(true)
|
||||
.union_all(select(t.alpha).from(t).where(true))
|
||||
.union_all(select(t.alpha).from(t).where(true)));
|
||||
.unconditionally()
|
||||
.union_all(select(t.alpha).from(t).unconditionally())
|
||||
.union_all(select(t.alpha).from(t).unconditionally()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -63,11 +63,11 @@ int Update(int, char* [])
|
||||
|
||||
db(u);
|
||||
|
||||
db(update(t).set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4")).where(true));
|
||||
db(update(t).set(t.delta = sqlpp::null).where(true));
|
||||
db(update(t).set(t.delta = sqlpp::default_value).where(true));
|
||||
db(update(t).set(t.delta = sqlpp::verbatim<sqlpp::integer>("17+4")).unconditionally());
|
||||
db(update(t).set(t.delta = sqlpp::null).unconditionally());
|
||||
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;
|
||||
}
|
||||
|
@ -38,16 +38,16 @@ int With(int, char* [])
|
||||
|
||||
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 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;
|
||||
printer.reset();
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user