0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Merge branch 'release/0.42'

This commit is contained in:
rbock 2016-09-03 13:19:28 +02:00
commit 781d63673f
47 changed files with 655 additions and 688 deletions

View File

@ -4,6 +4,12 @@ A type safe embedded domain specific language for SQL queries and results in C++
Documentation is found in the [wiki](https://github.com/rbock/sqlpp11/wiki) Documentation is found in the [wiki](https://github.com/rbock/sqlpp11/wiki)
Contact:
--------
* Meet me at [CppCon 2016](https://cppcon2016.sched.org/event/7nKk)
* Issues at https://github.com/rbock/sqlpp11/issues
* email at rbock at eudoxos dot de
* [![Join the chat at https://gitter.im/sqlpp11/Lobby](https://badges.gitter.im/sqlpp11/Lobby.svg)](https://gitter.im/sqlpp11/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Breaking changes in 0.36: Breaking changes in 0.36:
------------------------- -------------------------
@ -109,9 +115,7 @@ Past talks about sqlpp11 and some coding concepts used within the library:
* [MUC++:](http://www.meetup.com/MUCplusplus/) * [MUC++:](http://www.meetup.com/MUCplusplus/)
* 2014-02-27: [Selected C++11 Template Toffees From sqlpp11, Part1](https://www.youtube.com/watch?v=hXnGFYNbmXg), [Part2](https://www.youtube.com/watch?v=WPCV6dvxZ_U), [Part 3](https://www.youtube.com/watch?v=eB7hd_KjTig), [Part 4](https://www.youtube.com/watch?v=NBfqzcN0_EQ) * 2014-02-27: [Selected C++11 Template Toffees From sqlpp11, Part1](https://www.youtube.com/watch?v=hXnGFYNbmXg), [Part2](https://www.youtube.com/watch?v=WPCV6dvxZ_U), [Part 3](https://www.youtube.com/watch?v=eB7hd_KjTig), [Part 4](https://www.youtube.com/watch?v=NBfqzcN0_EQ)
You can contact me
* by posting issues at https://github.com/rbock/sqlpp11/issues
* or via email at rbock at eudoxos dot de
Requirements: Requirements:

View File

@ -27,8 +27,8 @@
#ifndef SQLPP_ALL_OF_H #ifndef SQLPP_ALL_OF_H
#define SQLPP_ALL_OF_H #define SQLPP_ALL_OF_H
#include <sqlpp11/interpret.h>
#include <sqlpp11/alias.h> #include <sqlpp11/alias.h>
#include <sqlpp11/interpret.h>
#include <sqlpp11/multi_column.h> #include <sqlpp11/multi_column.h>
#include <sqlpp11/portable_static_assert.h> #include <sqlpp11/portable_static_assert.h>
@ -62,7 +62,7 @@ namespace sqlpp
static Context& _(const T&, const Context&) static Context& _(const T&, const Context&)
{ {
_serialize_check::_(); _serialize_check{};
} }
}; };
} }

View File

@ -27,10 +27,10 @@
#ifndef SQLPP_CASE_H #ifndef SQLPP_CASE_H
#define SQLPP_CASE_H #define SQLPP_CASE_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/char_sequence.h> #include <sqlpp11/char_sequence.h>
#include <sqlpp11/data_types/boolean.h> #include <sqlpp11/data_types/boolean.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -87,13 +87,13 @@ namespace sqlpp
class case_then_t class case_then_t
{ {
template <typename Else> template <typename Else>
auto _else_impl(const std::true_type&, Else else_) -> case_t<When, Then, Else> auto _else_impl(consistent_t, Else else_) -> case_t<When, Then, Else>
{ {
return {_when, _then, else_}; return {_when, _then, else_};
} }
template <typename Else> template <typename Check, typename Else>
auto _else_impl(const std::false_type&, Else else_) -> void; auto _else_impl(Check, Else else_) -> inconsistent<Check>;
public: public:
case_then_t(When when, Then then) : _when(when), _then(then) case_then_t(When when, Then then) : _when(when), _then(then)
@ -109,7 +109,6 @@ namespace sqlpp
template <typename Else> template <typename Else>
auto else_(Else else_) -> decltype(this->_else_impl(check_case_else_t<Then, Else>{}, else_)) auto else_(Else else_) -> decltype(this->_else_impl(check_case_else_t<Then, Else>{}, else_))
{ {
check_case_else_t<Then, Else>::_();
return _else_impl(check_case_else_t<Then, Else>{}, else_); return _else_impl(check_case_else_t<Then, Else>{}, else_);
} }
@ -122,13 +121,13 @@ namespace sqlpp
class case_when_t class case_when_t
{ {
template <typename Then> template <typename Then>
auto _then_impl(const std::true_type&, Then t) -> case_then_t<When, wrap_operand_t<Then>> auto _then_impl(consistent_t, Then t) -> case_then_t<When, wrap_operand_t<Then>>
{ {
return {_when, t}; return {_when, t};
} }
template <typename Then> template <typename Check, typename Then>
auto _then_impl(const std::false_type&, Then t) -> void; auto _then_impl(Check, Then t) -> inconsistent<Check>;
public: public:
case_when_t(When when) : _when(when) case_when_t(When when) : _when(when)
@ -144,7 +143,6 @@ namespace sqlpp
template <typename Then> template <typename Then>
auto then(Then t) -> decltype(this->_then_impl(check_case_then_t<Then>{}, t)) auto then(Then t) -> decltype(this->_then_impl(check_case_then_t<Then>{}, t))
{ {
check_case_then_t<Then>::_();
return _then_impl(check_case_then_t<Then>{}, t); return _then_impl(check_case_then_t<Then>{}, t);
} }
@ -174,21 +172,19 @@ namespace sqlpp
namespace detail namespace detail
{ {
template <typename When> template <typename When>
auto case_when_impl(const std::true_type&, When when) -> case_when_t<wrap_operand_t<When>> auto case_when_impl(consistent_t, When when) -> case_when_t<wrap_operand_t<When>>
{ {
return {when}; return {when};
} }
template <typename When> template <typename Check, typename When>
auto case_when_impl(const std::false_type&, When when) -> void; auto case_when_impl(Check, When when) -> inconsistent<Check>;
} }
template <typename When> template <typename When>
auto case_when(When when) -> decltype(detail::case_when_impl(check_case_when_t<When>{}, when)) auto case_when(When when) -> decltype(detail::case_when_impl(check_case_when_t<When>{}, when))
{ {
check_case_when_t<When>::_(); return detail::case_when_impl(check_case_when_t<When>{}, when);
return detail::case_when_impl(typename check_case_when_t<When>::type{}, when);
} }
} }

View File

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

View File

@ -92,14 +92,14 @@ namespace sqlpp
template <typename Db> template <typename Db>
auto _run(Db& db) const -> decltype(std::declval<_methods_t>()._run(db, *this)) auto _run(Db& db) const -> decltype(std::declval<_methods_t>()._run(db, *this))
{ {
_run_check::_(); _run_check{}; // FIXME: dispatch here?
return _methods_t::_run(db, *this); return _methods_t::_run(db, *this);
} }
template <typename Db> template <typename Db>
auto _prepare(Db& db) const -> decltype(std::declval<_methods_t>()._prepare(db, *this)) auto _prepare(Db& db) const -> decltype(std::declval<_methods_t>()._prepare(db, *this))
{ {
_prepare_check::_(); _prepare_check{}; // FIXME: dispatch here?
return _methods_t::_prepare(db, *this); return _methods_t::_prepare(db, *this);
} }

View File

@ -91,10 +91,8 @@ namespace sqlpp
template <typename Expr> template <typename Expr>
auto on(Expr expr) const -> typename std::conditional<check_dynamic_join_on_t<dynamic_pre_join_t, Expr>::value, auto on(Expr expr) const -> typename std::conditional<check_dynamic_join_on_t<dynamic_pre_join_t, Expr>::value,
dynamic_join_t<dynamic_pre_join_t, on_t<Expr>>, dynamic_join_t<dynamic_pre_join_t, on_t<Expr>>,
bad_statement>::type check_dynamic_join_on_t<dynamic_pre_join_t, Expr>>::type
{ {
check_dynamic_join_on_t<dynamic_pre_join_t, Expr>::_();
return {*this, {expr}}; return {*this, {expr}};
} }
@ -119,40 +117,40 @@ namespace sqlpp
template <typename JoinType, typename Table> template <typename JoinType, typename Table>
using make_dynamic_pre_join_t = typename std::conditional<check_dynamic_pre_join_t<Table>::value, using make_dynamic_pre_join_t = typename std::conditional<check_dynamic_pre_join_t<Table>::value,
dynamic_pre_join_t<JoinType, Table>, dynamic_pre_join_t<JoinType, Table>,
bad_statement>::type; check_dynamic_pre_join_t<Table>>::type;
template <typename Table> template <typename Table>
auto dynamic_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table> auto dynamic_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table>
{ {
check_dynamic_pre_join_t<Table>::_(); check_dynamic_pre_join_t<Table>{}; // FIXME: Failure return type?
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_inner_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table> auto dynamic_inner_join(Table table) -> make_dynamic_pre_join_t<inner_join_t, Table>
{ {
check_dynamic_pre_join_t<Table>::_(); check_dynamic_pre_join_t<Table>{};
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_left_outer_join(Table table) -> make_dynamic_pre_join_t<left_outer_join_t, Table> auto dynamic_left_outer_join(Table table) -> make_dynamic_pre_join_t<left_outer_join_t, Table>
{ {
check_dynamic_pre_join_t<Table>::_(); check_dynamic_pre_join_t<Table>{};
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_right_outer_join(Table table) -> make_dynamic_pre_join_t<right_outer_join_t, Table> auto dynamic_right_outer_join(Table table) -> make_dynamic_pre_join_t<right_outer_join_t, Table>
{ {
check_dynamic_pre_join_t<Table>::_(); check_dynamic_pre_join_t<Table>{};
return {table}; return {table};
} }
template <typename Table> template <typename Table>
auto dynamic_outer_join(Table table) -> make_dynamic_pre_join_t<outer_join_t, Table> auto dynamic_outer_join(Table table) -> make_dynamic_pre_join_t<outer_join_t, Table>
{ {
check_dynamic_pre_join_t<Table>::_(); check_dynamic_pre_join_t<Table>{};
return {table}; return {table};
} }
@ -160,9 +158,8 @@ namespace sqlpp
auto dynamic_cross_join(Table table) -> auto dynamic_cross_join(Table table) ->
typename std::conditional<check_dynamic_pre_join_t<Table>::value, typename std::conditional<check_dynamic_pre_join_t<Table>::value,
dynamic_join_t<dynamic_pre_join_t<cross_join_t, Table>, on_t<unconditional_t>>, dynamic_join_t<dynamic_pre_join_t<cross_join_t, Table>, on_t<unconditional_t>>,
bad_statement>::type check_dynamic_pre_join_t<Table>>::type
{ {
check_dynamic_pre_join_t<Table>::_();
return {dynamic_pre_join_t<cross_join_t, Table>{table}, {}}; return {dynamic_pre_join_t<cross_join_t, Table>{table}, {}};
} }
} }

View File

@ -27,15 +27,15 @@
#ifndef SQLPP_FROM_H #ifndef SQLPP_FROM_H
#define SQLPP_FROM_H #define SQLPP_FROM_H
#include <sqlpp11/detail/sum.h>
#include <sqlpp11/dynamic_join.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/table_ref.h> #include <sqlpp11/table_ref.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/detail/sum.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/dynamic_join.h>
namespace sqlpp namespace sqlpp
{ {
@ -116,23 +116,22 @@ namespace sqlpp
} }
template <typename DynamicJoin> template <typename DynamicJoin>
auto add(DynamicJoin dynamicJoin) -> auto add(DynamicJoin dynamicJoin) -> typename std::
typename std::conditional<check_from_add_t<_impl_t, DynamicJoin>::value, void, bad_statement>::type conditional<check_from_add_t<_impl_t, DynamicJoin>::value, void, check_from_add_t<_impl_t, DynamicJoin>>::type
{ {
using Check = check_from_add_t<_impl_t, DynamicJoin>; using Check = check_from_add_t<_impl_t, DynamicJoin>;
Check::_();
return _add_impl(dynamicJoin, Check{}); return _add_impl(dynamicJoin, Check{});
} }
private: private:
template <typename DynamicJoin> template <typename DynamicJoin>
auto _add_impl(DynamicJoin dynamicJoin, const std::true_type&) -> void auto _add_impl(DynamicJoin dynamicJoin, consistent_t) -> void
{ {
_data._dynamic_tables.emplace_back(from_table(dynamicJoin)); _data._dynamic_tables.emplace_back(from_table(dynamicJoin));
} }
template <typename DynamicJoin> template <typename Check, typename DynamicJoin>
auto _add_impl(DynamicJoin dynamicJoin, const std::false_type&) -> bad_statement; auto _add_impl(DynamicJoin dynamicJoin, Check) -> inconsistent<Check>;
public: public:
_data_t _data; _data_t _data;
@ -146,8 +145,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : from{std::forward<Args>(args)...}
: from{std::forward<Args>(args)...}
{ {
} }
@ -234,8 +232,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_from{std::forward<Args>(args)...}
: no_from{std::forward<Args>(args)...}
{ {
} }
@ -258,7 +255,7 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_from_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_from_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
@ -266,7 +263,6 @@ namespace sqlpp
auto from(Table table) const -> _new_statement_t<check_from_static_t<Table>, from_t<void, from_table_t<Table>>> auto from(Table table) const -> _new_statement_t<check_from_static_t<Table>, from_t<void, from_table_t<Table>>>
{ {
using Check = check_from_static_t<Table>; using Check = check_from_static_t<Table>;
Check{}._();
return _from_impl<void>(Check{}, table); return _from_impl<void>(Check{}, table);
} }
@ -275,17 +271,16 @@ namespace sqlpp
-> _new_statement_t<check_from_dynamic_t<_database_t, Table>, from_t<_database_t, from_table_t<Table>>> -> _new_statement_t<check_from_dynamic_t<_database_t, Table>, from_t<_database_t, from_table_t<Table>>>
{ {
using Check = check_from_dynamic_t<_database_t, Table>; using Check = check_from_dynamic_t<_database_t, Table>;
Check{}._();
return _from_impl<_database_t>(Check{}, table); return _from_impl<_database_t>(Check{}, table);
} }
private: private:
template <typename Database, typename Table> template <typename Database, typename Check, typename Table>
auto _from_impl(const std::false_type&, Table table) const -> bad_statement; auto _from_impl(Check, Table table) const -> inconsistent<Check>;
template <typename Database, typename Table> template <typename Database, typename Table>
auto _from_impl(const std::true_type&, Table table) const auto _from_impl(consistent_t, Table table) const
-> _new_statement_t<std::true_type, from_t<Database, from_table_t<Table>>> -> _new_statement_t<consistent_t, from_t<Database, from_table_t<Table>>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
from_data_t<Database, from_table_t<Table>>{from_table(table)}}; from_data_t<Database, from_table_t<Table>>{from_table(table)}};

View File

@ -27,13 +27,13 @@
#ifndef SQLPP_GROUP_BY_H #ifndef SQLPP_GROUP_BY_H
#define SQLPP_GROUP_BY_H #define SQLPP_GROUP_BY_H
#include <tuple>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/expression.h> #include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h> #include <sqlpp11/interpretable_list.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/logic.h> #include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
#include <tuple>
namespace sqlpp namespace sqlpp
{ {
@ -67,9 +67,8 @@ namespace sqlpp
using _nodes = detail::type_vector<Expressions...>; using _nodes = detail::type_vector<Expressions...>;
using _is_dynamic = is_database<Database>; using _is_dynamic = is_database<Database>;
using _provided_aggregates = typename std::conditional<_is_dynamic::value, using _provided_aggregates = typename std::
detail::type_set<>, conditional<_is_dynamic::value, detail::type_set<>, detail::make_type_set_t<Expressions...>>::type;
detail::make_type_set_t<Expressions...>>::type;
// Data // Data
using _data_t = group_by_data_t<Database, Expressions...>; using _data_t = group_by_data_t<Database, Expressions...>;
@ -92,7 +91,7 @@ namespace sqlpp
static_assert(Policies::template _no_unknown_tables<Expression>::value, static_assert(Policies::template _no_unknown_tables<Expression>::value,
"expression uses tables unknown to this statement in group_by::add()"); "expression uses tables unknown to this statement in group_by::add()");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expression>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expression>::value, _serialize_check::type::value>;
@ -121,8 +120,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : group_by{std::forward<Args>(args)...}
: group_by{std::forward<Args>(args)...}
{ {
} }
@ -148,6 +146,17 @@ namespace sqlpp
}; };
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_group_by_args_are_expressions_t,
"arguments for group_by() must be valid expressions");
template <typename... Exprs>
struct check_group_by
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_expression_t<Exprs>::value...>::value, assert_group_by_args_are_expressions_t>>;
};
template <typename... Exprs>
using check_group_by_t = typename check_group_by<Exprs...>::type;
// NO GROUP BY YET // NO GROUP BY YET
struct no_group_by_t struct no_group_by_t
{ {
@ -178,8 +187,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_group_by{std::forward<Args>(args)...}
: no_group_by{std::forward<Args>(args)...}
{ {
} }
@ -201,47 +209,37 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _check = logic::all_t<is_expression_t<T>::value...>;
template <typename... T>
struct _check : logic::all_t<is_expression_t<T>::value...>
{
};
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_group_by_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_group_by_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename... Expressions> template <typename... Expressions>
auto group_by(Expressions... expressions) const auto group_by(Expressions... expressions) const
-> _new_statement_t<_check<Expressions...>, group_by_t<void, Expressions...>> -> _new_statement_t<check_group_by_t<Expressions...>, group_by_t<void, Expressions...>>
{ {
static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()"); static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in group_by()");
return _group_by_impl<void>(_check<Expressions...>{}, expressions...); return _group_by_impl<void>(check_group_by_t<Expressions...>{}, expressions...);
} }
template <typename... Expressions> template <typename... Expressions>
auto dynamic_group_by(Expressions... expressions) const auto dynamic_group_by(Expressions... expressions) const
-> _new_statement_t<_check<Expressions...>, group_by_t<_database_t, Expressions...>> -> _new_statement_t<check_group_by_t<Expressions...>, group_by_t<_database_t, Expressions...>>
{ {
static_assert(not std::is_same<_database_t, void>::value, static_assert(not std::is_same<_database_t, void>::value,
"dynamic_group_by must not be called in a static statement"); "dynamic_group_by must not be called in a static statement");
static_assert(_check<Expressions...>::value, "at least one argument is not an expression in group_by()");
return _group_by_impl<_database_t>(_check<Expressions...>{}, expressions...); return _group_by_impl<_database_t>(check_group_by_t<Expressions...>{}, expressions...);
} }
private: private:
template <typename Database, typename... Expressions> template <typename Database, typename Check, typename... Expressions>
auto _group_by_impl(const std::false_type&, Expressions... expressions) const -> bad_statement; auto _group_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
template <typename Database, typename... Expressions> template <typename Database, typename... Expressions>
auto _group_by_impl(const std::true_type&, Expressions... expressions) const auto _group_by_impl(consistent_t, Expressions... expressions) const
-> _new_statement_t<std::true_type, group_by_t<Database, Expressions...>> -> _new_statement_t<consistent_t, group_by_t<Database, Expressions...>>
{ {
static_assert(not detail::has_duplicates<Expressions...>::value, static_assert(not detail::has_duplicates<Expressions...>::value,
"at least one duplicate argument detected in group_by()"); "at least one duplicate argument detected in group_by()");

View File

@ -27,13 +27,13 @@
#ifndef SQLPP_HAVING_H #ifndef SQLPP_HAVING_H
#define SQLPP_HAVING_H #define SQLPP_HAVING_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/value.h>
#include <sqlpp11/expression.h> #include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h> #include <sqlpp11/interpretable_list.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/logic.h> #include <sqlpp11/logic.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/value.h>
namespace sqlpp namespace sqlpp
{ {
@ -92,7 +92,7 @@ namespace sqlpp
static_assert(Policies::template _no_unknown_tables<Expr>::value, static_assert(Policies::template _no_unknown_tables<Expr>::value,
"expression uses tables unknown to this statement in having::add()"); "expression uses tables unknown to this statement in having::add()");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expr>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expr>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value, _serialize_check::type::value>;
@ -121,8 +121,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : having{std::forward<Args>(args)...}
: having{std::forward<Args>(args)...}
{ {
} }
@ -212,8 +211,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_having{std::forward<Args>(args)...}
: no_having{std::forward<Args>(args)...}
{ {
} }
@ -244,7 +242,7 @@ namespace sqlpp
}; };
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_having_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_having_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
@ -253,7 +251,6 @@ namespace sqlpp
-> _new_statement_t<check_having_static_t<Expression>, having_t<void, Expression>> -> _new_statement_t<check_having_static_t<Expression>, having_t<void, Expression>>
{ {
using Check = check_having_static_t<Expression>; using Check = check_having_static_t<Expression>;
Check{}._();
return _having_impl<void>(Check{}, expression); return _having_impl<void>(Check{}, expression);
} }
@ -263,7 +260,6 @@ namespace sqlpp
-> _new_statement_t<check_having_dynamic_t<_database_t, Expression>, having_t<_database_t, Expression>> -> _new_statement_t<check_having_dynamic_t<_database_t, Expression>, having_t<_database_t, Expression>>
{ {
using Check = check_having_dynamic_t<_database_t, Expression>; using Check = check_having_dynamic_t<_database_t, Expression>;
Check{}._();
return _having_impl<_database_t>(Check{}, expression); return _having_impl<_database_t>(Check{}, expression);
} }
@ -275,12 +271,12 @@ namespace sqlpp
} }
private: private:
template <typename Database, typename Expression> template <typename Database, typename Check, typename Expression>
auto _having_impl(const std::false_type&, Expression expression) const -> bad_statement; auto _having_impl(Check, Expression expression) const -> inconsistent<Check>;
template <typename Database, typename Expression> template <typename Database, typename Expression>
auto _having_impl(const std::true_type&, Expression expression) const auto _having_impl(consistent_t, Expression expression) const
-> _new_statement_t<std::true_type, having_t<Database, Expression>> -> _new_statement_t<consistent_t, having_t<Database, Expression>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
having_data_t<Database, Expression>{expression}}; having_data_t<Database, Expression>{expression}};

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2016-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,
@ -24,20 +24,22 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_BAD_STATEMENT_H #ifndef SQLPP_INCONSISTENT_H
#define SQLPP_BAD_STATEMENT_H #define SQLPP_INCONSISTENT_H
#include <utility>
namespace sqlpp namespace sqlpp
{ {
struct bad_statement #if defined(__clang__) || defined(_MSC_VER)
{ template <typename Check>
static constexpr bool value = false; using inconsistent = Check;
#else
template <typename... T> // This version circumvents an ambiguity problem with gcc
bad_statement(T&&...) // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77449
{ template <typename Check>
} using inconsistent = typename std::enable_if<not std::is_same<consistent_t, Check>::value, Check>::type;
}; #endif
} }
#endif #endif

View File

@ -27,19 +27,19 @@
#ifndef SQLPP_INSERT_VALUE_LIST_H #ifndef SQLPP_INSERT_VALUE_LIST_H
#define SQLPP_INSERT_VALUE_LIST_H #define SQLPP_INSERT_VALUE_LIST_H
#include <sqlpp11/type_traits.h> #include <sqlpp11/assignment.h>
#include <sqlpp11/portable_static_assert.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/column_fwd.h> #include <sqlpp11/column_fwd.h>
#include <sqlpp11/expression_fwd.h> #include <sqlpp11/expression_fwd.h>
#include <sqlpp11/assignment.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/insert_value.h> #include <sqlpp11/insert_value.h>
#include <sqlpp11/simple_column.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h> #include <sqlpp11/no_data.h>
#include <sqlpp11/policy_update.h> #include <sqlpp11/policy_update.h>
#include <sqlpp11/portable_static_assert.h>
#include <sqlpp11/simple_column.h>
#include <sqlpp11/statement.h> #include <sqlpp11/statement.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -96,8 +96,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : default_values{std::forward<Args>(args)...}
: default_values{std::forward<Args>(args)...}
{ {
} }
@ -264,7 +263,7 @@ namespace sqlpp
static_assert(Policies::template _no_unknown_tables<Assignment>::value, static_assert(Policies::template _no_unknown_tables<Assignment>::value,
"add() contains a column from a foreign table"); "add() contains a column from a foreign table");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Assignment>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Assignment>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_assignment_t<Assignment>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_assignment_t<Assignment>::value, _serialize_check::type::value>;
@ -294,8 +293,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : insert_list{std::forward<Args>(args)...}
: insert_list{std::forward<Args>(args)...}
{ {
} }
@ -400,8 +398,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : values{std::forward<Args>(args)...}
: values{std::forward<Args>(args)...}
{ {
} }
@ -429,6 +426,16 @@ namespace sqlpp
SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_values_t, "insert values required, e.g. set(...) or default_values()"); SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_values_t, "insert values required, e.g. set(...) or default_values()");
SQLPP_PORTABLE_STATIC_ASSERT(assert_insert_columns_are_columns, "arguments for columns() must be table columns");
template <typename... Columns>
struct check_insert_columns
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_column_t<Columns>::value...>::value, assert_insert_columns_are_columns>>;
};
template <typename... Columns>
using check_insert_columns_t = typename check_insert_columns<Columns...>::type;
// NO INSERT COLUMNS/VALUES YET // NO INSERT COLUMNS/VALUES YET
struct no_insert_value_list_t struct no_insert_value_list_t
{ {
@ -459,8 +466,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_insert_values{std::forward<Args>(args)...}
: no_insert_values{std::forward<Args>(args)...}
{ {
} }
@ -482,32 +488,23 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _column_check = logic::all_t<is_column_t<T>::value...>;
template <typename... T>
struct _column_check : logic::all_t<is_column_t<T>::value...>
{
};
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_insert_value_list_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_insert_value_list_t, T>;
using _consistency_check = assert_insert_values_t; using _consistency_check = assert_insert_values_t;
auto default_values() const -> _new_statement_t<std::true_type, insert_default_values_t> auto default_values() const -> _new_statement_t<consistent_t, insert_default_values_t>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), insert_default_values_data_t{}}; return {static_cast<const derived_statement_t<Policies>&>(*this), insert_default_values_data_t{}};
} }
template <typename... Columns> template <typename... Columns>
auto columns(Columns... cols) const -> _new_statement_t<_column_check<Columns...>, column_list_t<Columns...>> auto columns(Columns... cols) const
-> _new_statement_t<check_insert_columns_t<Columns...>, column_list_t<Columns...>>
{ {
static_assert(logic::all_t<is_column_t<Columns>::value...>::value,
"at least one argument is not a column in columns()");
static_assert(sizeof...(Columns), "at least one column required in columns()"); static_assert(sizeof...(Columns), "at least one column required in columns()");
return _columns_impl(_column_check<Columns...>{}, cols...); return _columns_impl(check_insert_columns_t<Columns...>{}, cols...);
} }
template <typename... Assignments> template <typename... Assignments>
@ -515,8 +512,6 @@ namespace sqlpp
-> _new_statement_t<check_insert_static_set_t<Assignments...>, insert_list_t<void, Assignments...>> -> _new_statement_t<check_insert_static_set_t<Assignments...>, insert_list_t<void, Assignments...>>
{ {
using Check = check_insert_static_set_t<Assignments...>; using Check = check_insert_static_set_t<Assignments...>;
Check{}._();
return _set_impl<void>(Check{}, assignments...); return _set_impl<void>(Check{}, assignments...);
} }
@ -526,18 +521,16 @@ namespace sqlpp
insert_list_t<_database_t, Assignments...>> insert_list_t<_database_t, Assignments...>>
{ {
using Check = check_insert_dynamic_set_t<_database_t, Assignments...>; using Check = check_insert_dynamic_set_t<_database_t, Assignments...>;
Check{}._();
return _set_impl<_database_t>(Check{}, assignments...); return _set_impl<_database_t>(Check{}, assignments...);
} }
private: private:
template <typename... Columns> template <typename Check, typename... Columns>
auto _columns_impl(const std::false_type&, Columns... cols) const -> bad_statement; auto _columns_impl(Check, Columns... cols) const -> inconsistent<Check>;
template <typename... Columns> template <typename... Columns>
auto _columns_impl(const std::true_type&, Columns... cols) const auto _columns_impl(consistent_t, Columns... cols) const
-> _new_statement_t<std::true_type, column_list_t<Columns...>> -> _new_statement_t<consistent_t, column_list_t<Columns...>>
{ {
static_assert(not detail::has_duplicates<Columns...>::value, static_assert(not detail::has_duplicates<Columns...>::value,
"at least one duplicate argument detected in columns()"); "at least one duplicate argument detected in columns()");
@ -552,12 +545,12 @@ namespace sqlpp
return {static_cast<const derived_statement_t<Policies>&>(*this), column_list_data_t<Columns...>{cols...}}; return {static_cast<const derived_statement_t<Policies>&>(*this), column_list_data_t<Columns...>{cols...}};
} }
template <typename Database, typename... Assignments> template <typename Database, typename Check, typename... Assignments>
auto _set_impl(std::false_type, Assignments... assignments) const -> bad_statement; auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
template <typename Database, typename... Assignments> template <typename Database, typename... Assignments>
auto _set_impl(std::true_type, Assignments... assignments) const auto _set_impl(consistent_t, Assignments... assignments) const
-> _new_statement_t<std::true_type, insert_list_t<Database, Assignments...>> -> _new_statement_t<consistent_t, insert_list_t<Database, Assignments...>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
insert_list_data_t<Database, Assignments...>{assignments...}}; insert_list_data_t<Database, Assignments...>{assignments...}};

View File

@ -27,8 +27,8 @@
#ifndef SQLPP_INTERPRETABLE_LIST_H #ifndef SQLPP_INTERPRETABLE_LIST_H
#define SQLPP_INTERPRETABLE_LIST_H #define SQLPP_INTERPRETABLE_LIST_H
#include <vector>
#include <sqlpp11/interpretable.h> #include <sqlpp11/interpretable.h>
#include <vector>
namespace sqlpp namespace sqlpp
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2013-2016, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -27,13 +27,13 @@
#ifndef SQLPP_INTO_H #ifndef SQLPP_INTO_H
#define SQLPP_INTO_H #define SQLPP_INTO_H
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/data_types/no_value.h> #include <sqlpp11/data_types/no_value.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/no_data.h> #include <sqlpp11/no_data.h>
#include <sqlpp11/prepared_insert.h> #include <sqlpp11/prepared_insert.h>
#include <sqlpp11/serializer.h> #include <sqlpp11/serializer.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -88,8 +88,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : into{std::forward<Args>(args)...}
: into{std::forward<Args>(args)...}
{ {
} }
@ -115,6 +114,15 @@ namespace sqlpp
SQLPP_PORTABLE_STATIC_ASSERT(assert_into_t, "into() required"); SQLPP_PORTABLE_STATIC_ASSERT(assert_into_t, "into() required");
SQLPP_PORTABLE_STATIC_ASSERT(assert_into_arg_is_table, "argument for into() must be a table");
template <typename T>
struct check_into
{
using type = static_combined_check_t<static_check_t<is_raw_table_t<T>::value, assert_into_arg_is_table>>;
};
template <typename T>
using check_into_t = typename check_into<wrap_operand_t<T>>::type;
// NO INTO YET // NO INTO YET
struct no_into_t struct no_into_t
{ {
@ -155,28 +163,23 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename T>
using _check = logic::all_t<is_raw_table_t<T>::value>;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_into_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_into_t, T>;
using _consistency_check = assert_into_t; using _consistency_check = assert_into_t;
template <typename Table> template <typename Table>
auto into(Table table) const -> _new_statement_t<_check<Table>, into_t<void, Table>> auto into(Table table) const -> _new_statement_t<check_into_t<Table>, into_t<void, Table>>
{ {
static_assert(_check<Table>::value, "argument is not a raw table in into()"); return _into_impl<void>(check_into_t<Table>{}, table);
return _into_impl<void>(_check<Table>{}, table);
} }
private: private:
template <typename Database, typename Table> template <typename Database, typename Check, typename Table>
auto _into_impl(const std::false_type&, Table table) const -> bad_statement; auto _into_impl(Check, Table table) const -> inconsistent<Check>;
template <typename Database, typename Table> template <typename Database, typename Table>
auto _into_impl(const std::true_type&, Table table) const auto _into_impl(consistent_t, Table table) const -> _new_statement_t<consistent_t, into_t<Database, Table>>
-> _new_statement_t<std::true_type, into_t<Database, Table>>
{ {
static_assert(required_tables_of<into_t<Database, Table>>::size::value == 0, static_assert(required_tables_of<into_t<Database, Table>>::size::value == 0,
"argument depends on another table in into()"); "argument depends on another table in into()");

View File

@ -27,9 +27,9 @@
#ifndef SQLPP_LIMIT_H #ifndef SQLPP_LIMIT_H
#define SQLPP_LIMIT_H #define SQLPP_LIMIT_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -81,8 +81,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : limit{std::forward<Args>(args)...}
: limit{std::forward<Args>(args)...}
{ {
} }
@ -115,8 +114,7 @@ namespace sqlpp
} }
template <typename Limit> template <typename Limit>
dynamic_limit_data_t(Limit value) dynamic_limit_data_t(Limit value) : _initialized(true), _value(wrap_operand_t<Limit>(value))
: _initialized(true), _value(wrap_operand_t<Limit>(value))
{ {
} }
@ -172,8 +170,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : limit{std::forward<Args>(args)...}
: limit{std::forward<Args>(args)...}
{ {
} }
@ -197,6 +194,15 @@ namespace sqlpp
}; };
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_limit_is_integral, "argument for limit() must be an integral expressions");
template <typename T>
struct check_limit
{
using type = static_combined_check_t<static_check_t<is_integral_t<T>::value, assert_limit_is_integral>>;
};
template <typename T>
using check_limit_t = typename check_limit<wrap_operand_t<T>>::type;
struct no_limit_t struct no_limit_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
@ -226,8 +232,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_limit{std::forward<Args>(args)...}
: no_limit{std::forward<Args>(args)...}
{ {
} }
@ -249,32 +254,28 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename T>
using _check = is_integral_t<wrap_operand_t<T>>;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_limit_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_limit_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename Arg> template <typename Arg>
auto limit(Arg arg) const -> _new_statement_t<_check<Arg>, limit_t<wrap_operand_t<Arg>>> auto limit(Arg arg) const -> _new_statement_t<check_limit_t<Arg>, limit_t<wrap_operand_t<Arg>>>
{ {
static_assert(_check<Arg>::value, "limit requires an integral value or integral parameter"); return _limit_impl(check_limit_t<Arg>{}, wrap_operand_t<Arg>{arg});
return _limit_impl(_check<Arg>{}, wrap_operand_t<Arg>{arg});
} }
auto dynamic_limit() const -> _new_statement_t<std::true_type, dynamic_limit_t<_database_t>> auto dynamic_limit() const -> _new_statement_t<consistent_t, dynamic_limit_t<_database_t>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), dynamic_limit_data_t<_database_t>{}}; return {static_cast<const derived_statement_t<Policies>&>(*this), dynamic_limit_data_t<_database_t>{}};
} }
private: private:
template <typename Arg> template <typename Check, typename Arg>
auto _limit_impl(const std::false_type&, Arg arg) const -> bad_statement; auto _limit_impl(Check, Arg arg) const -> inconsistent<Check>;
template <typename Arg> template <typename Arg>
auto _limit_impl(const std::true_type&, Arg arg) const -> _new_statement_t<std::true_type, limit_t<Arg>> auto _limit_impl(consistent_t, Arg arg) const -> _new_statement_t<consistent_t, limit_t<Arg>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<Arg>{arg}}; return {static_cast<const derived_statement_t<Policies>&>(*this), limit_data_t<Arg>{arg}};
} }

View File

@ -27,9 +27,9 @@
#ifndef SQLPP_OFFSET_H #ifndef SQLPP_OFFSET_H
#define SQLPP_OFFSET_H #define SQLPP_OFFSET_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -83,8 +83,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : offset{std::forward<Args>(args)...}
: offset{std::forward<Args>(args)...}
{ {
} }
@ -117,8 +116,7 @@ namespace sqlpp
} }
template <typename Offset> template <typename Offset>
dynamic_offset_data_t(Offset value) dynamic_offset_data_t(Offset value) : _initialized(true), _value(wrap_operand_t<Offset>(value))
: _initialized(true), _value(wrap_operand_t<Offset>(value))
{ {
} }
@ -174,8 +172,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : offset{std::forward<Args>(args)...}
: offset{std::forward<Args>(args)...}
{ {
} }
@ -211,6 +208,15 @@ namespace sqlpp
interpretable_t<Database> _value; interpretable_t<Database> _value;
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_offset_is_integral, "argument for offset() must be an integral expressions");
template <typename T>
struct check_offset
{
using type = static_combined_check_t<static_check_t<is_integral_t<T>::value, assert_offset_is_integral>>;
};
template <typename T>
using check_offset_t = typename check_offset<wrap_operand_t<T>>::type;
struct no_offset_t struct no_offset_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
@ -240,8 +246,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_offset{std::forward<Args>(args)...}
: no_offset{std::forward<Args>(args)...}
{ {
} }
@ -263,22 +268,18 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename T>
using _check = is_integral_t<wrap_operand_t<T>>;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_offset_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_offset_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename Arg> template <typename Arg>
auto offset(Arg arg) const -> _new_statement_t<_check<Arg>, offset_t<wrap_operand_t<Arg>>> auto offset(Arg arg) const -> _new_statement_t<check_offset_t<Arg>, offset_t<wrap_operand_t<Arg>>>
{ {
static_assert(_check<Arg>::value, "offset requires an integral value or integral parameter"); return _offset_impl(check_offset_t<Arg>{}, wrap_operand_t<Arg>{arg});
return _offset_impl(_check<Arg>{}, wrap_operand_t<Arg>{arg});
} }
auto dynamic_offset() const -> _new_statement_t<std::true_type, dynamic_offset_t<_database_t>> auto dynamic_offset() const -> _new_statement_t<consistent_t, dynamic_offset_t<_database_t>>
{ {
static_assert(not std::is_same<_database_t, void>::value, static_assert(not std::is_same<_database_t, void>::value,
"dynamic_offset must not be called in a static statement"); "dynamic_offset must not be called in a static statement");
@ -286,11 +287,11 @@ namespace sqlpp
} }
private: private:
template <typename Arg> template <typename Check, typename Arg>
auto _offset_impl(const std::false_type&, Arg arg) const -> bad_statement; auto _offset_impl(Check, Arg arg) const -> inconsistent<Check>;
template <typename Arg> template <typename Arg>
auto _offset_impl(const std::true_type&, Arg arg) const -> _new_statement_t<std::true_type, offset_t<Arg>> auto _offset_impl(consistent_t, Arg arg) const -> _new_statement_t<consistent_t, offset_t<Arg>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<Arg>{arg}}; return {static_cast<const derived_statement_t<Policies>&>(*this), offset_data_t<Arg>{arg}};
} }

View File

@ -27,13 +27,13 @@
#ifndef SQLPP_ORDER_BY_H #ifndef SQLPP_ORDER_BY_H
#define SQLPP_ORDER_BY_H #define SQLPP_ORDER_BY_H
#include <tuple> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable.h> #include <sqlpp11/interpretable.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/logic.h> #include <sqlpp11/logic.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
#include <tuple>
namespace sqlpp namespace sqlpp
{ {
@ -89,7 +89,7 @@ namespace sqlpp
static_assert(Policies::template _no_unknown_tables<Expression>::value, static_assert(Policies::template _no_unknown_tables<Expression>::value,
"expression uses tables unknown to this statement in order_by::add()"); "expression uses tables unknown to this statement in order_by::add()");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expression>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value, _serialize_check::type::value>;
@ -118,8 +118,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : order_by{std::forward<Args>(args)...}
: order_by{std::forward<Args>(args)...}
{ {
} }
@ -145,6 +144,17 @@ namespace sqlpp
}; };
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_order_by_args_are_sort_order_expressions_t,
"arguments for order_by() must be sort order expressions");
template <typename... Exprs>
struct check_order_by
{
using type = static_combined_check_t<static_check_t<logic::all_t<is_sort_order_t<Exprs>::value...>::value,
assert_order_by_args_are_sort_order_expressions_t>>;
};
template <typename... Exprs>
using check_order_by_t = typename check_order_by<Exprs...>::type;
// NO ORDER BY YET // NO ORDER BY YET
struct no_order_by_t struct no_order_by_t
{ {
@ -175,8 +185,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_order_by{std::forward<Args>(args)...}
: no_order_by{std::forward<Args>(args)...}
{ {
} }
@ -198,47 +207,37 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _check = logic::all_t<is_sort_order_t<T>::value...>;
template <typename... T>
struct _check : logic::all_t<is_sort_order_t<T>::value...>
{
};
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_order_by_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_order_by_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename... Expressions> template <typename... Expressions>
auto order_by(Expressions... expressions) const auto order_by(Expressions... expressions) const
-> _new_statement_t<_check<Expressions...>, order_by_t<void, Expressions...>> -> _new_statement_t<check_order_by_t<Expressions...>, order_by_t<void, Expressions...>>
{ {
static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()"); static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
static_assert(_check<Expressions...>::value, "at least one argument is not a sort order in order_by()");
return _order_by_impl<void>(_check<Expressions...>{}, expressions...); return _order_by_impl<void>(check_order_by_t<Expressions...>{}, expressions...);
} }
template <typename... Expressions> template <typename... Expressions>
auto dynamic_order_by(Expressions... expressions) const auto dynamic_order_by(Expressions... expressions) const
-> _new_statement_t<_check<Expressions...>, order_by_t<_database_t, Expressions...>> -> _new_statement_t<check_order_by_t<Expressions...>, order_by_t<_database_t, Expressions...>>
{ {
static_assert(not std::is_same<_database_t, void>::value, static_assert(not std::is_same<_database_t, void>::value,
"dynamic_order_by must not be called in a static statement"); "dynamic_order_by must not be called in a static statement");
static_assert(_check<Expressions...>::value, "at least one argument is not a sort order in order_by()");
return _order_by_impl<_database_t>(_check<Expressions...>{}, expressions...); return _order_by_impl<_database_t>(check_order_by_t<Expressions...>{}, expressions...);
} }
private: private:
template <typename Database, typename... Expressions> template <typename Database, typename Check, typename... Expressions>
auto _order_by_impl(const std::false_type&, Expressions... expressions) const -> bad_statement; auto _order_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
template <typename Database, typename... Expressions> template <typename Database, typename... Expressions>
auto _order_by_impl(const std::true_type&, Expressions... expressions) const auto _order_by_impl(consistent_t, Expressions... expressions) const
-> _new_statement_t<std::true_type, order_by_t<Database, Expressions...>> -> _new_statement_t<consistent_t, order_by_t<Database, Expressions...>>
{ {
static_assert(not detail::has_duplicates<Expressions...>::value, static_assert(not detail::has_duplicates<Expressions...>::value,
"at least one duplicate argument detected in order_by()"); "at least one duplicate argument detected in order_by()");

View File

@ -28,7 +28,6 @@
#define SQLPP_POLICY_UPDATE_H #define SQLPP_POLICY_UPDATE_H
#include <sqlpp11/wrong.h> #include <sqlpp11/wrong.h>
#include <sqlpp11/bad_statement.h>
namespace sqlpp namespace sqlpp
{ {
@ -54,19 +53,19 @@ namespace sqlpp
template <typename Policies, typename Needle, typename Replacement> template <typename Policies, typename Needle, typename Replacement>
using new_statement = typename Policies::template _new_statement_t<Needle, Replacement>; using new_statement = typename Policies::template _new_statement_t<Needle, Replacement>;
template <bool, typename Policies, typename Needle, typename Replacement> template <typename Check, typename Policies, typename Needle, typename Replacement>
struct new_statement_impl struct new_statement_impl
{
using type = Check;
};
template <typename Policies, typename Needle, typename Replacement>
struct new_statement_impl<consistent_t, Policies, Needle, Replacement>
{ {
using type = typename Policies::template _new_statement_t<Needle, Replacement>; using type = typename Policies::template _new_statement_t<Needle, Replacement>;
}; };
template <typename Policies, typename Needle, typename Replacement> template <typename Check, typename Policies, typename Needle, typename Replacement>
struct new_statement_impl<false, Policies, Needle, Replacement>
{
using type = bad_statement;
};
template <bool Check, typename Policies, typename Needle, typename Replacement>
using new_statement_t = typename new_statement_impl<Check, Policies, Needle, Replacement>::type; using new_statement_t = typename new_statement_impl<Check, Policies, Needle, Replacement>::type;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2015, Roland Bock * Copyright (c) 2015-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,
@ -28,17 +28,20 @@
#define SQLPP_PORTABLE_STATIC_ASSERT_H #define SQLPP_PORTABLE_STATIC_ASSERT_H
#include <sqlpp11/consistent.h> #include <sqlpp11/consistent.h>
#include <sqlpp11/inconsistent.h>
namespace sqlpp namespace sqlpp
{ {
#define SQLPP_PORTABLE_STATIC_ASSERT(name, message) \ #define SQLPP_PORTABLE_STATIC_ASSERT(name, message) \
struct name : std::false_type \ struct name : std::false_type \
{ \ { \
template <typename T = void> \ template <typename... T> \
static void _() \ name(T&&...) \
{ \ { \
static_assert(wrong_t<T>::value, message); \ static_assert(wrong_t<T...>::value, message); \
} \ } \
auto begin() const -> void; \
auto end() const -> void; \
} }
namespace detail namespace detail

View File

@ -27,10 +27,9 @@
#ifndef SQLPP_PRE_JOIN_H #ifndef SQLPP_PRE_JOIN_H
#define SQLPP_PRE_JOIN_H #define SQLPP_PRE_JOIN_H
#include <sqlpp11/bad_statement.h>
#include <sqlpp11/join_types.h> #include <sqlpp11/join_types.h>
#include <sqlpp11/on.h>
#include <sqlpp11/noop.h> #include <sqlpp11/noop.h>
#include <sqlpp11/on.h>
namespace sqlpp namespace sqlpp
{ {
@ -106,20 +105,19 @@ namespace sqlpp
template <typename Expr> template <typename Expr>
auto on(Expr expr) const -> typename std::conditional<check_join_on_t<pre_join_t, Expr>::value, auto on(Expr expr) const -> typename std::conditional<check_join_on_t<pre_join_t, Expr>::value,
join_t<pre_join_t, on_t<Expr>>, join_t<pre_join_t, on_t<Expr>>,
bad_statement>::type check_join_on_t<pre_join_t, Expr>>::type
{ {
using Check = check_join_on_t<pre_join_t, Expr>; using Check = check_join_on_t<pre_join_t, Expr>;
Check::_();
return on_impl(Check{}, expr); return on_impl(Check{}, expr);
} }
private: private:
template <typename Expr> template <typename Check, typename Expr>
auto on_impl(const std::false_type&, const Expr&) const -> bad_statement; auto on_impl(Check, const Expr&) const -> inconsistent<Check>;
template <typename Expr> template <typename Expr>
auto on_impl(const std::true_type&, const Expr& expr) const -> join_t<pre_join_t, on_t<Expr>> auto on_impl(consistent_t, const Expr& expr) const -> join_t<pre_join_t, on_t<Expr>>
{ {
return {*this, {expr}}; return {*this, {expr}};
} }
@ -145,64 +143,66 @@ namespace sqlpp
} }
}; };
template <typename Lhs, typename Rhs> namespace detail
auto join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
pre_join_t<inner_join_t, Lhs, Rhs>,
bad_statement>::type
{ {
check_pre_join_t<Lhs, Rhs>::_(); template <typename JoinType, typename Check, typename Lhs, typename Rhs>
auto join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent<Check>;
template <typename JoinType, typename Lhs, typename Rhs>
auto join_impl(consistent_t, Lhs lhs, Rhs rhs) -> pre_join_t<JoinType, Lhs, Rhs>;
template <typename JoinType, typename Lhs, typename Rhs>
auto join_impl(Lhs lhs, Rhs rhs) -> decltype(join_impl<JoinType>(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
}
template <typename Lhs, typename Rhs>
auto join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
{
return {lhs, rhs};
}
template <typename Lhs, typename Rhs>
auto inner_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<inner_join_t>(lhs, rhs))
{
return {lhs, rhs};
}
template <typename Lhs, typename Rhs>
auto left_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<left_outer_join_t>(lhs, rhs))
{
return {lhs, rhs};
}
template <typename Lhs, typename Rhs>
auto right_outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<right_outer_join_t>(lhs, rhs))
{
check_pre_join_t<Lhs, Rhs>{};
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto inner_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value, auto outer_join(Lhs lhs, Rhs rhs) -> decltype(detail::join_impl<outer_join_t>(lhs, rhs))
pre_join_t<inner_join_t, Lhs, Rhs>,
bad_statement>::type
{ {
check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs}; return {lhs, rhs};
} }
template <typename Lhs, typename Rhs> namespace detail
auto left_outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
pre_join_t<left_outer_join_t, Lhs, Rhs>,
bad_statement>::type
{ {
check_pre_join_t<Lhs, Rhs>::_(); template <typename Check, typename Lhs, typename Rhs>
auto cross_join_impl(Check, Lhs lhs, Rhs rhs) -> inconsistent<Check>;
return {lhs, rhs}; template <typename Lhs, typename Rhs>
auto cross_join_impl(consistent_t, Lhs lhs, Rhs rhs)
-> join_t<pre_join_t<cross_join_t, Lhs, Rhs>, on_t<unconditional_t>>;
template <typename Lhs, typename Rhs>
auto cross_join_impl(Lhs lhs, Rhs rhs) -> decltype(cross_join_impl(check_pre_join_t<Lhs, Rhs>{}, lhs, rhs));
} }
template <typename Lhs, typename Rhs> template <typename Lhs, typename Rhs>
auto right_outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value, auto cross_join(Lhs lhs, Rhs rhs) -> decltype(detail::cross_join_impl(lhs, rhs))
pre_join_t<right_outer_join_t, Lhs, Rhs>,
bad_statement>::type
{ {
check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs};
}
template <typename Lhs, typename Rhs>
auto outer_join(Lhs lhs, Rhs rhs) -> typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
pre_join_t<outer_join_t, Lhs, Rhs>,
bad_statement>::type
{
check_pre_join_t<Lhs, Rhs>::_();
return {lhs, rhs};
}
template <typename Lhs, typename Rhs>
auto cross_join(Lhs lhs, Rhs rhs) ->
typename std::conditional<check_pre_join_t<Lhs, Rhs>::value,
join_t<pre_join_t<cross_join_t, Lhs, Rhs>, on_t<unconditional_t>>,
bad_statement>::type
{
check_pre_join_t<Lhs, Rhs>::_();
return {pre_join_t<cross_join_t, Lhs, Rhs>{lhs, rhs}, {}}; return {pre_join_t<cross_join_t, Lhs, Rhs>{lhs, rhs}, {}};
} }
} }

View File

@ -28,7 +28,6 @@
#define SQLPP_RESULT_FIELD_BASE_H #define SQLPP_RESULT_FIELD_BASE_H
#include <sqlpp11/alias_operators.h> #include <sqlpp11/alias_operators.h>
#include <sqlpp11/bad_statement.h>
#include <sqlpp11/basic_expression_operators.h> #include <sqlpp11/basic_expression_operators.h>
#include <sqlpp11/exception.h> #include <sqlpp11/exception.h>
#include <sqlpp11/result_field.h> #include <sqlpp11/result_field.h>
@ -37,6 +36,8 @@
namespace sqlpp namespace sqlpp
{ {
SQLPP_PORTABLE_STATIC_ASSERT(assert_result_field_value_is_safe_t, "result field value needs to be checked for NULL");
template <typename Db, typename FieldSpec, typename StorageType = typename value_type_of<FieldSpec>::_cpp_value_type> template <typename Db, typename FieldSpec, typename StorageType = typename value_type_of<FieldSpec>::_cpp_value_type>
struct result_field_base struct result_field_base
{ {
@ -117,8 +118,9 @@ namespace sqlpp
return _value; return _value;
} }
operator typename std::conditional<_null_is_trivial or (not _can_be_null::value), _cpp_value_type, bad_statement>:: operator typename std::conditional<_null_is_trivial or (not _can_be_null::value),
type() const _cpp_value_type,
assert_result_field_value_is_safe_t>::type() const
{ {
return value(); return value();
} }

View File

@ -27,9 +27,9 @@
#ifndef SQLPP_RHS_WRAP_H #ifndef SQLPP_RHS_WRAP_H
#define SQLPP_RHS_WRAP_H #define SQLPP_RHS_WRAP_H
#include <sqlpp11/tvin.h>
#include <sqlpp11/default_value.h> #include <sqlpp11/default_value.h>
#include <sqlpp11/null.h> #include <sqlpp11/null.h>
#include <sqlpp11/tvin.h>
namespace sqlpp namespace sqlpp
{ {

View File

@ -27,19 +27,19 @@
#ifndef SQLPP_SELECT_COLUMN_LIST_H #ifndef SQLPP_SELECT_COLUMN_LIST_H
#define SQLPP_SELECT_COLUMN_LIST_H #define SQLPP_SELECT_COLUMN_LIST_H
#include <tuple>
#include <sqlpp11/result_row.h>
#include <sqlpp11/dynamic_select_column_list.h>
#include <sqlpp11/table.h>
#include <sqlpp11/data_types/no_value.h> #include <sqlpp11/data_types/no_value.h>
#include <sqlpp11/field_spec.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/select_pseudo_table.h>
#include <sqlpp11/named_interpretable.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/detail/copy_tuple_args.h> #include <sqlpp11/detail/copy_tuple_args.h>
#include <sqlpp11/detail/type_set.h>
#include <sqlpp11/dynamic_select_column_list.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/field_spec.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/named_interpretable.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/select_pseudo_table.h>
#include <sqlpp11/table.h>
#include <tuple>
namespace sqlpp namespace sqlpp
{ {
@ -135,7 +135,7 @@ namespace sqlpp
static_assert(not detail::is_element_of<typename named_expression::_alias_t, column_names>::value, static_assert(not detail::is_element_of<typename named_expression::_alias_t, column_names>::value,
"a column of this name is present in the select already"); "a column of this name is present in the select already");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, named_expression>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, named_expression>;
_serialize_check::_(); _serialize_check{};
using ok = using ok =
logic::all_t<_is_dynamic::value, is_selectable_t<named_expression>::value, _serialize_check::type::value>; logic::all_t<_is_dynamic::value, is_selectable_t<named_expression>::value, _serialize_check::type::value>;
@ -165,8 +165,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : selected_columns{std::forward<Args>(args)...}
: selected_columns{std::forward<Args>(args)...}
{ {
} }
@ -249,7 +248,7 @@ namespace sqlpp
template <typename AliasProvider> template <typename AliasProvider>
_alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const _alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const
{ {
consistency_check_t<_statement_t>::_(); consistency_check_t<_statement_t>{};
static_assert(_statement_t::_can_be_used_as_table(), static_assert(_statement_t::_can_be_used_as_table(),
"statement cannot be used as table, e.g. due to missing tables"); "statement cannot be used as table, e.g. due to missing tables");
static_assert(logic::none_t<is_multi_column_t<Columns>::value...>::value, static_assert(logic::none_t<is_multi_column_t<Columns>::value...>::value,
@ -302,6 +301,17 @@ namespace sqlpp
copy_tuple_args_t<select_column_list_t, Database, decltype(column_tuple_merge(std::declval<Columns>()...))>; copy_tuple_args_t<select_column_list_t, Database, decltype(column_tuple_merge(std::declval<Columns>()...))>;
} }
SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable");
template <typename... T>
struct check_selected_columns
{
using type = static_combined_check_t<
static_check_t<logic::all_t<(is_selectable_t<T>::value or is_multi_column_t<T>::value)...>::value,
assert_selected_colums_are_selectable_t>>;
};
template <typename... T>
using check_selected_columns_t = typename check_selected_columns<T...>::type;
struct no_select_column_list_t struct no_select_column_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>; using _traits = make_traits<no_value_t, tag::is_noop, tag::is_missing>;
@ -335,8 +345,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_selected_columns{std::forward<Args>(args)...}
: no_selected_columns{std::forward<Args>(args)...}
{ {
} }
@ -358,16 +367,8 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _check = logic::all_t<(is_selectable_t<T>::value or is_multi_column_t<T>::value)...>;
template <typename... T> template <typename... T>
struct _check : logic::all_t<(is_selectable_t<T>::value or is_multi_column_t<T>::value)...> static constexpr auto _check_tuple(std::tuple<T...>) -> check_selected_columns_t<T...>
{
};
template <typename... T>
static constexpr auto _check_tuple(std::tuple<T...>) -> _check<T...>
{ {
return {}; return {};
} }
@ -375,11 +376,11 @@ namespace sqlpp
template <typename... T> template <typename... T>
static constexpr auto _check_args(T... args) -> decltype(_check_tuple(detail::column_tuple_merge(args...))) static constexpr auto _check_args(T... args) -> decltype(_check_tuple(detail::column_tuple_merge(args...)))
{ {
return _check_tuple(detail::column_tuple_merge(args...)); return {};
} }
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_select_column_list_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_select_column_list_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
@ -391,7 +392,7 @@ namespace sqlpp
static_assert(decltype(_check_args(args...))::value, static_assert(decltype(_check_args(args...))::value,
"at least one argument is not a selectable expression in columns()"); "at least one argument is not a selectable expression in columns()");
return _columns_impl<void>(_check_args(args...), detail::column_tuple_merge(args...)); return _columns_impl<void>(decltype(_check_args(args...)){}, detail::column_tuple_merge(args...));
} }
template <typename... Args> template <typename... Args>
@ -403,16 +404,16 @@ namespace sqlpp
static_assert(decltype(_check_args(args...))::value, static_assert(decltype(_check_args(args...))::value,
"at least one argument is not a selectable expression in columns()"); "at least one argument is not a selectable expression in columns()");
return _columns_impl<_database_t>(_check_args(args...), detail::column_tuple_merge(args...)); return _columns_impl<_database_t>(decltype(_check_args(args...)){}, detail::column_tuple_merge(args...));
} }
private: private:
template <typename Database, typename... Args> template <typename Database, typename Check, typename... Args>
auto _columns_impl(const std::false_type&, std::tuple<Args...> args) const -> bad_statement; auto _columns_impl(Check, std::tuple<Args...> args) const -> inconsistent<Check>;
template <typename Database, typename... Args> template <typename Database, typename... Args>
auto _columns_impl(const std::true_type&, std::tuple<Args...> args) const auto _columns_impl(consistent_t, std::tuple<Args...> args) const
-> _new_statement_t<_check<Args...>, select_column_list_t<Database, Args...>> -> _new_statement_t<consistent_t, select_column_list_t<Database, Args...>>
{ {
static_assert(not detail::has_duplicates<Args...>::value, "at least one duplicate argument detected"); static_assert(not detail::has_duplicates<Args...>::value, "at least one duplicate argument detected");
static_assert(not detail::has_duplicates<typename Args::_alias_t...>::value, static_assert(not detail::has_duplicates<typename Args::_alias_t...>::value,

View File

@ -27,13 +27,13 @@
#ifndef SQLPP_SELECT_FLAG_LIST_H #ifndef SQLPP_SELECT_FLAG_LIST_H
#define SQLPP_SELECT_FLAG_LIST_H #define SQLPP_SELECT_FLAG_LIST_H
#include <tuple>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/policy_update.h> #include <sqlpp11/policy_update.h>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/type_traits.h>
#include <tuple>
namespace sqlpp namespace sqlpp
{ {
@ -85,7 +85,7 @@ namespace sqlpp
static_assert(Policies::template _no_unknown_tables<Flag>::value, static_assert(Policies::template _no_unknown_tables<Flag>::value,
"flag uses tables unknown to this statement in select_flags::add()"); "flag uses tables unknown to this statement in select_flags::add()");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Flag>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Flag>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value, _serialize_check::type::value>;
@ -114,8 +114,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : select_flags{std::forward<Args>(args)...}
: select_flags{std::forward<Args>(args)...}
{ {
} }
@ -139,6 +138,16 @@ namespace sqlpp
}; };
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_select_flags_are_flags_t, "arguments for flags() must be known select flags");
template <typename... Flags>
struct check_select_flags
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_select_flag_t<Flags>::value...>::value, assert_select_flags_are_flags_t>>;
};
template <typename... Flags>
using check_select_flags_t = typename check_select_flags<Flags...>::type;
struct no_select_flag_list_t struct no_select_flag_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
@ -168,8 +177,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_select_flags{std::forward<Args>(args)...}
: no_select_flags{std::forward<Args>(args)...}
{ {
} }
@ -191,45 +199,35 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _check = logic::all_t<is_select_flag_t<T>::value...>;
template <typename... T>
struct _check : logic::all_t<detail::is_select_flag_impl<T>::type::value...>
{
};
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_select_flag_list_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_select_flag_list_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename... Flags> template <typename... Flags>
auto flags(Flags... flgs) const -> _new_statement_t<_check<Flags...>, select_flag_list_t<void, Flags...>> auto flags(Flags... flgs) const
-> _new_statement_t<check_select_flags_t<Flags...>, select_flag_list_t<void, Flags...>>
{ {
static_assert(_check<Flags...>::value, "at least one argument is not a select flag in select flag list"); return _flags_impl<void>(check_select_flags_t<Flags...>{}, flgs...);
return _flags_impl<void>(_check<Flags...>{}, flgs...);
} }
template <typename... Flags> template <typename... Flags>
auto dynamic_flags(Flags... flgs) const auto dynamic_flags(Flags... flgs) const
-> _new_statement_t<_check<Flags...>, select_flag_list_t<_database_t, Flags...>> -> _new_statement_t<check_select_flags_t<Flags...>, select_flag_list_t<_database_t, Flags...>>
{ {
static_assert(not std::is_same<_database_t, void>::value, static_assert(not std::is_same<_database_t, void>::value,
"dynamic_flags must not be called in a static statement"); "dynamic_flags must not be called in a static statement");
static_assert(_check<Flags...>::value, "at least one argument is not a select flag in select flag list");
return _flags_impl<_database_t>(_check<Flags...>{}, flgs...); return _flags_impl<_database_t>(check_select_flags_t<Flags...>{}, flgs...);
} }
private: private:
template <typename Database, typename... Flags> template <typename Database, typename Check, typename... Flags>
auto _flags_impl(const std::false_type&, Flags... flgs) const -> bad_statement; auto _flags_impl(Check, Flags... flgs) const -> inconsistent<Check>;
template <typename Database, typename... Flags> template <typename Database, typename... Flags>
auto _flags_impl(const std::true_type&, Flags... flgs) const auto _flags_impl(consistent_t, Flags... flgs) const
-> _new_statement_t<std::true_type, select_flag_list_t<Database, Flags...>> -> _new_statement_t<consistent_t, select_flag_list_t<Database, Flags...>>
{ {
static_assert(not detail::has_duplicates<Flags...>::value, static_assert(not detail::has_duplicates<Flags...>::value,
"at least one duplicate argument detected in select flag list"); "at least one duplicate argument detected in select flag list");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2013-2016, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -28,6 +28,7 @@
#define SQLPP_SELECT_PSEUDO_TABLE_H #define SQLPP_SELECT_PSEUDO_TABLE_H
#include <sqlpp11/data_types/no_value.h> #include <sqlpp11/data_types/no_value.h>
#include <sqlpp11/table.h>
namespace sqlpp namespace sqlpp
{ {

View File

@ -27,8 +27,8 @@
#ifndef SQLPP_SERIALIZER_H #ifndef SQLPP_SERIALIZER_H
#define SQLPP_SERIALIZER_H #define SQLPP_SERIALIZER_H
#include <sqlpp11/wrong.h>
#include <sqlpp11/portable_static_assert.h> #include <sqlpp11/portable_static_assert.h>
#include <sqlpp11/wrong.h>
namespace sqlpp namespace sqlpp
{ {
@ -41,7 +41,7 @@ namespace sqlpp
static void _(const T&, Context&) static void _(const T&, Context&)
{ {
_serialize_check::_(); _serialize_check{};
} }
}; };
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2013-2016, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -27,12 +27,12 @@
#ifndef SQLPP_SINGLE_TABLE_H #ifndef SQLPP_SINGLE_TABLE_H
#define SQLPP_SINGLE_TABLE_H #define SQLPP_SINGLE_TABLE_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/data_types/no_value.h> #include <sqlpp11/data_types/no_value.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/serializer.h>
#include <sqlpp11/prepared_insert.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/prepared_insert.h>
#include <sqlpp11/serializer.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -90,8 +90,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : from{std::forward<Args>(args)...}
: from{std::forward<Args>(args)...}
{ {
} }
@ -115,7 +114,16 @@ namespace sqlpp
}; };
}; };
// NO INTO YET SQLPP_PORTABLE_STATIC_ASSERT(assert_update_table_arg_is_table_t, "argument for update() must be a table");
template <typename Table>
struct check_update_table
{
using type = static_combined_check_t<static_check_t<is_table_t<Table>::value, assert_update_table_arg_is_table_t>>;
};
template <typename Table>
using check_update_table_t = typename check_update_table<Table>::type;
// NO TABLE YET
struct no_single_table_t struct no_single_table_t
{ {
using _traits = make_traits<no_value_t, tag::is_noop>; using _traits = make_traits<no_value_t, tag::is_noop>;
@ -154,28 +162,25 @@ namespace sqlpp
} }
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename T>
using _check = logic::all_t<is_table_t<T>::value>;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_single_table_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_single_table_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename Table> template <typename Table>
auto single_table(Table table) const -> _new_statement_t<_check<Table>, single_table_t<void, Table>> auto single_table(Table table) const -> _new_statement_t<check_update_table_t<Table>, single_table_t<void, Table>>
{ {
static_assert(_check<Table>::value, "argument is not a table in single_table()"); return _single_table_impl<void>(check_update_table_t<Table>{}, table);
return _single_table_impl<void>(_check<Table>{}, table);
} }
private: private:
template <typename Database, typename Table> template <typename Database, typename Check, typename Table>
auto _single_table_impl(const std::false_type&, Table table) const -> bad_statement; auto _single_table_impl(Check, Table table) const -> inconsistent<Check>;
template <typename Database, typename Table> template <typename Database, typename Table>
auto _single_table_impl(const std::true_type&, Table table) const auto _single_table_impl(consistent_t, Table table) const
-> _new_statement_t<std::true_type, single_table_t<Database, Table>> -> _new_statement_t<consistent_t, single_table_t<Database, Table>>
{ {
static_assert(required_tables_of<single_table_t<Database, Table>>::size::value == 0, static_assert(required_tables_of<single_table_t<Database, Table>>::size::value == 0,
"argument depends on another table in single_table()"); "argument depends on another table in single_table()");

View File

@ -27,12 +27,12 @@
#ifndef SQLPP_STATEMENT_H #ifndef SQLPP_STATEMENT_H
#define SQLPP_STATEMENT_H #define SQLPP_STATEMENT_H
#include <sqlpp11/result.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_select.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/noop.h> #include <sqlpp11/noop.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/policy_update.h> #include <sqlpp11/policy_update.h>
#include <sqlpp11/prepared_select.h>
#include <sqlpp11/result.h>
#include <sqlpp11/serialize.h>
#include <sqlpp11/serializer.h> #include <sqlpp11/serializer.h>
#include <sqlpp11/detail/get_first.h> #include <sqlpp11/detail/get_first.h>
@ -142,9 +142,8 @@ namespace sqlpp
typename std::conditional<_required_ctes::size::value == 0, consistent_t, assert_no_unknown_ctes_t>::type; typename std::conditional<_required_ctes::size::value == 0, consistent_t, assert_no_unknown_ctes_t>::type;
using _table_check = using _table_check =
typename std::conditional<_required_tables::size::value == 0, consistent_t, assert_no_unknown_tables_t>::type; typename std::conditional<_required_tables::size::value == 0, consistent_t, assert_no_unknown_tables_t>::type;
using _parameter_check = typename std::conditional<detail::type_vector_size<_parameters>::value == 0, using _parameter_check = typename std::
consistent_t, conditional<detail::type_vector_size<_parameters>::value == 0, consistent_t, assert_no_parameters_t>::type;
assert_no_parameters_t>::type;
}; };
} }
@ -235,14 +234,14 @@ namespace sqlpp
template <typename Database> template <typename Database>
auto _run(Database& db) const -> decltype(std::declval<_result_methods_t<statement_t>>()._run(db)) auto _run(Database& db) const -> decltype(std::declval<_result_methods_t<statement_t>>()._run(db))
{ {
_run_check::_(); _run_check{}; // FIXME: Dispatch?
return _result_methods_t<statement_t>::_run(db); return _result_methods_t<statement_t>::_run(db);
} }
template <typename Database> template <typename Database>
auto _prepare(Database& db) const -> decltype(std::declval<_result_methods_t<statement_t>>()._prepare(db)) auto _prepare(Database& db) const -> decltype(std::declval<_result_methods_t<statement_t>>()._prepare(db))
{ {
_prepare_check::_(); _prepare_check{}; // FIXME: Dispatch?
return _result_methods_t<statement_t>::_prepare(db); return _result_methods_t<statement_t>::_prepare(db);
} }
}; };
@ -294,8 +293,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : statement_name{std::forward<Args>(args)...}
: statement_name{std::forward<Args>(args)...}
{ {
} }

View File

@ -29,9 +29,9 @@
// TVIN: Trivial value is NULL // TVIN: Trivial value is NULL
#include <sqlpp11/type_traits.h>
#include <sqlpp11/serialize.h> #include <sqlpp11/serialize.h>
#include <sqlpp11/serializer.h> #include <sqlpp11/serializer.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/wrap_operand.h> #include <sqlpp11/wrap_operand.h>
namespace sqlpp namespace sqlpp
@ -67,7 +67,7 @@ namespace sqlpp
static Context& _(const T&, Context&) static Context& _(const T&, Context&)
{ {
_serialize_check::_(); _serialize_check{};
} }
}; };

View File

@ -27,16 +27,16 @@
#ifndef SQLPP_UNION_H #ifndef SQLPP_UNION_H
#define SQLPP_UNION_H #define SQLPP_UNION_H
#include <sqlpp11/union_data.h>
#include <sqlpp11/union_flags.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/expression.h> #include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h> #include <sqlpp11/interpretable_list.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/logic.h> #include <sqlpp11/logic.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/union_data.h>
#include <sqlpp11/union_flags.h>
namespace sqlpp namespace sqlpp
{ {
@ -45,19 +45,19 @@ namespace sqlpp
using blank_union_t = statement_t<void, no_union_t>; using blank_union_t = statement_t<void, no_union_t>;
// There is no order by or limit or offset in union, use it as a pseudo table to do that. // There is no order by or limit or offset in union, use it as a pseudo table to do that.
template <bool, typename Union> template <typename Check, typename Union>
struct union_statement_impl struct union_statement_impl
{
using type = Check;
};
template <typename Union>
struct union_statement_impl<consistent_t, Union>
{ {
using type = statement_t<void, Union, no_union_t>; using type = statement_t<void, Union, no_union_t>;
}; };
template <typename Union> template <typename Check, typename Union>
struct union_statement_impl<false, Union>
{
using type = bad_statement;
};
template <bool Check, typename Union>
using union_statement_t = typename union_statement_impl<Check, Union>::type; using union_statement_t = typename union_statement_impl<Check, Union>::type;
// UNION(EXPR) // UNION(EXPR)
@ -95,8 +95,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : union_{std::forward<Args>(args)...}
: union_{std::forward<Args>(args)...}
{ {
} }
@ -136,6 +135,16 @@ namespace sqlpp
using _result_methods_t = typename Lhs::template _result_methods_t<Statement>; using _result_methods_t = typename Lhs::template _result_methods_t<Statement>;
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_union_args_are_statements_t, "arguments for union() must be statements");
template <typename... T>
struct check_union
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_statement_t<T>::value...>::value, assert_union_args_are_statements_t>>;
};
template <typename... T>
using check_union_t = typename check_union<T...>::type;
// NO UNION YET // NO UNION YET
struct no_union_t struct no_union_t
{ {
@ -166,8 +175,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_union{std::forward<Args>(args)...}
: no_union{std::forward<Args>(args)...}
{ {
} }
@ -189,20 +197,15 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _check = logic::all_t<is_statement_t<T>::value...>;
template <typename... T>
using _check = typename logic::all<is_statement_t<T>::value...>::type;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = union_statement_t<Check::value, T>; using _new_statement_t = union_statement_t<Check, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename Rhs> template <typename Rhs>
auto union_distinct(Rhs rhs) const auto union_distinct(Rhs rhs) const
-> _new_statement_t<_check<Rhs>, union_t<void, union_distinct_t, derived_statement_t<Policies>, Rhs>> -> _new_statement_t<check_union_t<derived_statement_t<Policies>, Rhs>,
union_t<void, union_distinct_t, derived_statement_t<Policies>, Rhs>>
{ {
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement"); static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select"); static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
@ -215,12 +218,12 @@ namespace sqlpp
"both arguments in a union have to have the same result columns (type and name)"); "both arguments in a union have to have the same result columns (type and name)");
static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns"); static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns");
return _union_impl<void, union_distinct_t>(_check<derived_statement_t<Policies>, Rhs>{}, rhs); return _union_impl<void, union_distinct_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
} }
template <typename Rhs> template <typename Rhs>
auto union_all(Rhs rhs) const auto union_all(Rhs rhs) const -> _new_statement_t<check_union_t<derived_statement_t<Policies>, Rhs>,
-> _new_statement_t<_check<Rhs>, union_t<void, union_all_t, derived_statement_t<Policies>, Rhs>> union_t<void, union_all_t, derived_statement_t<Policies>, Rhs>>
{ {
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement"); static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select"); static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
@ -233,19 +236,18 @@ namespace sqlpp
"both arguments in a union have to have the same result columns (type and name)"); "both arguments in a union have to have the same result columns (type and name)");
static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns"); static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns");
return _union_impl<void, union_all_t>(_check<derived_statement_t<Policies>, Rhs>{}, rhs); return _union_impl<void, union_all_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
} }
private: private:
template <typename Database, typename Flag, typename Rhs> template <typename Database, typename Flag, typename Check, typename Rhs>
auto _union_impl(const std::false_type&, Rhs rhs) const -> bad_statement; auto _union_impl(Check, Rhs rhs) const -> inconsistent<Check>;
template <typename Database, typename Flag, typename Rhs> template <typename Database, typename Flag, typename Rhs>
auto _union_impl(const std::true_type&, Rhs rhs) const auto _union_impl(consistent_t, Rhs rhs) const
-> _new_statement_t<std::true_type, union_t<Database, Flag, derived_statement_t<Policies>, Rhs>> -> _new_statement_t<consistent_t, union_t<Database, Flag, derived_statement_t<Policies>, Rhs>>
{ {
return {blank_union_t{}, return {blank_union_t{}, union_data_t<Database, Flag, derived_statement_t<Policies>, Rhs>{
union_data_t<Database, Flag, derived_statement_t<Policies>, Rhs>{
static_cast<const derived_statement_t<Policies>&>(*this), rhs}}; static_cast<const derived_statement_t<Policies>&>(*this), rhs}};
} }
}; };

View File

@ -27,10 +27,10 @@
#ifndef SQLPP_UPDATE_LIST_H #ifndef SQLPP_UPDATE_LIST_H
#define SQLPP_UPDATE_LIST_H #define SQLPP_UPDATE_LIST_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h> #include <sqlpp11/interpretable_list.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -89,7 +89,7 @@ namespace sqlpp
static_assert(Policies::template _no_unknown_tables<Assignment>::value, static_assert(Policies::template _no_unknown_tables<Assignment>::value,
"assignment uses tables unknown to this statement in add()"); "assignment uses tables unknown to this statement in add()");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Assignment>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Assignment>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_assignment_t<Assignment>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_assignment_t<Assignment>::value, _serialize_check::type::value>;
@ -118,8 +118,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : assignments{std::forward<Args>(args)...}
: assignments{std::forward<Args>(args)...}
{ {
} }
@ -228,8 +227,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_assignments{std::forward<Args>(args)...}
: no_assignments{std::forward<Args>(args)...}
{ {
} }
@ -252,7 +250,7 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_update_list_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_update_list_t, T>;
using _consistency_check = assert_update_assignments_t; using _consistency_check = assert_update_assignments_t;
@ -261,8 +259,6 @@ namespace sqlpp
-> _new_statement_t<check_update_static_set_t<Assignments...>, update_list_t<void, Assignments...>> -> _new_statement_t<check_update_static_set_t<Assignments...>, update_list_t<void, Assignments...>>
{ {
using Check = check_update_static_set_t<Assignments...>; using Check = check_update_static_set_t<Assignments...>;
Check{}._();
return _set_impl<void>(Check{}, assignments...); return _set_impl<void>(Check{}, assignments...);
} }
@ -272,18 +268,16 @@ namespace sqlpp
update_list_t<_database_t, Assignments...>> update_list_t<_database_t, Assignments...>>
{ {
using Check = check_update_dynamic_set_t<_database_t, Assignments...>; using Check = check_update_dynamic_set_t<_database_t, Assignments...>;
Check{}._();
return _set_impl<_database_t>(Check{}, assignments...); return _set_impl<_database_t>(Check{}, assignments...);
} }
private: private:
template <typename Database, typename... Assignments> template <typename Database, typename Check, typename... Assignments>
auto _set_impl(const std::false_type&, Assignments... assignments) const -> bad_statement; auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
template <typename Database, typename... Assignments> template <typename Database, typename... Assignments>
auto _set_impl(const std::true_type&, Assignments... assignments) const auto _set_impl(consistent_t, Assignments... assignments) const
-> _new_statement_t<std::true_type, update_list_t<Database, Assignments...>> -> _new_statement_t<consistent_t, update_list_t<Database, Assignments...>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
update_list_data_t<Database, Assignments...>{assignments...}}; update_list_data_t<Database, Assignments...>{assignments...}};

View File

@ -27,11 +27,11 @@
#ifndef SQLPP_USING_H #ifndef SQLPP_USING_H
#define SQLPP_USING_H #define SQLPP_USING_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/detail/type_set.h> #include <sqlpp11/detail/type_set.h>
#include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h>
#include <sqlpp11/policy_update.h> #include <sqlpp11/policy_update.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -81,7 +81,7 @@ namespace sqlpp
static_assert(_is_dynamic::value, "add must not be called for static using()"); static_assert(_is_dynamic::value, "add must not be called for static using()");
static_assert(is_table_t<Table>::value, "invalid table argument in add()"); static_assert(is_table_t<Table>::value, "invalid table argument in add()");
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, Table>;
_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<Table>::value, _serialize_check::type::value>;
@ -110,8 +110,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : using_{std::forward<Args>(args)...}
: using_{std::forward<Args>(args)...}
{ {
} }
@ -136,6 +135,16 @@ namespace sqlpp
}; };
}; };
SQLPP_PORTABLE_STATIC_ASSERT(assert_using_args_are_tables_t, "arguments for using() must be tables");
template <typename... Tables>
struct check_using
{
using type = static_combined_check_t<
static_check_t<logic::all_t<is_table_t<Tables>::value...>::value, assert_using_args_are_tables_t>>;
};
template <typename... Tables>
using check_using_t = typename check_using<Tables...>::type;
// NO USING YET // NO USING YET
struct no_using_t struct no_using_t
{ {
@ -166,8 +175,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_using{std::forward<Args>(args)...}
: no_using{std::forward<Args>(args)...}
{ {
} }
@ -189,52 +197,43 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
// using _check = logic::all_t<is_table_t<T>::value...>;
template <typename... T>
struct _check : logic::all_t<is_table_t<T>::value...>
{
};
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_using_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_using_t, T>;
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
template <typename... Args> template <typename... Tables>
auto using_(Args... args) const -> _new_statement_t<_check<Args...>, using_t<void, Args...>> auto using_(Tables... tables) const -> _new_statement_t<check_using_t<Tables...>, using_t<void, Tables...>>
{ {
static_assert(not detail::has_duplicates<Args...>::value, static_assert(not detail::has_duplicates<Tables...>::value,
"at least one duplicate argument detected in using()"); "at least one duplicate argument detected in using()");
static_assert(sizeof...(Args), "at least one table required in using()"); static_assert(sizeof...(Tables), "at least one table required in using()");
static_assert(_check<Args...>::value, "at least one argument is not an table in using()");
return {_using_impl<void>(_check<Args...>{}, args...)}; return {_using_impl<void>(check_using_t<Tables...>{}, tables...)};
} }
template <typename... Args> template <typename... Tables>
auto dynamic_using(Args... args) const -> _new_statement_t<_check<Args...>, using_t<_database_t, Args...>> auto dynamic_using(Tables... tables) const
-> _new_statement_t<check_using_t<Tables...>, using_t<_database_t, Tables...>>
{ {
static_assert(not std::is_same<_database_t, void>::value, static_assert(not std::is_same<_database_t, void>::value,
"dynamic_using must not be called in a static statement"); "dynamic_using must not be called in a static statement");
static_assert(_check<Args...>::value, "at least one argument is not an table in using()");
return {_using_impl<_database_t>(_check<Args...>{}, args...)}; return {_using_impl<_database_t>(check_using_t<Tables...>{}, tables...)};
} }
private: private:
template <typename Database, typename... Args> template <typename Database, typename Check, typename... Tables>
auto _using_impl(const std::false_type&, Args... args) const -> bad_statement; auto _using_impl(Check, Tables... tables) const -> inconsistent<Check>;
template <typename Database, typename... Args> template <typename Database, typename... Tables>
auto _using_impl(const std::true_type&, Args... args) const auto _using_impl(consistent_t, Tables... tables) const
-> _new_statement_t<std::true_type, using_t<_database_t, Args...>> -> _new_statement_t<consistent_t, using_t<_database_t, Tables...>>
{ {
static_assert(not detail::has_duplicates<Args...>::value, static_assert(not detail::has_duplicates<Tables...>::value,
"at least one duplicate argument detected in using()"); "at least one duplicate argument detected in using()");
return {static_cast<const derived_statement_t<Policies>&>(*this), using_data_t<Database, Args...>{args...}}; return {static_cast<const derived_statement_t<Policies>&>(*this), using_data_t<Database, Tables...>{tables...}};
} }
}; };
}; };

View File

@ -94,7 +94,7 @@ namespace sqlpp
static_assert(not contains_aggregate_function_t<Expr>::value, static_assert(not contains_aggregate_function_t<Expr>::value,
"where expression must not contain aggregate functions"); "where expression must not contain aggregate functions");
using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expr>; using _serialize_check = sqlpp::serialize_check_t<typename Database::_serializer_context_t, Expr>;
_serialize_check::_(); _serialize_check{};
using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value, _serialize_check::type::value>; using ok = logic::all_t<_is_dynamic::value, is_expression_t<Expr>::value, _serialize_check::type::value>;
@ -307,14 +307,14 @@ namespace sqlpp
using _database_t = typename Policies::_database_t; using _database_t = typename Policies::_database_t;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check::value, Policies, no_where_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_where_t, T>;
using _consistency_check = using _consistency_check =
typename std::conditional<WhereRequired and (Policies::_all_provided_tables::size::value > 0), typename std::conditional<WhereRequired and (Policies::_all_provided_tables::size::value > 0),
assert_where_t, assert_where_t,
consistent_t>::type; consistent_t>::type;
auto unconditionally() const -> _new_statement_t<std::true_type, where_t<void, unconditional_t>> auto unconditionally() const -> _new_statement_t<consistent_t, where_t<void, unconditional_t>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, unconditional_t>{}}; return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, unconditional_t>{}};
} }
@ -324,8 +324,6 @@ namespace sqlpp
-> _new_statement_t<check_where_static_t<Expression>, where_t<void, Expression>> -> _new_statement_t<check_where_static_t<Expression>, where_t<void, Expression>>
{ {
using Check = check_where_static_t<Expression>; using Check = check_where_static_t<Expression>;
Check{}._();
return _where_impl<void>(Check{}, expression); return _where_impl<void>(Check{}, expression);
} }
@ -334,8 +332,6 @@ namespace sqlpp
-> _new_statement_t<check_where_dynamic_t<_database_t, Expression>, where_t<_database_t, Expression>> -> _new_statement_t<check_where_dynamic_t<_database_t, Expression>, where_t<_database_t, Expression>>
{ {
using Check = check_where_dynamic_t<_database_t, Expression>; using Check = check_where_dynamic_t<_database_t, Expression>;
Check{}._();
return _where_impl<_database_t>(Check{}, expression); return _where_impl<_database_t>(Check{}, expression);
} }
@ -346,12 +342,12 @@ namespace sqlpp
} }
private: private:
template <typename Database, typename Expression> template <typename Database, typename Check, typename Expression>
auto _where_impl(const std::false_type&, Expression expression) const -> bad_statement; auto _where_impl(Check, Expression expression) const -> inconsistent<Check>;
template <typename Database, typename Expression> template <typename Database, typename Expression>
auto _where_impl(const std::true_type&, Expression expression) const auto _where_impl(consistent_t, Expression expression) const
-> _new_statement_t<std::true_type, where_t<Database, Expression>> -> _new_statement_t<consistent_t, where_t<Database, Expression>>
{ {
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
where_data_t<Database, Expression>{expression}}; where_data_t<Database, Expression>{expression}};

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015, Roland Bock * Copyright (c) 2013-2016, Roland Bock
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
@ -29,15 +29,15 @@
#include <sqlpp11/assignment.h> #include <sqlpp11/assignment.h>
#include <sqlpp11/column_fwd.h> #include <sqlpp11/column_fwd.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/expression.h> #include <sqlpp11/expression.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/interpret_tuple.h>
#include <sqlpp11/interpretable_list.h> #include <sqlpp11/interpretable_list.h>
#include <sqlpp11/logic.h> #include <sqlpp11/logic.h>
#include <sqlpp11/no_data.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/policy_update.h>
#include <sqlpp11/statement_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/cte.h> #include <sqlpp11/cte.h>
@ -96,8 +96,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : with{std::forward<Args>(args)...}
: with{std::forward<Args>(args)...}
{ {
} }
@ -151,8 +150,7 @@ namespace sqlpp
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 // workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args> template <typename... Args>
_base_t(Args&&... args) _base_t(Args&&... args) : no_with{std::forward<Args>(args)...}
: no_with{std::forward<Args>(args)...}
{ {
} }
@ -183,7 +181,7 @@ namespace sqlpp
template <typename Statement> template <typename Statement>
auto operator()(Statement statement) auto operator()(Statement statement)
-> new_statement_t<true, typename Statement::_policies_t, no_with_t, with_t<Database, Expressions...>> -> new_statement_t<consistent_t, typename Statement::_policies_t, no_with_t, with_t<Database, Expressions...>>
{ {
// FIXME need checks here // FIXME need checks here
// check that no cte refers to any of the ctes to the right // check that no cte refers to any of the ctes to the right

View File

@ -29,7 +29,7 @@
#include <iostream> #include <iostream>
SQLPP_ALIAS_PROVIDER(pragma); SQLPP_ALIAS_PROVIDER(pragma)
int CustomQuery(int, char* []) int CustomQuery(int, char* [])
{ {

View File

@ -23,104 +23,95 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "Sample.h"
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h"
#include <iostream>
#include <sqlpp11/alias_provider.h> #include <sqlpp11/alias_provider.h>
#include <sqlpp11/select.h>
#include <sqlpp11/functions.h>
#include <sqlpp11/connection.h> #include <sqlpp11/connection.h>
#include <sqlpp11/functions.h>
namespace sqlpp #include <sqlpp11/select.h>
{
namespace test
{
template <typename T>
void print_type_on_error(std::true_type, const T&)
{
}
template <typename T>
void print_type_on_error(std::false_type, const T& t)
{
t._print_me_;
}
template <typename Assert, typename Expression>
void run_check(const Expression&)
{
using Context = MockDb::_serializer_context_t;
using CheckResult = std::is_same<sqlpp::run_check_t<Context, Expression>, Assert>;
static_assert(CheckResult::value, "Unexpected run_check result");
print_type_on_error(CheckResult{}, sqlpp::run_check_t<Context, Expression>{});
}
template <typename Expression>
void run_check(const Expression&)
{
using Context = MockDb::_serializer_context_t;
using CheckResult = std::is_same<sqlpp::run_check_t<Context, Expression>, consistent_t>;
static_assert(CheckResult::value, "Unexpected run_check result");
print_type_on_error(CheckResult{}, sqlpp::run_check_t<Context, Expression>{});
}
}
}
namespace namespace
{ {
template <typename T>
void print_type_on_error(std::true_type)
{
}
template <typename T>
void print_type_on_error(std::false_type)
{
T::_print_me_;
}
template <typename Assert, typename Expression>
void static_run_check(const Expression&)
{
using Context = MockDb::_serializer_context_t;
using CheckResult = sqlpp::run_check_t<Context, Expression>;
using ExpectedCheckResult = std::is_same<CheckResult, Assert>;
print_type_on_error<CheckResult>(ExpectedCheckResult{});
static_assert(ExpectedCheckResult::value, "Unexpected check result");
}
SQLPP_ALIAS_PROVIDER(whatever) SQLPP_ALIAS_PROVIDER(whatever)
using sqlpp::test::run_check;
static constexpr auto t = test::TabBar{}; static constexpr auto t = test::TabBar{};
// 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).unconditionally()); static_run_check<sqlpp::consistent_t>(select(all_of(t)).from(t).unconditionally());
run_check(select(t.alpha).from(t).unconditionally()); static_run_check<sqlpp::consistent_t>(select(t.alpha).from(t).unconditionally());
run_check(select(count(t.alpha)).from(t).unconditionally()); static_run_check<sqlpp::consistent_t>(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).unconditionally()); static_run_check<sqlpp::consistent_t>(select(all_of(t)).from(t).unconditionally());
run_check(select(t.alpha).from(t).unconditionally()); static_run_check<sqlpp::consistent_t>(select(t.alpha).from(t).unconditionally());
run_check(select(count(t.alpha)).from(t).unconditionally()); static_run_check<sqlpp::consistent_t>(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).unconditionally().group_by(t.alpha)); static_run_check<sqlpp::consistent_t>(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)); static_run_check<sqlpp::consistent_t>(
run_check(select((t.alpha + 42).as(whatever)).from(t).unconditionally().group_by(t.alpha, t.alpha + t.delta * 17)); select((t.alpha + 42).as(whatever)).from(t).unconditionally().group_by(t.alpha));
run_check(select((t.alpha + t.delta * 17).as(whatever)) static_run_check<sqlpp::consistent_t>(
select((t.alpha + 42).as(whatever)).from(t).unconditionally().group_by(t.alpha, t.alpha + t.delta * 17));
static_run_check<sqlpp::consistent_t>(select((t.alpha + t.delta * 17).as(whatever))
.from(t) .from(t)
.unconditionally() .unconditionally()
.group_by(t.alpha, t.alpha + t.delta * 17)); .group_by(t.alpha, t.alpha + t.delta * 17));
run_check(select((t.beta + "fortytwo").as(whatever)).from(t).unconditionally().group_by(t.beta)); static_run_check<sqlpp::consistent_t>(
select((t.beta + "fortytwo").as(whatever)).from(t).unconditionally().group_by(t.beta));
run_check(select(avg(t.alpha)).from(t).unconditionally().group_by(t.beta)); static_run_check<sqlpp::consistent_t>(select(avg(t.alpha)).from(t).unconditionally().group_by(t.beta));
run_check(select(count(t.alpha)).from(t).unconditionally().group_by(t.beta)); static_run_check<sqlpp::consistent_t>(select(count(t.alpha)).from(t).unconditionally().group_by(t.beta));
run_check(select(max(t.alpha)).from(t).unconditionally().group_by(t.beta)); static_run_check<sqlpp::consistent_t>(select(max(t.alpha)).from(t).unconditionally().group_by(t.beta));
run_check(select(min(t.alpha)).from(t).unconditionally().group_by(t.beta)); static_run_check<sqlpp::consistent_t>(select(min(t.alpha)).from(t).unconditionally().group_by(t.beta));
run_check(select(sum(t.alpha)).from(t).unconditionally().group_by(t.beta)); static_run_check<sqlpp::consistent_t>(select(sum(t.alpha)).from(t).unconditionally().group_by(t.beta));
run_check(select((t.alpha + count(t.delta)).as(whatever)).from(t).unconditionally().group_by(t.alpha)); static_run_check<sqlpp::consistent_t>(
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).unconditionally().group_by(t.alpha)); static_run_check<sqlpp::consistent_t>(
run_check(select(sqlpp::value("whatever").as(whatever)).from(t).unconditionally().group_by(t.alpha)); select(sqlpp::value(1).as(whatever)).from(t).unconditionally().group_by(t.alpha));
static_run_check<sqlpp::consistent_t>(
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_no_unknown_aggregates_t>(select(t.beta).from(t).unconditionally().group_by(t.alpha)); static_run_check<sqlpp::assert_no_unknown_aggregates_t>(select(t.beta).from(t).unconditionally().group_by(t.alpha));
run_check<sqlpp::assert_no_unknown_aggregates_t>( static_run_check<sqlpp::assert_no_unknown_aggregates_t>(
select((t.alpha + t.delta).as(whatever)).from(t).unconditionally().group_by(t.alpha)); select((t.alpha + t.delta).as(whatever)).from(t).unconditionally().group_by(t.alpha));
run_check<sqlpp::assert_no_unknown_aggregates_t>( static_run_check<sqlpp::assert_no_unknown_aggregates_t>(
select((t.alpha + t.delta).as(whatever)).from(t).unconditionally().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));
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2015, Roland Bock * Copyright (c) 2015-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,
@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -52,7 +52,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(sqlpp::case_when(when)); using ReturnType = decltype(sqlpp::case_when(when));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, void>::value>; using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -66,7 +66,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(sqlpp::case_when(when).then(then)); using ReturnType = decltype(sqlpp::case_when(when).then(then));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, void>::value>; using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -80,7 +80,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(sqlpp::case_when(when).then(then).else_(else_)); using ReturnType = decltype(sqlpp::case_when(when).then(then).else_(else_));
using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, void>::value>; using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }

View File

@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -53,8 +53,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(select(t.alpha).from(expression)); using ReturnType = decltype(select(t.alpha).from(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -69,8 +68,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(dynamic_select(db, t.alpha).dynamic_from(expression)); using ReturnType = decltype(dynamic_select(db, t.alpha).dynamic_from(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -120,8 +118,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(from.add(expression)); using ReturnType = decltype(from.add(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }

View File

@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -53,8 +53,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(select(all_of(t)).from(t).unconditionally().group_by(t.alpha).having(expression)); using ReturnType = decltype(select(all_of(t)).from(t).unconditionally().group_by(t.alpha).having(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -70,8 +69,7 @@ namespace
using ReturnType = using ReturnType =
decltype(dynamic_select(db, all_of(t)).from(t).unconditionally().group_by(t.alpha).dynamic_having(expression)); decltype(dynamic_select(db, all_of(t)).from(t).unconditionally().group_by(t.alpha).dynamic_having(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -140,7 +138,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(select(all_of(t)).from(t).dynamic_having()); using ReturnType = decltype(select(all_of(t)).from(t).dynamic_having());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::bad_statement>; using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_where_dynamic_statement_dynamic_t>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2015, Roland Bock * Copyright (c) 2015-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,
@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -53,8 +53,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(insert_into(t).set(assignments...)); using ReturnType = decltype(insert_into(t).set(assignments...));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -69,8 +68,7 @@ namespace
print_type_on_error<CheckResult>(ExpectedCheckResult{}); print_type_on_error<CheckResult>(ExpectedCheckResult{});
using ReturnType = decltype(dynamic_insert_into(db, t).dynamic_set(assignments...)); using ReturnType = decltype(dynamic_insert_into(db, t).dynamic_set(assignments...));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
} }
@ -162,7 +160,7 @@ namespace
print_type_on_error<CheckResult>(ExpectedCheckResult{}); print_type_on_error<CheckResult>(ExpectedCheckResult{});
using ReturnType = decltype(insert_into(t).dynamic_set()); using ReturnType = decltype(insert_into(t).dynamic_set());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::bad_statement>; using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_insert_dynamic_set_statement_dynamic_t>;
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
} }

View File

@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -62,12 +62,9 @@ namespace
(Assert::value and sqlpp::is_pre_join_t<JoinType>::value and sqlpp::is_pre_join_t<InnerJoinType>::value and (Assert::value and sqlpp::is_pre_join_t<JoinType>::value and sqlpp::is_pre_join_t<InnerJoinType>::value and
sqlpp::is_pre_join_t<LeftOuterJoinType>::value and sqlpp::is_pre_join_t<RightOuterJoinType>::value and sqlpp::is_pre_join_t<LeftOuterJoinType>::value and sqlpp::is_pre_join_t<RightOuterJoinType>::value and
sqlpp::is_pre_join_t<OuterJoinType>::value and sqlpp::is_join_t<CrossJoinType>::value) xor sqlpp::is_pre_join_t<OuterJoinType>::value and sqlpp::is_join_t<CrossJoinType>::value) xor
(std::is_same<JoinType, sqlpp::bad_statement>::value and (std::is_same<JoinType, Assert>::value and std::is_same<InnerJoinType, Assert>::value and
std::is_same<InnerJoinType, sqlpp::bad_statement>::value and std::is_same<LeftOuterJoinType, Assert>::value and std::is_same<RightOuterJoinType, Assert>::value and
std::is_same<LeftOuterJoinType, sqlpp::bad_statement>::value and std::is_same<OuterJoinType, Assert>::value and std::is_same<CrossJoinType, Assert>::value)>;
std::is_same<RightOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<OuterJoinType, sqlpp::bad_statement>::value and
std::is_same<CrossJoinType, sqlpp::bad_statement>::value)>;
print_type_on_error<JoinType>(ExpectedReturnType{}); print_type_on_error<JoinType>(ExpectedReturnType{});
print_type_on_error<InnerJoinType>(ExpectedReturnType{}); print_type_on_error<InnerJoinType>(ExpectedReturnType{});
print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{}); print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{});
@ -87,7 +84,7 @@ namespace
using ResultType = decltype(lhs.on(rhs)); using ResultType = decltype(lhs.on(rhs));
using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_join_t<ResultType>::value) xor using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_join_t<ResultType>::value) xor
std::is_same<ResultType, sqlpp::bad_statement>::value>; std::is_same<ResultType, Assert>::value>;
print_type_on_error<ResultType>(ExpectedReturnType{}); print_type_on_error<ResultType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -190,18 +187,15 @@ namespace
using RightOuterJoinType = decltype(sqlpp::dynamic_right_outer_join(table)); using RightOuterJoinType = decltype(sqlpp::dynamic_right_outer_join(table));
using OuterJoinType = decltype(sqlpp::dynamic_outer_join(table)); using OuterJoinType = decltype(sqlpp::dynamic_outer_join(table));
using CrossJoinType = decltype(sqlpp::dynamic_cross_join(table)); using CrossJoinType = decltype(sqlpp::dynamic_cross_join(table));
using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_dynamic_pre_join_t<JoinType>::value and using ExpectedReturnType = sqlpp::logic::all_t<
(Assert::value and sqlpp::is_dynamic_pre_join_t<JoinType>::value and
sqlpp::is_dynamic_pre_join_t<InnerJoinType>::value and sqlpp::is_dynamic_pre_join_t<InnerJoinType>::value and
sqlpp::is_dynamic_pre_join_t<LeftOuterJoinType>::value and sqlpp::is_dynamic_pre_join_t<LeftOuterJoinType>::value and
sqlpp::is_dynamic_pre_join_t<RightOuterJoinType>::value and sqlpp::is_dynamic_pre_join_t<RightOuterJoinType>::value and
sqlpp::is_dynamic_pre_join_t<OuterJoinType>::value and sqlpp::is_dynamic_pre_join_t<OuterJoinType>::value and sqlpp::is_dynamic_join_t<CrossJoinType>::value) xor
sqlpp::is_dynamic_join_t<CrossJoinType>::value) xor (std::is_same<JoinType, Assert>::value and std::is_same<InnerJoinType, Assert>::value and
(std::is_same<JoinType, sqlpp::bad_statement>::value and std::is_same<LeftOuterJoinType, Assert>::value and std::is_same<RightOuterJoinType, Assert>::value and
std::is_same<InnerJoinType, sqlpp::bad_statement>::value and std::is_same<OuterJoinType, Assert>::value and std::is_same<CrossJoinType, Assert>::value)>;
std::is_same<LeftOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<RightOuterJoinType, sqlpp::bad_statement>::value and
std::is_same<OuterJoinType, sqlpp::bad_statement>::value and
std::is_same<CrossJoinType, sqlpp::bad_statement>::value)>;
print_type_on_error<JoinType>(ExpectedReturnType{}); print_type_on_error<JoinType>(ExpectedReturnType{});
print_type_on_error<InnerJoinType>(ExpectedReturnType{}); print_type_on_error<InnerJoinType>(ExpectedReturnType{});
print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{}); print_type_on_error<LeftOuterJoinType>(ExpectedReturnType{});
@ -221,7 +215,7 @@ namespace
using ResultType = decltype(lhs.on(rhs)); using ResultType = decltype(lhs.on(rhs));
using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_dynamic_join_t<ResultType>::value) xor using ExpectedReturnType = sqlpp::logic::all_t<(Assert::value and sqlpp::is_dynamic_join_t<ResultType>::value) xor
std::is_same<ResultType, sqlpp::bad_statement>::value>; std::is_same<ResultType, Assert>::value>;
print_type_on_error<ResultType>(ExpectedReturnType{}); print_type_on_error<ResultType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }

View File

@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -82,8 +82,7 @@ namespace
void where_check(const Condition& condition) void where_check(const Condition& condition)
{ {
using ReturnType = decltype(sqlpp::where(condition)); using ReturnType = decltype(sqlpp::where(condition));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -104,7 +103,7 @@ namespace
void where() void where()
{ {
where_check<sqlpp::consistent_t>(t.gamma); where_check<sqlpp::consistent_t>(t.gamma);
where_check<sqlpp::bad_statement>(true); where_check<sqlpp::assert_where_not_cpp_bool_t>(true);
} }
} }

View File

@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -53,8 +53,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(update(t).set(expressions...)); using ReturnType = decltype(update(t).set(expressions...));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -69,8 +68,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(dynamic_update(db, t).dynamic_set(expressions...)); using ReturnType = decltype(dynamic_update(db, t).dynamic_set(expressions...));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -127,7 +125,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(update(t).dynamic_set()); using ReturnType = decltype(update(t).dynamic_set());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::bad_statement>; using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_update_dynamic_set_statement_dynamic_t>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }

View File

@ -23,9 +23,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <iostream>
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h" #include "Sample.h"
#include <iostream>
#include <sqlpp11/sqlpp11.h> #include <sqlpp11/sqlpp11.h>
namespace namespace
@ -52,8 +52,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(remove_from(t).where(expression)); using ReturnType = decltype(remove_from(t).where(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -68,8 +67,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(dynamic_remove_from(db, t).dynamic_where(expression)); using ReturnType = decltype(dynamic_remove_from(db, t).dynamic_where(expression));
using ExpectedReturnType = using ExpectedReturnType = sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, Assert>::value>;
sqlpp::logic::all_t<Assert::value xor std::is_same<ReturnType, sqlpp::bad_statement>::value>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }
@ -140,7 +138,7 @@ namespace
static_assert(ExpectedCheckResult::value, "Unexpected check result"); static_assert(ExpectedCheckResult::value, "Unexpected check result");
using ReturnType = decltype(remove_from(t).dynamic_where()); using ReturnType = decltype(remove_from(t).dynamic_where());
using ExpectedReturnType = std::is_same<ReturnType, sqlpp::bad_statement>; using ExpectedReturnType = std::is_same<ReturnType, sqlpp::assert_where_dynamic_statement_dynamic_t>;
print_type_on_error<ReturnType>(ExpectedReturnType{}); print_type_on_error<ReturnType>(ExpectedReturnType{});
static_assert(ExpectedReturnType::value, "Unexpected return type"); static_assert(ExpectedReturnType::value, "Unexpected return type");
} }

View File

@ -1,4 +1,4 @@
# 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,

View File

@ -23,12 +23,12 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "Sample.h"
#include "MockDb.h" #include "MockDb.h"
#include "Sample.h"
#include "is_regular.h" #include "is_regular.h"
#include <sqlpp11/insert.h>
#include <sqlpp11/functions.h>
#include <iostream> #include <iostream>
#include <sqlpp11/functions.h>
#include <sqlpp11/insert.h>
int Insert(int, char* []) int Insert(int, char* [])
{ {

View File

@ -26,13 +26,13 @@
#ifndef SQLPP_MOCK_DB_H #ifndef SQLPP_MOCK_DB_H
#define SQLPP_MOCK_DB_H #define SQLPP_MOCK_DB_H
#include <sstream>
#include <iostream> #include <iostream>
#include <sqlpp11/schema.h> #include <sqlpp11/connection.h>
#include <sqlpp11/data_types/no_value.h> #include <sqlpp11/data_types/no_value.h>
#include <sqlpp11/schema.h>
#include <sqlpp11/serialize.h> #include <sqlpp11/serialize.h>
#include <sqlpp11/serializer_context.h> #include <sqlpp11/serializer_context.h>
#include <sqlpp11/connection.h> #include <sstream>
template <bool enforceNullResultTreatment> template <bool enforceNullResultTreatment>
struct MockDbT : public sqlpp::connection struct MockDbT : public sqlpp::connection
@ -111,18 +111,17 @@ struct MockDbT : public sqlpp::connection
// Directly executed statements start here // Directly executed statements start here
template <typename T> template <typename T>
auto _run(const T& t, const std::true_type&) -> decltype(t._run(*this)) auto _run(const T& t, ::sqlpp::consistent_t) -> decltype(t._run(*this))
{ {
return t._run(*this); return t._run(*this);
} }
template <typename T> template <typename Check, typename T>
auto _run(const T& t, const std::false_type&) -> void; auto _run(const T& t, Check) -> Check;
template <typename T> template <typename T>
auto operator()(const T& t) -> decltype(this->_run(t, sqlpp::run_check_t<_serializer_context_t, T>{})) auto operator()(const T& t) -> decltype(this->_run(t, sqlpp::run_check_t<_serializer_context_t, T>{}))
{ {
sqlpp::run_check_t<_serializer_context_t, T>::_();
return _run(t, sqlpp::run_check_t<_serializer_context_t, T>{}); return _run(t, sqlpp::run_check_t<_serializer_context_t, T>{});
} }
@ -182,18 +181,17 @@ struct MockDbT : public sqlpp::connection
using _prepared_statement_t = std::nullptr_t; using _prepared_statement_t = std::nullptr_t;
template <typename T> template <typename T>
auto _prepare(const T& t, const std::true_type&) -> decltype(t._prepare(*this)) auto _prepare(const T& t, ::sqlpp::consistent_t) -> decltype(t._prepare(*this))
{ {
return t._prepare(*this); return t._prepare(*this);
} }
template <typename T> template <typename Check, typename T>
auto _prepare(const T& t, const std::false_type&) -> void; auto _prepare(const T& t, Check) -> Check;
template <typename T> template <typename T>
auto prepare(const T& t) -> decltype(this->_prepare(t, sqlpp::prepare_check_t<_serializer_context_t, T>{})) auto prepare(const T& t) -> decltype(this->_prepare(t, sqlpp::prepare_check_t<_serializer_context_t, T>{}))
{ {
sqlpp::prepare_check_t<_serializer_context_t, T>::_();
return _prepare(t, sqlpp::prepare_check_t<_serializer_context_t, T>{}); return _prepare(t, sqlpp::prepare_check_t<_serializer_context_t, T>{});
} }

View File

@ -122,8 +122,8 @@ int Select(int, char* [])
.group_by(t.alpha) .group_by(t.alpha)
.order_by(t.gamma.asc()) .order_by(t.gamma.asc())
.having(t.gamma) .having(t.gamma)
.limit(7) .offset(19)
.offset(19); .limit(7);
printer.reset(); printer.reset();
std::cerr << serialize(stat, printer).str() << std::endl; std::cerr << serialize(stat, printer).str() << std::endl;