mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Added dynamic versions of from and where to select
This commit is contained in:
parent
5576df1775
commit
472833016f
@ -51,6 +51,13 @@ namespace sqlpp
|
|||||||
|
|
||||||
using _name_t = typename ColumnSpec::_name_t;
|
using _name_t = typename ColumnSpec::_name_t;
|
||||||
|
|
||||||
|
column_t() = default;
|
||||||
|
column_t(const column_t&) = default;
|
||||||
|
column_t(column_t&&) = default;
|
||||||
|
column_t& operator=(const column_t&) = default;
|
||||||
|
column_t& operator=(column_t&&) = default;
|
||||||
|
~column_t() = default;
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
|
@ -57,11 +57,11 @@ namespace sqlpp
|
|||||||
std::tuple<TableOrJoin...> _tables;
|
std::tuple<TableOrJoin...> _tables;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Db, typename... TableOrJoin>
|
template<typename Db>
|
||||||
struct dynamic_from_t
|
struct dynamic_from_t
|
||||||
{
|
{
|
||||||
using _is_from = tag_yes;
|
using _is_from = tag_yes;
|
||||||
using _is_dynamic_from = tag_yes;
|
using _is_dynamic = tag_yes;
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
void add(Table&& table)
|
void add(Table&& table)
|
||||||
@ -69,13 +69,12 @@ namespace sqlpp
|
|||||||
_dynamic_tables.push_back(std::forward<Table>(table));
|
_dynamic_tables.push_back(std::forward<Table>(table));
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::ostream& os, Db& db, bool has_static_from) const
|
void serialize(std::ostream& os, Db& db) const
|
||||||
{
|
{
|
||||||
if (sizeof...(TableOrJoin) == 0 and _dynamic_tables.empty())
|
if (_dynamic_tables.empty())
|
||||||
return;
|
return;
|
||||||
os << " FROM ";
|
os << " FROM ";
|
||||||
detail::serialize_tuple(os, db, _tables, ',');
|
bool first = true;
|
||||||
bool first = sizeof...(TableOrJoin) == 0;
|
|
||||||
for (const auto& table : _dynamic_tables)
|
for (const auto& table : _dynamic_tables)
|
||||||
{
|
{
|
||||||
if (not first)
|
if (not first)
|
||||||
@ -85,7 +84,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<TableOrJoin...> _tables;
|
|
||||||
std::vector<detail::serializable_t<Db>> _dynamic_tables;
|
std::vector<detail::serializable_t<Db>> _dynamic_tables;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -93,10 +93,10 @@ namespace sqlpp
|
|||||||
using _is_select = tag_yes;
|
using _is_select = tag_yes;
|
||||||
using _requires_braces = tag_yes;
|
using _requires_braces = tag_yes;
|
||||||
|
|
||||||
template<typename... Table>
|
template<typename FromT>
|
||||||
using set_from_t = select_t<Database, Flags, ExpressionList, from_t<typename std::decay<Table>::type...>, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
using set_from_t = select_t<Database, Flags, ExpressionList, FromT, Where, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||||
template<typename Expr>
|
template<typename WhereT>
|
||||||
using set_where_t = select_t<Database, Flags, ExpressionList, From, where_t<typename std::decay<Expr>::type>, GroupBy, Having, OrderBy, Limit, Offset>;
|
using set_where_t = select_t<Database, Flags, ExpressionList, From, WhereT, GroupBy, Having, OrderBy, Limit, Offset>;
|
||||||
template<typename... Col>
|
template<typename... Col>
|
||||||
using set_group_by_t = select_t<Database, Flags, ExpressionList, From, Where, group_by_t<typename std::decay<Col>::type...>, Having, OrderBy, Limit, Offset>;
|
using set_group_by_t = select_t<Database, Flags, ExpressionList, From, Where, group_by_t<typename std::decay<Col>::type...>, Having, OrderBy, Limit, Offset>;
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
@ -165,7 +165,8 @@ namespace sqlpp
|
|||||||
|
|
||||||
// sqlpp functions
|
// sqlpp functions
|
||||||
template<typename... Table>
|
template<typename... Table>
|
||||||
set_from_t<Table...> from(Table&&... table)
|
auto from(Table&&... table)
|
||||||
|
-> set_from_t<from_t<typename std::decay<Table>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||||
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
||||||
@ -182,24 +183,40 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
auto dynamic_from()
|
||||||
|
-> set_from_t<dynamic_from_t<Database>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
||||||
|
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||||
|
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
||||||
|
return {
|
||||||
|
_flags,
|
||||||
|
_expression_list,
|
||||||
|
{{}},
|
||||||
|
_where,
|
||||||
|
_group_by,
|
||||||
|
_having,
|
||||||
|
_order_by,
|
||||||
|
_limit,
|
||||||
|
_offset
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
select_t& add_from(Table&& table)
|
void add_from(Table&& table)
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
|
static_assert(not is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
|
||||||
static_assert(not std::is_same<Database, void>::value, "cannot call add_from() in a non-dynamic select");
|
static_assert(is_dynamic_t<From>::value, "cannot call add_from() in a non-dynamic from");
|
||||||
|
|
||||||
_dynamic._from.add(std::forward<Table>(table));
|
_from.add(std::forward<Table>(table));
|
||||||
|
}
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
set_where_t<Expr> where(Expr&& expr)
|
auto where(Expr&& expr)
|
||||||
|
-> set_where_t<where_t<typename std::decay<Expr>::type>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call where() without a from()");
|
static_assert(not is_noop<From>::value, "cannot call where() without a from()");
|
||||||
static_assert(is_noop<Where>::value, "cannot call where() twice for a single select");
|
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -213,6 +230,33 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto dynamic_where()
|
||||||
|
-> set_where_t<dynamic_where_t<Database>>
|
||||||
|
{
|
||||||
|
static_assert(not is_noop<From>::value, "cannot call dynamic_where() without a from()");
|
||||||
|
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||||
|
return {
|
||||||
|
_flags,
|
||||||
|
_expression_list,
|
||||||
|
_from,
|
||||||
|
{{}},
|
||||||
|
_group_by,
|
||||||
|
_having,
|
||||||
|
_order_by,
|
||||||
|
_limit,
|
||||||
|
_offset,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expr>
|
||||||
|
void add_where(Expr&& expr)
|
||||||
|
{
|
||||||
|
static_assert(not is_noop<From>::value, "cannot call add_from() without having selected anything");
|
||||||
|
static_assert(is_dynamic_t<Where>::value, "cannot call add_where() in a non-dynamic where");
|
||||||
|
|
||||||
|
_where.add(std::forward<Expr>(expr));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename... Col>
|
template<typename... Col>
|
||||||
set_group_by_t<Col...> group_by(Col&&... column)
|
set_group_by_t<Col...> group_by(Col&&... column)
|
||||||
{
|
{
|
||||||
@ -391,7 +435,6 @@ namespace sqlpp
|
|||||||
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
template<typename Db, typename... NamedExpr>
|
template<typename Db, typename... NamedExpr>
|
||||||
select_t<typename std::decay<Db>::type, detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>> dynamic_select(const Db& db, NamedExpr&&... namedExpr)
|
select_t<typename std::decay<Db>::type, detail::make_select_flag_list_t<NamedExpr...>, detail::make_select_expression_list_t<NamedExpr...>> dynamic_select(const Db& db, NamedExpr&&... namedExpr)
|
||||||
{
|
{
|
||||||
@ -400,6 +443,5 @@ namespace sqlpp
|
|||||||
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,6 +95,7 @@ namespace sqlpp
|
|||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_from);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_from);
|
||||||
|
SQLPP_TYPE_TRAIT_GENERATOR(is_dynamic);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_where);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_where);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_group_by);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_group_by);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_having);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_having);
|
||||||
|
@ -27,10 +27,13 @@
|
|||||||
#ifndef SQLPP_WHERE_H
|
#ifndef SQLPP_WHERE_H
|
||||||
#define SQLPP_WHERE_H
|
#define SQLPP_WHERE_H
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
#include <sqlpp11/select_fwd.h>
|
#include <sqlpp11/select_fwd.h>
|
||||||
#include <sqlpp11/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
#include <sqlpp11/detail/serializable.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -51,6 +54,39 @@ namespace sqlpp
|
|||||||
Expr _expr;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
struct dynamic_where_t
|
||||||
|
{
|
||||||
|
|
||||||
|
using _is_where = tag_yes;
|
||||||
|
using _is_dynamic = tag_yes;
|
||||||
|
|
||||||
|
template<typename Expr>
|
||||||
|
void add(Expr&& expr)
|
||||||
|
{
|
||||||
|
static_assert(is_expression_t<Expr>::value, "invalid expression argument in where()");
|
||||||
|
_conditions.push_back(std::forward<Expr>(expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize(std::ostream& os, Db& db) const
|
||||||
|
{
|
||||||
|
if (_conditions.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
os << " WHERE ";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto& condition : _conditions)
|
||||||
|
{
|
||||||
|
if (not first)
|
||||||
|
os << " AND ";
|
||||||
|
condition.serialize(os, db);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<detail::serializable_t<Db>> _conditions;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -262,16 +262,14 @@ int main()
|
|||||||
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
|
static_assert(std::is_same<A, B>::value, "select with identical columns(name/value_type) need to have identical result_types");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
{
|
{
|
||||||
auto s = dynamic_select(db, t);
|
auto s = dynamic_select(db, t).dynamic_from().dynamic_where();
|
||||||
s = s.add_from(t);
|
s.add_from(t);
|
||||||
s = s.add_from(t); // This will not be accepted by the SQL server, but it is dynamic and this kind of test is not possible at compile time, I guess
|
s.add_where(t.alpha > 7);
|
||||||
std::cerr << "------------------------\n";
|
std::cerr << "------------------------\n";
|
||||||
s.serialize(std::cerr, db);
|
s.serialize(std::cerr, db);
|
||||||
std::cerr << "------------------------\n";
|
std::cerr << "------------------------\n";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
||||||
|
Loading…
Reference in New Issue
Block a user