mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Adjusted remaining select parts
This commit is contained in:
parent
98bb9a7db7
commit
b00fe51fed
@ -203,13 +203,13 @@ namespace sqlpp
|
|||||||
vendor::no_select_flag_list_t,
|
vendor::no_select_flag_list_t,
|
||||||
vendor::no_select_column_list_t,
|
vendor::no_select_column_list_t,
|
||||||
vendor::no_from_t,
|
vendor::no_from_t,
|
||||||
//vendor::no_extra_tables_t,
|
vendor::no_extra_tables_t,
|
||||||
vendor::no_where_t/*,
|
vendor::no_where_t,
|
||||||
vendor::no_group_by_t,
|
vendor::no_group_by_t,
|
||||||
vendor::no_having_t,
|
vendor::no_having_t,
|
||||||
vendor::no_order_by_t,
|
vendor::no_order_by_t,
|
||||||
vendor::no_limit_t,
|
vendor::no_limit_t,
|
||||||
vendor::no_offset_t*/>;
|
vendor::no_offset_t>;
|
||||||
|
|
||||||
|
|
||||||
blank_select_t<void> select() // FIXME: These should be constexpr
|
blank_select_t<void> select() // FIXME: These should be constexpr
|
||||||
|
37
include/sqlpp11/vendor/extra_tables.h
vendored
37
include/sqlpp11/vendor/extra_tables.h
vendored
@ -84,9 +84,17 @@ namespace sqlpp
|
|||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
|
using _data_t = extra_tables_data_t<Tables...>;
|
||||||
|
|
||||||
_impl_t<Policies> extra_tables;
|
_impl_t<Policies> extra_tables;
|
||||||
_impl_t<Policies>& operator()() { return extra_tables; }
|
_impl_t<Policies>& operator()() { return extra_tables; }
|
||||||
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.extra_tables)
|
||||||
|
{
|
||||||
|
return t.extra_tables;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Additional methods for the statement
|
// Additional methods for the statement
|
||||||
@ -103,9 +111,7 @@ namespace sqlpp
|
|||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
struct _data_t
|
using _data_t = no_data_t;
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
// Member implementation with data and methods
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
@ -118,9 +124,17 @@ namespace sqlpp
|
|||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _member_t
|
struct _member_t
|
||||||
{
|
{
|
||||||
_impl_t<Policies> no_extra_tables_t;
|
using _data_t = no_data_t;
|
||||||
_impl_t<Policies>& operator()() { return no_extra_tables_t; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_extra_tables_t; }
|
_impl_t<Policies> no_extra_tables;
|
||||||
|
_impl_t<Policies>& operator()() { return no_extra_tables; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_extra_tables; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_extra_tables)
|
||||||
|
{
|
||||||
|
return t.no_extra_tables;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
@ -150,17 +164,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, typename no_extra_tables_t::_data_t>
|
|
||||||
{
|
|
||||||
using T = typename no_extra_tables_t::_data_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
128
include/sqlpp11/vendor/group_by.h
vendored
128
include/sqlpp11/vendor/group_by.h
vendored
@ -39,6 +39,24 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// GROUP BY DATA
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct group_by_data_t
|
||||||
|
{
|
||||||
|
group_by_data_t(Expressions... expressions):
|
||||||
|
_expressions(expressions...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
group_by_data_t(const group_by_data_t&) = default;
|
||||||
|
group_by_data_t(group_by_data_t&&) = default;
|
||||||
|
group_by_data_t& operator=(const group_by_data_t&) = default;
|
||||||
|
group_by_data_t& operator=(group_by_data_t&&) = default;
|
||||||
|
~group_by_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Expressions...> _expressions;
|
||||||
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
|
};
|
||||||
|
|
||||||
// GROUP BY
|
// GROUP BY
|
||||||
template<typename Database, typename... Expressions>
|
template<typename Database, typename... Expressions>
|
||||||
struct group_by_t
|
struct group_by_t
|
||||||
@ -54,60 +72,100 @@ namespace sqlpp
|
|||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
||||||
|
|
||||||
group_by_t& _group_by() { return *this; }
|
// Data
|
||||||
|
using _data_t = select_flag_list_data_t<Database, Expressions...>;
|
||||||
group_by_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
group_by_t(const group_by_t&) = default;
|
|
||||||
group_by_t(group_by_t&&) = default;
|
|
||||||
group_by_t& operator=(const group_by_t&) = default;
|
|
||||||
group_by_t& operator=(group_by_t&&) = default;
|
|
||||||
~group_by_t() = default;
|
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _impl_t
|
||||||
{
|
{
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void add_group_by_ntc(Expression expression)
|
void add_ntc(Expression expression)
|
||||||
{
|
{
|
||||||
add_group_by<Expression, std::false_type>(expression);
|
add<Expression, std::false_type>(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||||
void add_group_by(Expression expression)
|
void add(Expression expression)
|
||||||
{
|
{
|
||||||
static_assert(_is_dynamic::value, "add_group_by must not be called for static group_by");
|
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
||||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_group_by()");
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_group_by()");
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||||
|
|
||||||
_add_group_by_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void _add_group_by_impl(Expression expression, const std::true_type&)
|
void _add_impl(Expression expression, const std::true_type&)
|
||||||
{
|
{
|
||||||
return static_cast<typename Policies::_statement_t*>(this)->_group_by()._dynamic_expressions.emplace_back(expression);
|
return _data._dynamic_expressions.emplace_back(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void _add_group_by_impl(Expression expression, const std::false_type&);
|
void _add_impl(Expression expression, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const group_by_t& _group_by() const { return *this; }
|
// Member template for adding the named member to a statement
|
||||||
std::tuple<Expressions...> _expressions;
|
template<typename Policies>
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> group_by;
|
||||||
|
_impl_t<Policies>& operator()() { return group_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return group_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.group_by)
|
||||||
|
{
|
||||||
|
return t.group_by;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO GROUP BY YET
|
||||||
struct no_group_by_t
|
struct no_group_by_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_group_by;
|
||||||
|
_impl_t<Policies>& operator()() { return no_group_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_group_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_group_by)
|
||||||
|
{
|
||||||
|
return t.no_group_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
@ -119,7 +177,7 @@ namespace sqlpp
|
|||||||
auto group_by(Args... args)
|
auto group_by(Args... args)
|
||||||
-> _new_statement_t<group_by_t<void, Args...>>
|
-> _new_statement_t<group_by_t<void, Args...>>
|
||||||
{
|
{
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_t<void, Args...>{args...} };
|
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<void, Args...>{args...} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@ -127,16 +185,16 @@ namespace sqlpp
|
|||||||
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::group_by_t<_database_t, Args...>{args...} };
|
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<_database_t, Args...>{args...} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interpreters
|
// Interpreters
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
struct serializer_t<Context, group_by_t<Database, Expressions...>>
|
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
||||||
{
|
{
|
||||||
using T = group_by_t<Database, Expressions...>;
|
using T = group_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -150,18 +208,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, no_group_by_t>
|
|
||||||
{
|
|
||||||
using T = no_group_by_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
129
include/sqlpp11/vendor/having.h
vendored
129
include/sqlpp11/vendor/having.h
vendored
@ -38,6 +38,24 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// HAVING DATA
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct having_data_t
|
||||||
|
{
|
||||||
|
having_data_t(Expressions... expressions):
|
||||||
|
_expressions(expressions...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
having_data_t(const having_data_t&) = default;
|
||||||
|
having_data_t(having_data_t&&) = default;
|
||||||
|
having_data_t& operator=(const having_data_t&) = default;
|
||||||
|
having_data_t& operator=(having_data_t&&) = default;
|
||||||
|
~having_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Expressions...> _expressions;
|
||||||
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
|
};
|
||||||
|
|
||||||
// HAVING
|
// HAVING
|
||||||
template<typename Database, typename... Expressions>
|
template<typename Database, typename... Expressions>
|
||||||
struct having_t
|
struct having_t
|
||||||
@ -50,59 +68,102 @@ namespace sqlpp
|
|||||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
||||||
|
|
||||||
having_t& _having() { return *this; }
|
// Data
|
||||||
|
using _data_t = having_data_t<Database, Expressions...>;
|
||||||
having_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
having_t(const having_t&) = default;
|
|
||||||
having_t(having_t&&) = default;
|
|
||||||
having_t& operator=(const having_t&) = default;
|
|
||||||
having_t& operator=(having_t&&) = default;
|
|
||||||
~having_t() = default;
|
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
template <typename Policies>
|
template <typename Policies>
|
||||||
struct _methods_t
|
struct _impl_t
|
||||||
{
|
{
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void add_having_ntc(Expression expression)
|
void add_ntc(Expression expression)
|
||||||
{
|
{
|
||||||
add_having<Expression, std::false_type>(expression);
|
add<Expression, std::false_type>(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||||
void add_having(Expression expression)
|
void add(Expression expression)
|
||||||
{
|
{
|
||||||
static_assert(_is_dynamic::value, "add_having must not be called for static having");
|
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
||||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_having()");
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_having()");
|
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||||
|
|
||||||
_add_having_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void _add_having_impl(Expression expression, const std::true_type&)
|
void _add_impl(Expression expression, const std::true_type&)
|
||||||
{
|
{
|
||||||
return static_cast<typename Policies::_statement_t*>(this)->_having()._dynamic_expressions.emplace_back(expression);
|
return _data._dynamic_expressions.emplace_back(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void _add_having_impl(Expression expression, const std::false_type&);
|
void _add_impl(Expression expression, const std::false_type&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
// Member template for adding the named member to a statement
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = having_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> having;
|
||||||
|
_impl_t<Policies>& operator()() { return having; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return having; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.having)
|
||||||
|
{
|
||||||
|
return t.having;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO HAVING YET
|
||||||
struct no_having_t
|
struct no_having_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_having;
|
||||||
|
_impl_t<Policies>& operator()() { return no_having; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_having; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_having)
|
||||||
|
{
|
||||||
|
return t.no_having;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
@ -114,7 +175,7 @@ namespace sqlpp
|
|||||||
auto having(Args... args)
|
auto having(Args... args)
|
||||||
-> _new_statement_t<having_t<void, Args...>>
|
-> _new_statement_t<having_t<void, Args...>>
|
||||||
{
|
{
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), having_t<void, Args...>{args...} };
|
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<void, Args...>{args...} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@ -122,16 +183,16 @@ namespace sqlpp
|
|||||||
-> _new_statement_t<having_t<_database_t, Args...>>
|
-> _new_statement_t<having_t<_database_t, Args...>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::having_t<_database_t, Args...>{args...} };
|
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<_database_t, Args...>{args...} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interpreters
|
// Interpreters
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
struct serializer_t<Context, having_t<Database, Expressions...>>
|
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
||||||
{
|
{
|
||||||
using T = having_t<Database, Expressions...>;
|
using T = having_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -145,18 +206,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, no_having_t>
|
|
||||||
{
|
|
||||||
using T = no_having_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
178
include/sqlpp11/vendor/limit.h
vendored
178
include/sqlpp11/vendor/limit.h
vendored
@ -35,6 +35,23 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// LIMIT DATA
|
||||||
|
template<typename Limit>
|
||||||
|
struct limit_data_t
|
||||||
|
{
|
||||||
|
limit_data_t(Limit value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
limit_data_t(const limit_data_t&) = default;
|
||||||
|
limit_data_t(limit_data_t&&) = default;
|
||||||
|
limit_data_t& operator=(const limit_data_t&) = default;
|
||||||
|
limit_data_t& operator=(limit_data_t&&) = default;
|
||||||
|
~limit_data_t() = default;
|
||||||
|
|
||||||
|
Limit _value;
|
||||||
|
};
|
||||||
|
|
||||||
// LIMIT
|
// LIMIT
|
||||||
template<typename Limit>
|
template<typename Limit>
|
||||||
struct limit_t
|
struct limit_t
|
||||||
@ -44,65 +61,109 @@ namespace sqlpp
|
|||||||
|
|
||||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||||
|
|
||||||
limit_t(Limit value):
|
// Data
|
||||||
_value(value)
|
using _data_t = limit_data_t<Limit>;
|
||||||
{}
|
|
||||||
|
|
||||||
limit_t(const limit_t&) = default;
|
// Member implementation with data and methods
|
||||||
limit_t(limit_t&&) = default;
|
template <typename Policies>
|
||||||
limit_t& operator=(const limit_t&) = default;
|
struct _impl_t
|
||||||
limit_t& operator=(limit_t&&) = default;
|
{
|
||||||
~limit_t() = default;
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
_impl_t<Policies> limit;
|
||||||
|
_impl_t<Policies>& operator()() { return limit; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return limit; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.limit)
|
||||||
|
{
|
||||||
|
return t.limit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
Limit _value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// DYNAMIC LIMIT DATA
|
||||||
|
template<typename Database>
|
||||||
|
struct dynamic_limit_data_t
|
||||||
|
{
|
||||||
|
dynamic_limit_data_t():
|
||||||
|
_value(noop())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Limit>
|
||||||
|
dynamic_limit_data_t(Limit value):
|
||||||
|
_initialized(true),
|
||||||
|
_value(typename wrap_operand<Limit>::type(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
|
||||||
|
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
|
||||||
|
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
|
||||||
|
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
|
||||||
|
~dynamic_limit_data_t() = default;
|
||||||
|
|
||||||
|
bool _initialized = false;
|
||||||
|
interpretable_t<Database> _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// DYNAMIC LIMIT
|
||||||
template<typename Database>
|
template<typename Database>
|
||||||
struct dynamic_limit_t
|
struct dynamic_limit_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
dynamic_limit_t& _limit() { return *this; }
|
// Data
|
||||||
|
using _data_t = limit_data_t<Database>;
|
||||||
dynamic_limit_t():
|
|
||||||
_value(noop())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Limit>
|
|
||||||
dynamic_limit_t(Limit value):
|
|
||||||
_initialized(true),
|
|
||||||
_value(typename wrap_operand<Limit>::type(value))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic_limit_t(const dynamic_limit_t&) = default;
|
|
||||||
dynamic_limit_t(dynamic_limit_t&&) = default;
|
|
||||||
dynamic_limit_t& operator=(const dynamic_limit_t&) = default;
|
|
||||||
dynamic_limit_t& operator=(dynamic_limit_t&&) = default;
|
|
||||||
~dynamic_limit_t() = default;
|
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
template <typename Policies>
|
template <typename Policies>
|
||||||
struct _methods_t
|
struct _impl_t
|
||||||
{
|
{
|
||||||
template<typename Limit>
|
template<typename Limit>
|
||||||
void set_limit(Limit value)
|
void set(Limit value)
|
||||||
{
|
{
|
||||||
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
||||||
using arg_t = typename wrap_operand<Limit>::type;
|
using arg_t = typename wrap_operand<Limit>::type;
|
||||||
static_cast<typename Policies::_statement_t*>(this)->_limit()._value = arg_t{value};
|
_data._value = arg_t{value};
|
||||||
static_cast<typename Policies::_statement_t*>(this)->_limit()._initialized = true;
|
_data._initialized = true;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
_impl_t<Policies> limit;
|
||||||
|
_impl_t<Policies>& operator()() { return limit; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return limit; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.limit)
|
||||||
|
{
|
||||||
|
return t.limit;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool _initialized = false;
|
// Additional methods for the statement
|
||||||
interpretable_t<Database> _value;
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct no_limit_t
|
struct no_limit_t
|
||||||
@ -110,6 +171,33 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_limit;
|
||||||
|
_impl_t<Policies>& operator()() { return no_limit; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_limit; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_limit)
|
||||||
|
{
|
||||||
|
return t.no_limit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
@ -121,23 +209,23 @@ namespace sqlpp
|
|||||||
auto limit(Arg arg)
|
auto limit(Arg arg)
|
||||||
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
||||||
{
|
{
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), limit_t<typename wrap_operand<Arg>::type>{{arg}} };
|
return { *static_cast<typename Policies::_statement_t*>(this), limit_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dynamic_limit()
|
auto dynamic_limit()
|
||||||
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_t<_database_t>{} };
|
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_data_t<_database_t>{} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interpreters
|
// Interpreters
|
||||||
template<typename Context, typename Database>
|
template<typename Context, typename Database>
|
||||||
struct serializer_t<Context, dynamic_limit_t<Database>>
|
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
||||||
{
|
{
|
||||||
using T = dynamic_limit_t<Database>;
|
using T = dynamic_limit_data_t<Database>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -162,18 +250,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, no_limit_t>
|
|
||||||
{
|
|
||||||
using T = no_limit_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
159
include/sqlpp11/vendor/offset.h
vendored
159
include/sqlpp11/vendor/offset.h
vendored
@ -35,6 +35,23 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// OFFSET DATA
|
||||||
|
template<typename Offset>
|
||||||
|
struct offset_data_t
|
||||||
|
{
|
||||||
|
offset_data_t(Offset value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
offset_data_t(const offset_data_t&) = default;
|
||||||
|
offset_data_t(offset_data_t&&) = default;
|
||||||
|
offset_data_t& operator=(const offset_data_t&) = default;
|
||||||
|
offset_data_t& operator=(offset_data_t&&) = default;
|
||||||
|
~offset_data_t() = default;
|
||||||
|
|
||||||
|
Offset _value;
|
||||||
|
};
|
||||||
|
|
||||||
// OFFSET
|
// OFFSET
|
||||||
template<typename Offset>
|
template<typename Offset>
|
||||||
struct offset_t
|
struct offset_t
|
||||||
@ -44,49 +61,103 @@ namespace sqlpp
|
|||||||
|
|
||||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||||
|
|
||||||
offset_t(Offset value):
|
// Data
|
||||||
_value(value)
|
using _data_t = offset_data_t<Offset>;
|
||||||
{}
|
|
||||||
|
|
||||||
offset_t(const offset_t&) = default;
|
// Member implementation with data and methods
|
||||||
offset_t(offset_t&&) = default;
|
template <typename Policies>
|
||||||
offset_t& operator=(const offset_t&) = default;
|
struct _impl_t
|
||||||
offset_t& operator=(offset_t&&) = default;
|
{
|
||||||
~offset_t() = default;
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
_impl_t<Policies> offset;
|
||||||
|
_impl_t<Policies>& operator()() { return offset; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return offset; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.offset)
|
||||||
|
{
|
||||||
|
return t.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
Offset _value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// DYNAMIC OFFSET DATA
|
||||||
|
template<typename Database>
|
||||||
|
struct dynamic_offset_data_t
|
||||||
|
{
|
||||||
|
dynamic_offset_data_t():
|
||||||
|
_value(noop())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Offset>
|
||||||
|
dynamic_offset_data_t(Offset value):
|
||||||
|
_initialized(true),
|
||||||
|
_value(typename wrap_operand<Offset>::type(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
|
||||||
|
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
|
||||||
|
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
|
||||||
|
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
|
||||||
|
~dynamic_offset_data_t() = default;
|
||||||
|
|
||||||
|
bool _initialized = false;
|
||||||
|
interpretable_t<Database> _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// DYNAMIC OFFSET
|
||||||
template<typename Database>
|
template<typename Database>
|
||||||
struct dynamic_offset_t
|
struct dynamic_offset_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
dynamic_offset_t& _offset() { return *this; }
|
// Data
|
||||||
|
using _data_t = offset_data_t<Database>;
|
||||||
|
|
||||||
dynamic_offset_t():
|
// Member implementation with data and methods
|
||||||
_value(noop())
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Offset>
|
template<typename Offset>
|
||||||
dynamic_offset_t(Offset value):
|
void set(Offset value)
|
||||||
_initialized(true),
|
|
||||||
_value(typename wrap_operand<Offset>::type(value))
|
|
||||||
{
|
{
|
||||||
|
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||||
|
using arg_t = typename wrap_operand<Offset>::type;
|
||||||
|
_data._value = arg_t{value};
|
||||||
|
_data._initialized = true;
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
dynamic_offset_t(const dynamic_offset_t&) = default;
|
// Member template for adding the named member to a statement
|
||||||
dynamic_offset_t(dynamic_offset_t&&) = default;
|
template<typename Policies>
|
||||||
dynamic_offset_t& operator=(const dynamic_offset_t&) = default;
|
struct _member_t
|
||||||
dynamic_offset_t& operator=(dynamic_offset_t&&) = default;
|
{
|
||||||
~dynamic_offset_t() = default;
|
_impl_t<Policies> offset;
|
||||||
|
_impl_t<Policies>& operator()() { return offset; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return offset; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.offset)
|
||||||
|
{
|
||||||
|
return t.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
@ -110,6 +181,33 @@ namespace sqlpp
|
|||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_offset;
|
||||||
|
_impl_t<Policies>& operator()() { return no_offset; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_offset; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_offset)
|
||||||
|
{
|
||||||
|
return t.no_offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
@ -121,14 +219,14 @@ namespace sqlpp
|
|||||||
auto offset(Arg arg)
|
auto offset(Arg arg)
|
||||||
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
||||||
{
|
{
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), offset_t<typename wrap_operand<Arg>::type>{{arg}} };
|
return { *static_cast<typename Policies::_statement_t*>(this), offset_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dynamic_offset()
|
auto dynamic_offset()
|
||||||
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_t<_database_t>{} };
|
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_data_t<_database_t>{} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -162,17 +260,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, no_offset_t>
|
|
||||||
{
|
|
||||||
using T = no_offset_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
184
include/sqlpp11/vendor/order_by.h
vendored
184
include/sqlpp11/vendor/order_by.h
vendored
@ -39,73 +39,133 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// ORDER BY DATA
|
||||||
template<typename Database, typename... Expressions>
|
template<typename Database, typename... Expressions>
|
||||||
struct order_by_t
|
struct order_by_data_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
order_by_data_t(Expressions... expressions):
|
||||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one sort-order expression required in order_by()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_sort_order_t<Expressions>::value...>::value, "at least one argument is not a sort order expression in order_by()");
|
|
||||||
|
|
||||||
order_by_t& _order_by() { return *this; }
|
|
||||||
|
|
||||||
order_by_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
_expressions(expressions...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
order_by_t(const order_by_t&) = default;
|
order_by_data_t(const order_by_data_t&) = default;
|
||||||
order_by_t(order_by_t&&) = default;
|
order_by_data_t(order_by_data_t&&) = default;
|
||||||
order_by_t& operator=(const order_by_t&) = default;
|
order_by_data_t& operator=(const order_by_data_t&) = default;
|
||||||
order_by_t& operator=(order_by_t&&) = default;
|
order_by_data_t& operator=(order_by_data_t&&) = default;
|
||||||
~order_by_t() = default;
|
~order_by_data_t() = default;
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
template<typename Expression>
|
|
||||||
void add_order_by_ntc(Expression expression)
|
|
||||||
{
|
|
||||||
add_order_by<Expression, std::false_type>(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
|
||||||
void add_order_by(Expression expression)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "add_order_by must not be called for static order_by");
|
|
||||||
static_assert(is_sort_order_t<Expression>::value, "invalid expression argument in add_order_by()");
|
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_order_by()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value>;
|
|
||||||
|
|
||||||
_add_order_by_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_order_by_impl(Expression expression, const std::true_type&)
|
|
||||||
{
|
|
||||||
return static_cast<typename Policies::_statement_t*>(this)->_order_by()._dynamic_expressions.emplace_back(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_order_by_impl(Expression expression, const std::false_type&);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
std::tuple<Expressions...> _expressions;
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ORDER BY
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct order_by_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = select_flag_list_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Expression>
|
||||||
|
void add_ntc(Expression expression)
|
||||||
|
{
|
||||||
|
add<Expression, std::false_type>(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Expression expression)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
||||||
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||||
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||||
|
|
||||||
|
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_expressions.emplace_back(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> order_by;
|
||||||
|
_impl_t<Policies>& operator()() { return order_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return order_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.order_by)
|
||||||
|
{
|
||||||
|
return t.order_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO ORDER BY YET
|
||||||
struct no_order_by_t
|
struct no_order_by_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_order_by;
|
||||||
|
_impl_t<Policies>& operator()() { return no_order_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_order_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_order_by)
|
||||||
|
{
|
||||||
|
return t.no_order_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Policies>
|
template<typename Policies>
|
||||||
struct _methods_t
|
struct _methods_t
|
||||||
{
|
{
|
||||||
@ -117,7 +177,7 @@ namespace sqlpp
|
|||||||
auto order_by(Args... args)
|
auto order_by(Args... args)
|
||||||
-> _new_statement_t<order_by_t<void, Args...>>
|
-> _new_statement_t<order_by_t<void, Args...>>
|
||||||
{
|
{
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_t<void, Args...>{args...} };
|
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<void, Args...>{args...} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@ -125,16 +185,16 @@ namespace sqlpp
|
|||||||
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::order_by_t<_database_t, Args...>{args...} };
|
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<_database_t, Args...>{args...} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interpreters
|
// Interpreters
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
struct serializer_t<Context, order_by_t<Database, Expressions...>>
|
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
||||||
{
|
{
|
||||||
using T = order_by_t<Database, Expressions...>;
|
using T = order_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -148,18 +208,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, no_order_by_t>
|
|
||||||
{
|
|
||||||
using T = no_order_by_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
include/sqlpp11/vendor/select_flag_list.h
vendored
2
include/sqlpp11/vendor/select_flag_list.h
vendored
@ -38,7 +38,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
// SELECTED COLUMNS DATA
|
// SELECTED FLAGS DATA
|
||||||
template<typename Database, typename... Flags>
|
template<typename Database, typename... Flags>
|
||||||
struct select_flag_list_data_t
|
struct select_flag_list_data_t
|
||||||
{
|
{
|
||||||
|
1
include/sqlpp11/vendor/where.h
vendored
1
include/sqlpp11/vendor/where.h
vendored
@ -38,6 +38,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// WHERE DATA
|
||||||
template<typename Database, typename... Expressions>
|
template<typename Database, typename... Expressions>
|
||||||
struct where_data_t
|
struct where_data_t
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user