mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Migrated select components to support policy based select
This commit is contained in:
parent
9c4832df0f
commit
62b828ef8f
@ -28,7 +28,6 @@
|
|||||||
#define SQLPP_SELECT_H
|
#define SQLPP_SELECT_H
|
||||||
|
|
||||||
#include <sqlpp11/result.h>
|
#include <sqlpp11/result.h>
|
||||||
#include <sqlpp11/select_fwd.h>
|
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_select.h>
|
#include <sqlpp11/prepared_select.h>
|
||||||
|
|
||||||
@ -45,74 +44,69 @@
|
|||||||
#include <sqlpp11/vendor/expression.h>
|
#include <sqlpp11/vendor/expression.h>
|
||||||
#include <sqlpp11/vendor/interpreter.h>
|
#include <sqlpp11/vendor/interpreter.h>
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/vendor/wrong.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
|
#include <sqlpp11/vendor/policy.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
|
||||||
|
|
||||||
#include <sqlpp11/detail/make_flag_tuple.h>
|
#include <sqlpp11/detail/make_flag_tuple.h>
|
||||||
#include <sqlpp11/detail/make_expression_tuple.h>
|
#include <sqlpp11/detail/make_expression_tuple.h>
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<
|
namespace detail
|
||||||
typename Database,
|
{
|
||||||
typename FlagList,
|
template<
|
||||||
typename ColumnList,
|
typename FlagList,
|
||||||
typename From,
|
typename ColumnList,
|
||||||
typename Where,
|
typename From,
|
||||||
typename GroupBy,
|
typename Where,
|
||||||
typename Having,
|
typename GroupBy,
|
||||||
typename OrderBy,
|
typename Having,
|
||||||
typename Limit,
|
typename OrderBy,
|
||||||
typename Offset
|
typename Limit,
|
||||||
>
|
typename Offset
|
||||||
struct select_t
|
>
|
||||||
: public ColumnList::_value_type::template operators<select_t<
|
struct check_select_t
|
||||||
Database,
|
{
|
||||||
FlagList,
|
//static_assert(is_where_t<Where>::value, "cannot select remove without having a where condition, use .where(true) to remove all rows");
|
||||||
ColumnList,
|
static constexpr bool value = true;
|
||||||
From,
|
};
|
||||||
Where,
|
}
|
||||||
GroupBy,
|
|
||||||
Having,
|
|
||||||
OrderBy,
|
|
||||||
Limit,
|
|
||||||
Offset>>
|
|
||||||
{
|
|
||||||
using _Database = Database;
|
|
||||||
using _From = From;
|
|
||||||
|
|
||||||
static_assert(is_select_flag_list_t<FlagList>::value, "invalid list of select flags");
|
template<typename Database, typename... Policies>
|
||||||
static_assert(is_select_column_list_t<ColumnList>::value, "invalid list of select expressions");
|
struct select_t: public vendor::policy_t<Policies>..., public vendor::crtp_wrapper_t<select_t<Database, Policies...>, Policies>...
|
||||||
static_assert(vendor::is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
|
{
|
||||||
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
|
template<typename Needle, typename Replacement>
|
||||||
static_assert(vendor::is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
|
using _policy_update_t = select_t<Database, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||||
static_assert(vendor::is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
|
|
||||||
static_assert(vendor::is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
|
using _database_t = Database;
|
||||||
static_assert(vendor::is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
|
using _parameter_tuple_t = std::tuple<Policies...>;
|
||||||
static_assert(vendor::is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
|
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
|
||||||
|
|
||||||
|
select_t()
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename Whatever>
|
||||||
|
select_t(select_t r, Whatever whatever):
|
||||||
|
vendor::policy_t<Policies>(r, whatever)...
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename Remove, typename Whatever>
|
||||||
|
select_t(Remove r, Whatever whatever):
|
||||||
|
vendor::policy_t<Policies>(r, whatever)...
|
||||||
|
{}
|
||||||
|
|
||||||
|
select_t(const select_t& r) = default;
|
||||||
|
select_t(select_t&& r) = default;
|
||||||
|
select_t& operator=(const select_t& r) = default;
|
||||||
|
select_t& operator=(select_t&& r) = default;
|
||||||
|
~select_t() = default;
|
||||||
|
|
||||||
using _is_select = std::true_type;
|
using _is_select = std::true_type;
|
||||||
using _requires_braces = std::true_type;
|
using _requires_braces = std::true_type;
|
||||||
|
|
||||||
template<typename FlagListT>
|
/*
|
||||||
using set_flag_list_t = select_t<Database, FlagListT, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
|
||||||
template<typename ColumnListT>
|
|
||||||
using set_column_list_t = select_t<Database, FlagList, ColumnListT, From, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
|
||||||
template<typename FromT>
|
|
||||||
using set_from_t = select_t<Database, FlagList, ColumnList, FromT, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
|
||||||
template<typename WhereT>
|
|
||||||
using set_where_t = select_t<Database, FlagList, ColumnList, From, WhereT, GroupBy, Having, OrderBy, Limit, Offset>;
|
|
||||||
template<typename GroupByT>
|
|
||||||
using set_group_by_t = select_t<Database, FlagList, ColumnList, From, Where, GroupByT, Having, OrderBy, Limit, Offset>;
|
|
||||||
template<typename HavingT>
|
|
||||||
using set_having_t = select_t<Database, FlagList, ColumnList, From, Where, GroupBy, HavingT, OrderBy, Limit, Offset>;
|
|
||||||
template<typename OrderByT>
|
|
||||||
using set_order_by_t = select_t<Database, FlagList, ColumnList, From, Where, GroupBy, Having, OrderByT, Limit, Offset>;
|
|
||||||
template<typename LimitT>
|
|
||||||
using set_limit_t = select_t<Database, FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, LimitT, Offset>;
|
|
||||||
template<typename OffsetT>
|
|
||||||
using set_offset_t = select_t<Database, FlagList, ColumnList, From, Where, GroupBy, Having, OrderBy, Limit, OffsetT>;
|
|
||||||
|
|
||||||
using _result_row_t = typename ColumnList::_result_row_t;
|
using _result_row_t = typename ColumnList::_result_row_t;
|
||||||
using _dynamic_names_t = typename ColumnList::_dynamic_names_t;
|
using _dynamic_names_t = typename ColumnList::_dynamic_names_t;
|
||||||
using _parameter_tuple_t = std::tuple<ColumnList, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
using _parameter_tuple_t = std::tuple<ColumnList, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||||
@ -640,58 +634,21 @@ namespace sqlpp
|
|||||||
|
|
||||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
FlagList _flags;
|
|
||||||
ColumnList _columns;
|
|
||||||
From _from;
|
|
||||||
Where _where;
|
|
||||||
GroupBy _group_by;
|
|
||||||
Having _having;
|
|
||||||
OrderBy _order_by;
|
|
||||||
Limit _limit;
|
|
||||||
Offset _offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Context,
|
template<typename Context, typename Database, typename... Policies>
|
||||||
typename Database,
|
struct interpreter_t<Context, select_t<Database, Policies...>>
|
||||||
typename FlagList,
|
|
||||||
typename ColumnList,
|
|
||||||
typename From,
|
|
||||||
typename Where,
|
|
||||||
typename GroupBy,
|
|
||||||
typename Having,
|
|
||||||
typename OrderBy,
|
|
||||||
typename Limit,
|
|
||||||
typename Offset
|
|
||||||
>
|
|
||||||
struct interpreter_t<Context, select_t<Database,
|
|
||||||
FlagList,
|
|
||||||
ColumnList,
|
|
||||||
From,
|
|
||||||
Where,
|
|
||||||
GroupBy,
|
|
||||||
Having,
|
|
||||||
OrderBy,
|
|
||||||
Limit,
|
|
||||||
Offset>>
|
|
||||||
{
|
{
|
||||||
using T = select_t<Database,
|
using T = select_t<Database, Policies...>;
|
||||||
FlagList,
|
|
||||||
ColumnList,
|
|
||||||
From,
|
|
||||||
Where,
|
|
||||||
GroupBy,
|
|
||||||
Having,
|
|
||||||
OrderBy,
|
|
||||||
Limit,
|
|
||||||
Offset>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
context << "SELECT ";
|
context << "SELECT ";
|
||||||
|
|
||||||
|
/*
|
||||||
interpret(t._flags, context);
|
interpret(t._flags, context);
|
||||||
interpret(t._columns, context);
|
interpret(t._columns, context);
|
||||||
interpret(t._from, context);
|
interpret(t._from, context);
|
||||||
@ -701,6 +658,7 @@ namespace sqlpp
|
|||||||
interpret(t._order_by, context);
|
interpret(t._order_by, context);
|
||||||
interpret(t._limit, context);
|
interpret(t._limit, context);
|
||||||
interpret(t._offset, context);
|
interpret(t._offset, context);
|
||||||
|
*/
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
@ -708,6 +666,8 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
// construct select flag list
|
// construct select flag list
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
@ -751,6 +711,7 @@ namespace sqlpp
|
|||||||
{}, {}, {}, {}, {}, {}, {}
|
{}, {}, {}, {}, {}, {}, {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,27 +31,7 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
template<typename Database, typename... Policies>
|
||||||
{
|
|
||||||
struct noop;
|
|
||||||
}
|
|
||||||
// select flags
|
|
||||||
struct all_t;
|
|
||||||
struct distinct_t;
|
|
||||||
struct straight_join_t;
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename Db,
|
|
||||||
typename Flags = vendor::noop,
|
|
||||||
typename ExpressionList = vendor::noop,
|
|
||||||
typename From = vendor::noop,
|
|
||||||
typename Where = vendor::noop,
|
|
||||||
typename GroupBy = vendor::noop,
|
|
||||||
typename Having = vendor::noop,
|
|
||||||
typename OrderBy = vendor::noop,
|
|
||||||
typename Limit = vendor::noop,
|
|
||||||
typename Offset = vendor::noop
|
|
||||||
>
|
|
||||||
struct select_t;
|
struct select_t;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
4
include/sqlpp11/vendor/from.h
vendored
4
include/sqlpp11/vendor/from.h
vendored
@ -83,7 +83,6 @@ namespace sqlpp
|
|||||||
no_from_t& _from = *this;
|
no_from_t& _from = *this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// CRTP Wrappers
|
// CRTP Wrappers
|
||||||
template<typename Derived, typename Database, typename... Args>
|
template<typename Derived, typename Database, typename... Args>
|
||||||
struct crtp_wrapper_t<Derived, from_t<Database, Args...>>
|
struct crtp_wrapper_t<Derived, from_t<Database, Args...>>
|
||||||
@ -109,7 +108,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Interpreters
|
// Interpreters
|
||||||
template<typename Context, typename Database, typename... Tables>
|
template<typename Context, typename Database, typename... Tables>
|
||||||
struct interpreter_t<Context, from_t<Database, Tables...>>
|
struct interpreter_t<Context, from_t<Database, Tables...>>
|
||||||
@ -139,8 +137,8 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
90
include/sqlpp11/vendor/group_by.h
vendored
90
include/sqlpp11/vendor/group_by.h
vendored
@ -32,57 +32,111 @@
|
|||||||
#include <sqlpp11/vendor/expression.h>
|
#include <sqlpp11/vendor/expression.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
#include <sqlpp11/vendor/interpretable_list.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
#include <sqlpp11/detail/logic.h>
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Database, typename... Expr>
|
// GROUP BY
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
struct group_by_t
|
struct group_by_t
|
||||||
{
|
{
|
||||||
using _is_group_by = std::true_type;
|
using _is_group_by = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
using _parameter_tuple_t = std::tuple<Expressions...>;
|
||||||
|
|
||||||
// ensure one argument at least
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
|
|
||||||
|
|
||||||
// check for duplicate expressions
|
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
|
|
||||||
|
|
||||||
// check for invalid expressions
|
static_assert(::sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in group_by()");
|
||||||
static_assert(::sqlpp::detail::and_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in group_by()");
|
|
||||||
|
|
||||||
template<typename E>
|
group_by_t(Expressions... expressions):
|
||||||
void add(E expr)
|
_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;
|
||||||
|
|
||||||
|
template<typename Expression>
|
||||||
|
void add_group_by(Expression expression)
|
||||||
{
|
{
|
||||||
static_assert(is_table_t<E>::value, "from arguments require to be tables or joins");
|
static_assert(is_table_t<Expression>::value, "from arguments require to be tables or joins");
|
||||||
_dynamic_expressions.emplace_back(expr);
|
_dynamic_expressions.emplace_back(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_by_t& _group_by = *this;
|
||||||
_parameter_tuple_t _expressions;
|
_parameter_tuple_t _expressions;
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Database, typename... Expr>
|
struct no_group_by_t
|
||||||
struct interpreter_t<Context, group_by_t<Database, Expr...>>
|
{
|
||||||
|
using _is_group_by = std::true_type;
|
||||||
|
no_group_by_t& _group_by = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Database, typename... Args>
|
||||||
|
struct crtp_wrapper_t<Derived, group_by_t<Database, Args...>>
|
||||||
{
|
{
|
||||||
using T = group_by_t<Database, Expr...>;
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_group_by_t>
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
auto group_by(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_group_by_t, group_by_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), group_by_t<void, Args...>(args...) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_group_by(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_group_by_t, group_by_t<get_database_t<Derived>, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), group_by_t<get_database_t<Derived>, Args...>(args...) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
|
struct interpreter_t<Context, group_by_t<Database, Expressions...>>
|
||||||
|
{
|
||||||
|
using T = group_by_t<Database, Expressions...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
return context;
|
return context;
|
||||||
context << " GROUP BY ";
|
context << " GROUP BY ";
|
||||||
interpret_tuple(t._expressions, ',', context);
|
interpret_tuple(t._expressions, ',', context);
|
||||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
context << ',';
|
context << ',';
|
||||||
interpret_list(t._dynamic_expressions, ',', context);
|
interpret_list(t._dynamic_expressions, ',', context);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, no_group_by_t>
|
||||||
|
{
|
||||||
|
using T = no_group_by_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
72
include/sqlpp11/vendor/having.h
vendored
72
include/sqlpp11/vendor/having.h
vendored
@ -31,52 +31,100 @@
|
|||||||
#include <sqlpp11/vendor/expression.h>
|
#include <sqlpp11/vendor/expression.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
#include <sqlpp11/vendor/interpretable_list.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
#include <sqlpp11/detail/logic.h>
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Database, typename... Expr>
|
// HAVING
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
struct having_t
|
struct having_t
|
||||||
{
|
{
|
||||||
using _is_having = std::true_type;
|
using _is_having = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
using _parameter_tuple_t = std::tuple<Expressions...>;
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "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::and_t<is_expression_t, Expr...>::value, "at least one argument is not an expression in having()");
|
static_assert(::sqlpp::detail::and_t<is_expression_t, Expressions...>::value, "at least one argument is not an expression in having()");
|
||||||
|
|
||||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||||
|
|
||||||
template<typename E>
|
template<typename Expression>
|
||||||
void add(E expr)
|
void add(Expression expr)
|
||||||
{
|
{
|
||||||
static_assert(is_expression_t<E>::value, "invalid expression argument in add_having()");
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_having()");
|
||||||
_dynamic_expressions.emplace_back(expr);
|
_dynamic_expressions.emplace_back(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
having_t& _having = *this;
|
||||||
_parameter_tuple_t _expressions;
|
_parameter_tuple_t _expressions;
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Database, typename... Expr>
|
struct no_having_t
|
||||||
struct interpreter_t<Context, having_t<Database, Expr...>>
|
{
|
||||||
|
using _is_having = std::true_type;
|
||||||
|
no_having_t& _having = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Database, typename... Args>
|
||||||
|
struct crtp_wrapper_t<Derived, having_t<Database, Args...>>
|
||||||
{
|
{
|
||||||
using T = having_t<Database, Expr...>;
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_having_t>
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
auto having(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_having_t, having_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), having_t<void, Args...>(args...) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_having(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_having_t, having_t<get_database_t<Derived>, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_having must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), having_t<get_database_t<Derived>, Args...>(args...) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
|
struct interpreter_t<Context, having_t<Database, Expressions...>>
|
||||||
|
{
|
||||||
|
using T = having_t<Database, Expressions...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
return context;
|
return context;
|
||||||
context << " HAVING ";
|
context << " HAVING ";
|
||||||
interpret_tuple(t._expressions, " AND ", context);
|
interpret_tuple(t._expressions, " AND ", context);
|
||||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
context << " AND ";
|
context << " AND ";
|
||||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, no_having_t>
|
||||||
|
{
|
||||||
|
using T = no_having_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
114
include/sqlpp11/vendor/limit.h
vendored
114
include/sqlpp11/vendor/limit.h
vendored
@ -27,21 +27,106 @@
|
|||||||
#ifndef SQLPP_LIMIT_H
|
#ifndef SQLPP_LIMIT_H
|
||||||
#define SQLPP_LIMIT_H
|
#define SQLPP_LIMIT_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/select_fwd.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// LIMIT
|
||||||
template<typename Limit>
|
template<typename Limit>
|
||||||
struct limit_t
|
struct limit_t
|
||||||
{
|
{
|
||||||
using _is_limit = std::true_type;
|
using _is_limit = std::true_type;
|
||||||
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 _limit;
|
limit_t(size_t value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
limit_t(const limit_t&) = default;
|
||||||
|
limit_t(limit_t&&) = default;
|
||||||
|
limit_t& operator=(const limit_t&) = default;
|
||||||
|
limit_t& operator=(limit_t&&) = default;
|
||||||
|
~limit_t() = default;
|
||||||
|
|
||||||
|
limit_t& _limit = *this;
|
||||||
|
Limit _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dynamic_limit_t
|
||||||
|
{
|
||||||
|
using _is_limit = std::true_type;
|
||||||
|
using _is_dynamic = std::true_type;
|
||||||
|
|
||||||
|
dynamic_limit_t(size_t value):
|
||||||
|
_value(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;
|
||||||
|
|
||||||
|
void set_limit(std::size_t limit)
|
||||||
|
{
|
||||||
|
_value = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_limit_t& _limit = *this;
|
||||||
|
std::size_t _value; // FIXME: This should be a serializable!
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_limit_t
|
||||||
|
{
|
||||||
|
using _is_limit = std::true_type;
|
||||||
|
no_limit_t& _limit = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Limit>
|
||||||
|
struct crtp_wrapper_t<Derived, limit_t<Limit>>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, dynamic_limit_t>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_limit_t>
|
||||||
|
{
|
||||||
|
template<typename Arg>
|
||||||
|
auto limit(Arg arg)
|
||||||
|
-> vendor::update_policies_t<Derived, no_limit_t, limit_t<Arg>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), limit_t<Arg>(arg) };
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dynamic_limit(size_t arg)
|
||||||
|
-> vendor::update_policies_t<Derived, no_limit_t, dynamic_limit_t>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_limit must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), dynamic_limit_t(arg) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, dynamic_limit_t>
|
||||||
|
{
|
||||||
|
using T = dynamic_limit_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (t._value > 0)
|
||||||
|
context << " LIMIT " << t._limit;
|
||||||
|
return context;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Limit>
|
template<typename Context, typename Limit>
|
||||||
@ -52,38 +137,23 @@ namespace sqlpp
|
|||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
context << " LIMIT ";
|
context << " LIMIT ";
|
||||||
interpret(t._limit, context);
|
interpret(t._value, context);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynamic_limit_t
|
|
||||||
{
|
|
||||||
using _is_limit = std::true_type;
|
|
||||||
using _is_dynamic = std::true_type;
|
|
||||||
|
|
||||||
void set(std::size_t limit)
|
|
||||||
{
|
|
||||||
_limit = limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t _limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct interpreter_t<Context, dynamic_limit_t>
|
struct interpreter_t<Context, no_limit_t>
|
||||||
{
|
{
|
||||||
using T = dynamic_limit_t;
|
using T = no_limit_t;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
if (t._limit > 0)
|
|
||||||
context << " LIMIT " << t._limit;
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
101
include/sqlpp11/vendor/offset.h
vendored
101
include/sqlpp11/vendor/offset.h
vendored
@ -28,20 +28,94 @@
|
|||||||
#define SQLPP_OFFSET_H
|
#define SQLPP_OFFSET_H
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
|
// OFFSET
|
||||||
template<typename Offset>
|
template<typename Offset>
|
||||||
struct offset_t
|
struct offset_t
|
||||||
{
|
{
|
||||||
using _is_offset = std::true_type;
|
using _is_offset = std::true_type;
|
||||||
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 _offset;
|
offset_t(size_t value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
offset_t(const offset_t&) = default;
|
||||||
|
offset_t(offset_t&&) = default;
|
||||||
|
offset_t& operator=(const offset_t&) = default;
|
||||||
|
offset_t& operator=(offset_t&&) = default;
|
||||||
|
~offset_t() = default;
|
||||||
|
|
||||||
|
offset_t& _offset = *this;
|
||||||
|
Offset _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dynamic_offset_t
|
||||||
|
{
|
||||||
|
using _is_offset = std::true_type;
|
||||||
|
using _is_dynamic = std::true_type;
|
||||||
|
|
||||||
|
dynamic_offset_t(size_t value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
dynamic_offset_t(const dynamic_offset_t&) = default;
|
||||||
|
dynamic_offset_t(dynamic_offset_t&&) = default;
|
||||||
|
dynamic_offset_t& operator=(const dynamic_offset_t&) = default;
|
||||||
|
dynamic_offset_t& operator=(dynamic_offset_t&&) = default;
|
||||||
|
~dynamic_offset_t() = default;
|
||||||
|
|
||||||
|
void set_offset(std::size_t offset)
|
||||||
|
{
|
||||||
|
_value = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_offset_t& _offset = *this;
|
||||||
|
std::size_t _value; // FIXME: This should be a serializable!
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_offset_t
|
||||||
|
{
|
||||||
|
using _is_offset = std::true_type;
|
||||||
|
no_offset_t& _offset = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Limit>
|
||||||
|
struct crtp_wrapper_t<Derived, offset_t<Limit>>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, dynamic_offset_t>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_offset_t>
|
||||||
|
{
|
||||||
|
template<typename Arg>
|
||||||
|
auto offset(Arg arg)
|
||||||
|
-> vendor::update_policies_t<Derived, no_offset_t, offset_t<Arg>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), offset_t<Arg>(arg) };
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dynamic_offset(size_t arg)
|
||||||
|
-> vendor::update_policies_t<Derived, no_offset_t, dynamic_offset_t>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_offset must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), dynamic_offset_t(arg) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
template<typename Context, typename Offset>
|
template<typename Context, typename Offset>
|
||||||
struct interpreter_t<Context, offset_t<Offset>>
|
struct interpreter_t<Context, offset_t<Offset>>
|
||||||
{
|
{
|
||||||
@ -55,19 +129,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynamic_offset_t
|
|
||||||
{
|
|
||||||
using _is_offset = std::true_type;
|
|
||||||
using _is_dynamic = std::true_type;
|
|
||||||
|
|
||||||
void set(std::size_t offset)
|
|
||||||
{
|
|
||||||
_offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t _offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct interpreter_t<Context, dynamic_offset_t>
|
struct interpreter_t<Context, dynamic_offset_t>
|
||||||
{
|
{
|
||||||
@ -75,12 +136,22 @@ namespace sqlpp
|
|||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
if (t._offset > 0)
|
if (t._value > 0)
|
||||||
context << " OFFSET " << t._offset;
|
context << " OFFSET " << t._offset;
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, no_offset_t>
|
||||||
|
{
|
||||||
|
using T = no_offset_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
89
include/sqlpp11/vendor/order_by.h
vendored
89
include/sqlpp11/vendor/order_by.h
vendored
@ -32,55 +32,110 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <sqlpp11/vendor/interpretable.h>
|
#include <sqlpp11/vendor/interpretable.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Database,typename... Expr>
|
template<typename Database,typename... Expressions>
|
||||||
struct order_by_t
|
struct order_by_t
|
||||||
{
|
{
|
||||||
using _is_order_by = std::true_type;
|
using _is_order_by = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
using _parameter_tuple_t = std::tuple<Expressions...>;
|
||||||
|
|
||||||
// check for at least one order expression
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one sort-order expression required in order_by()");
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
|
|
||||||
|
|
||||||
// check for duplicate order expressions
|
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()");
|
|
||||||
|
|
||||||
// check for invalid order expressions
|
static_assert(::sqlpp::detail::and_t<is_sort_order_t, Expressions...>::value, "at least one argument is not a sort order expression in order_by()");
|
||||||
static_assert(::sqlpp::detail::and_t<is_sort_order_t, Expr...>::value, "at least one argument is not a sort order expression in order_by()");
|
|
||||||
|
|
||||||
template<typename E>
|
order_by_t(Expressions... expressions):
|
||||||
void add(E expr)
|
_expressions(expressions...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
order_by_t(const order_by_t&) = default;
|
||||||
|
order_by_t(order_by_t&&) = default;
|
||||||
|
order_by_t& operator=(const order_by_t&) = default;
|
||||||
|
order_by_t& operator=(order_by_t&&) = default;
|
||||||
|
~order_by_t() = default;
|
||||||
|
|
||||||
|
template<typename Expression>
|
||||||
|
void add_order_by(Expression expressions)
|
||||||
{
|
{
|
||||||
static_assert(is_sort_order_t<E>::value, "order_by arguments require to be sort-order expressions");
|
static_assert(is_sort_order_t<Expression>::value, "order_by arguments require to be sort-order expressions");
|
||||||
_dynamic_expressions.push_back(expr);
|
_dynamic_expressions.push_back(expressions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
order_by_t& _order_by = *this;
|
||||||
_parameter_tuple_t _expressions;
|
_parameter_tuple_t _expressions;
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Database, typename... Expr>
|
struct no_order_by_t
|
||||||
struct interpreter_t<Context, order_by_t<Database, Expr...>>
|
{
|
||||||
|
using _is_order_by = std::true_type;
|
||||||
|
no_order_by_t& _order_by = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Database, typename... Args>
|
||||||
|
struct crtp_wrapper_t<Derived, order_by_t<Database, Args...>>
|
||||||
{
|
{
|
||||||
using T = order_by_t<Database, Expr...>;
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_order_by_t>
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
auto order_by(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_order_by_t, order_by_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), order_by_t<void, Args...>(args...) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_order_by(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_order_by_t, order_by_t<get_database_t<Derived>, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), order_by_t<get_database_t<Derived>, Args...>(args...) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
|
struct interpreter_t<Context, order_by_t<Database, Expressions...>>
|
||||||
|
{
|
||||||
|
using T = order_by_t<Database, Expressions...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
return context;
|
return context;
|
||||||
context << " ORDER BY ";
|
context << " ORDER BY ";
|
||||||
interpret_tuple(t._expressions, ',', context);
|
interpret_tuple(t._expressions, ',', context);
|
||||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
context << ',';
|
context << ',';
|
||||||
interpret_list(t._dynamic_expressions, ',', context);
|
interpret_list(t._dynamic_expressions, ',', context);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, no_order_by_t>
|
||||||
|
{
|
||||||
|
using T = no_order_by_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
101
include/sqlpp11/vendor/select_column_list.h
vendored
101
include/sqlpp11/vendor/select_column_list.h
vendored
@ -37,6 +37,8 @@
|
|||||||
#include <sqlpp11/vendor/select_pseudo_table.h>
|
#include <sqlpp11/vendor/select_pseudo_table.h>
|
||||||
#include <sqlpp11/vendor/named_interpretable.h>
|
#include <sqlpp11/vendor/named_interpretable.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -130,69 +132,103 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename Database, typename T>
|
// SELECT COLUMNS
|
||||||
|
template<typename Database, typename... Columns>
|
||||||
struct select_column_list_t
|
struct select_column_list_t
|
||||||
{
|
|
||||||
static_assert(::sqlpp::vendor::wrong_t<Database, T>::value, "invalid template argument for select_column_list");
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Database, typename... NamedExpr>
|
|
||||||
struct select_column_list_t<Database, std::tuple<NamedExpr...>>
|
|
||||||
{
|
{
|
||||||
using _is_select_column_list = std::true_type;
|
using _is_select_column_list = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
using _parameter_tuple_t = std::tuple<NamedExpr...>;
|
using _parameter_tuple_t = std::tuple<Columns...>;
|
||||||
using size = std::tuple_size<_parameter_tuple_t>;
|
using size = std::tuple_size<_parameter_tuple_t>;
|
||||||
|
|
||||||
// check for duplicate select expressions
|
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
|
||||||
|
|
||||||
// check for invalid select expressions
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
|
using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
|
||||||
static_assert(::sqlpp::detail::and_t<is_valid_expression_t, NamedExpr...>::value, "at least one argument is not a named expression");
|
static_assert(::sqlpp::detail::and_t<is_valid_expression_t, Columns...>::value, "at least one argument is not a named expression");
|
||||||
|
|
||||||
// check for duplicate select expression names
|
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
|
|
||||||
|
|
||||||
// provide type information for sub-selects that are used as expressions
|
|
||||||
struct _column_type {};
|
struct _column_type {};
|
||||||
struct _value_type: ::sqlpp::detail::get_first_argument_if_unique<NamedExpr...>::_value_type
|
struct _value_type: ::sqlpp::detail::get_first_argument_if_unique<Columns...>::_value_type
|
||||||
{
|
{
|
||||||
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
using _is_expression = typename std::conditional<sizeof...(Columns) == 1, std::true_type, std::false_type>::type;
|
||||||
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
using _is_named_expression = typename std::conditional<sizeof...(Columns) == 1, std::true_type, std::false_type>::type;
|
||||||
using _is_alias = std::false_type;
|
using _is_alias = std::false_type;
|
||||||
};
|
};
|
||||||
using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique<NamedExpr...>::_name_t;
|
using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique<Columns...>::_name_t;
|
||||||
|
|
||||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||||
dynamic_result_row_t<make_field_t<NamedExpr>...>,
|
dynamic_result_row_t<make_field_t<Columns>...>,
|
||||||
result_row_t<make_field_t<NamedExpr>...>>::type;
|
result_row_t<make_field_t<Columns>...>>::type;
|
||||||
|
|
||||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||||
|
|
||||||
template <typename Select>
|
template <typename Select>
|
||||||
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
|
using _pseudo_table_t = select_pseudo_table_t<Select, Columns...>;
|
||||||
|
|
||||||
template <typename Db>
|
template <typename Db>
|
||||||
using _dynamic_t = select_column_list_t<Db, std::tuple<NamedExpr...>>;
|
using _dynamic_t = select_column_list_t<Db, std::tuple<Columns...>>;
|
||||||
|
|
||||||
|
select_column_list_t(Columns... columns):
|
||||||
|
_columns(columns...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
select_column_list_t(const select_column_list_t&) = default;
|
||||||
|
select_column_list_t(select_column_list_t&&) = default;
|
||||||
|
select_column_list_t& operator=(const select_column_list_t&) = default;
|
||||||
|
select_column_list_t& operator=(select_column_list_t&&) = default;
|
||||||
|
~select_column_list_t() = default;
|
||||||
|
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
void add(Expr namedExpr)
|
void add_column(Expr namedExpr)
|
||||||
{
|
{
|
||||||
static_assert(is_named_expression_t<Expr>::value, "select() arguments require to be named expressions");
|
static_assert(is_named_expression_t<Expr>::value, "select() arguments require to be named expressions");
|
||||||
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
|
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
|
||||||
_dynamic_columns.push_back(namedExpr);
|
_dynamic_columns.push_back(namedExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select_column_list_t& _column_list = *this;
|
||||||
_parameter_tuple_t _columns;
|
_parameter_tuple_t _columns;
|
||||||
dynamic_select_column_list<Database> _dynamic_columns;
|
dynamic_select_column_list<Database> _dynamic_columns;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Database, typename Tuple>
|
struct no_select_column_list_t
|
||||||
struct interpreter_t<Context, select_column_list_t<Database, Tuple>>
|
{
|
||||||
|
using _is_select_column_list = std::true_type;
|
||||||
|
no_select_column_list_t& _column_list = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Database, typename... Args>
|
||||||
|
struct crtp_wrapper_t<Derived, select_column_list_t<Database, Args...>>
|
||||||
{
|
{
|
||||||
using T = select_column_list_t<Database, Tuple>;
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_select_column_list_t>
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
auto columns(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_select_column_list_t, select_column_list_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), select_column_list_t<void, Args...>(args...) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_columns(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_select_column_list_t, select_column_list_t<get_database_t<Derived>, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_columns must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), select_column_list_t<get_database_t<Derived>, Args...>(args...) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Columns>
|
||||||
|
struct interpreter_t<Context, select_column_list_t<Database, Columns...>>
|
||||||
|
{
|
||||||
|
using T = select_column_list_t<Database, Columns...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -206,6 +242,17 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, no_select_column_list_t>
|
||||||
|
{
|
||||||
|
using T = no_select_column_list_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
92
include/sqlpp11/vendor/select_flag_list.h
vendored
92
include/sqlpp11/vendor/select_flag_list.h
vendored
@ -27,58 +27,95 @@
|
|||||||
#ifndef SQLPP_VENDOR_SELECT_FLAG_LIST_H
|
#ifndef SQLPP_VENDOR_SELECT_FLAG_LIST_H
|
||||||
#define SQLPP_VENDOR_SELECT_FLAG_LIST_H
|
#define SQLPP_VENDOR_SELECT_FLAG_LIST_H
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
#include <sqlpp11/select_fwd.h>
|
#include <sqlpp11/select_fwd.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/select_flags.h>
|
#include <sqlpp11/select_flags.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <tuple>
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace vendor
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Database, typename T>
|
// SELECT FLAGS
|
||||||
|
template<typename Database, typename... Flags>
|
||||||
struct select_flag_list_t
|
struct select_flag_list_t
|
||||||
{
|
|
||||||
static_assert(::sqlpp::vendor::wrong_t<T>::value, "invalid argument for select_flag_list");
|
|
||||||
};
|
|
||||||
|
|
||||||
// select_flag_list_t
|
|
||||||
template<typename Database, typename... Flag>
|
|
||||||
struct select_flag_list_t<Database, std::tuple<Flag...>>
|
|
||||||
{
|
{
|
||||||
using _is_select_flag_list = std::true_type;
|
using _is_select_flag_list = std::true_type;
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
using _parameter_tuple_t = std::tuple<Flag...>;
|
using _parameter_tuple_t = std::tuple<Flags...>;
|
||||||
using size = std::tuple_size<_parameter_tuple_t>;
|
using size = std::tuple_size<_parameter_tuple_t>;
|
||||||
|
|
||||||
// check for duplicate order expressions
|
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
|
|
||||||
|
|
||||||
// check for invalid order expressions
|
static_assert(::sqlpp::detail::and_t<is_select_flag_t, Flags...>::value, "at least one argument is not a select flag in select flag list");
|
||||||
static_assert(::sqlpp::detail::and_t<is_select_flag_t, Flag...>::value, "at least one argument is not a select flag in select flag list");
|
|
||||||
|
|
||||||
template<typename E>
|
select_flag_list_t(Flags... flags):
|
||||||
void add(E expr)
|
_flags(flags...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
select_flag_list_t(const select_flag_list_t&) = default;
|
||||||
|
select_flag_list_t(select_flag_list_t&&) = default;
|
||||||
|
select_flag_list_t& operator=(const select_flag_list_t&) = default;
|
||||||
|
select_flag_list_t& operator=(select_flag_list_t&&) = default;
|
||||||
|
~select_flag_list_t() = default;
|
||||||
|
|
||||||
|
template<typename Flag>
|
||||||
|
void add_flag(Flag flag)
|
||||||
{
|
{
|
||||||
static_assert(is_select_flag_t<E>::value, "flag arguments require to be select flags");
|
static_assert(is_select_flag_t<Flag>::value, "flag arguments require to be select flags");
|
||||||
_dynamic_flags.emplace_back(expr);
|
_dynamic_flags.emplace_back(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select_flag_list_t& _flag_list = *this;
|
||||||
_parameter_tuple_t _flags;
|
_parameter_tuple_t _flags;
|
||||||
vendor::interpretable_list_t<Database> _dynamic_flags;
|
vendor::interpretable_list_t<Database> _dynamic_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Database, typename... Flag>
|
struct no_select_flag_list_t
|
||||||
struct interpreter_t<Context, select_flag_list_t<Database, std::tuple<Flag...>>>
|
{
|
||||||
|
using _is_select_flag_list = std::true_type;
|
||||||
|
no_select_flag_list_t& _flag_list = *this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CRTP Wrappers
|
||||||
|
template<typename Derived, typename Database, typename... Args>
|
||||||
|
struct crtp_wrapper_t<Derived, select_flag_list_t<Database, Args...>>
|
||||||
{
|
{
|
||||||
using T = select_flag_list_t<Database, std::tuple<Flag...>>;
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct crtp_wrapper_t<Derived, no_select_flag_list_t>
|
||||||
|
{
|
||||||
|
template<typename... Args>
|
||||||
|
auto flags(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_select_flag_list_t, select_flag_list_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { static_cast<Derived&>(*this), select_flag_list_t<void, Args...>(args...) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_flags(Args... args)
|
||||||
|
-> vendor::update_policies_t<Derived, no_select_flag_list_t, select_flag_list_t<get_database_t<Derived>, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<get_database_t<Derived>, void>::value, "dynamic_flags must not be called in a static statement");
|
||||||
|
return { static_cast<Derived&>(*this), select_flag_list_t<get_database_t<Derived>, Args...>(args...) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Flags>
|
||||||
|
struct interpreter_t<Context, select_flag_list_t<Database, Flags...>>
|
||||||
|
{
|
||||||
|
using T = select_flag_list_t<Database, Flags...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
interpret_tuple(t._flags, ' ', context);
|
interpret_tuple(t._flags, ' ', context);
|
||||||
if (sizeof...(Flag))
|
if (sizeof...(Flags))
|
||||||
context << ' ';
|
context << ' ';
|
||||||
interpret_list(t._dynamic_flags, ',', context);
|
interpret_list(t._dynamic_flags, ',', context);
|
||||||
if (not t._dynamic_flags.empty())
|
if (not t._dynamic_flags.empty())
|
||||||
@ -86,6 +123,17 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct interpreter_t<Context, no_select_flag_list_t>
|
||||||
|
{
|
||||||
|
using T = no_select_flag_list_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
30
include/sqlpp11/vendor/where.h
vendored
30
include/sqlpp11/vendor/where.h
vendored
@ -27,14 +27,14 @@
|
|||||||
#ifndef SQLPP_WHERE_H
|
#ifndef SQLPP_WHERE_H
|
||||||
#define SQLPP_WHERE_H
|
#define SQLPP_WHERE_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/select_fwd.h>
|
|
||||||
#include <sqlpp11/vendor/expression.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/logic.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/vendor/expression.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
#include <sqlpp11/vendor/interpretable_list.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/vendor/policy_update.h>
|
||||||
|
#include <sqlpp11/vendor/crtp_wrapper.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -76,8 +76,18 @@ namespace sqlpp
|
|||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct where_t<void, bool>
|
||||||
|
{
|
||||||
|
using _is_where = std::true_type;
|
||||||
|
using _is_dynamic = std::false_type;
|
||||||
|
|
||||||
|
std::tuple<bool> _condition;
|
||||||
|
};
|
||||||
|
|
||||||
struct no_where_t
|
struct no_where_t
|
||||||
{
|
{
|
||||||
|
using _is_where = std::true_type;
|
||||||
no_where_t& _where = *this;
|
no_where_t& _where = *this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,16 +135,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
|
||||||
struct where_t<void, bool>
|
|
||||||
{
|
|
||||||
using _is_where = std::true_type;
|
|
||||||
using _is_dynamic = std::false_type;
|
|
||||||
using _parameter_tuple_t = std::tuple<>;
|
|
||||||
|
|
||||||
std::tuple<bool> _condition;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct interpreter_t<Context, where_t<void, bool>>
|
struct interpreter_t<Context, where_t<void, bool>>
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user