Added interpreter to select, select_flag_list, select_expression_list

This commit is contained in:
rbock
2014-01-12 12:22:15 +01:00
parent f8b5d750fa
commit d957e8c0ae
5 changed files with 175 additions and 89 deletions

View File

@@ -33,11 +33,19 @@ namespace sqlpp
{
struct noop
{
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{}
};
template<typename Context>
struct interpreter_t<Context, noop>
{
using T = noop;
static Context& _(const T& t, Context& context)
{
return context;
}
};
template<typename T>
struct is_noop: std::is_same<T, noop> {};

View File

@@ -547,32 +547,6 @@ namespace sqlpp
*this).as(aliasProvider);
}
// Serialize
template<typename Db>
const select_t& serialize(std::ostream& os, Db& db) const
{
os << "SELECT ";
_flags.serialize(os, db);
_expression_list.serialize(os, db);
_from.serialize(os, db);
_where.serialize(os, db);
_group_by.serialize(os, db);
_having.serialize(os, db);
_order_by.serialize(os, db);
_limit.serialize(os, db);
_offset.serialize(os, db);
return *this;
}
template<typename Db>
select_t& serialize(std::ostream& os, Db& db)
{
const_cast<const select_t*>(this)->serialize(os, db);
return *this;
}
const typename ExpressionList::_dynamic_names_t& get_dynamic_names() const
{
return _expression_list._dynamic_expressions._dynamic_expression_names;
@@ -644,6 +618,59 @@ namespace sqlpp
Offset _offset;
};
template<typename Context,
typename Database,
typename Flags,
typename ExpressionList,
typename From,
typename Where,
typename GroupBy,
typename Having,
typename OrderBy,
typename Limit,
typename Offset
>
struct interpreter_t<Context, select_t<Database,
Flags,
ExpressionList,
From,
Where,
GroupBy,
Having,
OrderBy,
Limit,
Offset>>
{
using T = select_t<Database,
Flags,
ExpressionList,
From,
Where,
GroupBy,
Having,
OrderBy,
Limit,
Offset>;
static Context& _(const T& t, Context& context)
{
context << "SELECT ";
interpret(t._flags, context);
interpret(t._expression_list, context);
interpret(t._from, context);
interpret(t._where, context);
interpret(t._group_by, context);
interpret(t._having, context);
interpret(t._order_by, context);
interpret(t._limit, context);
interpret(t._offset, context);
return context;
}
};
// construct select flag list
namespace detail
{

View File

@@ -57,32 +57,27 @@ namespace sqlpp
using _value_type = typename T::_value_type;
using _name_t = typename T::_name_t;
};
}
template<typename Db>
struct dynamic_select_expression_list
{
using _names_t = std::vector<std::string>;
std::vector<detail::named_serializable_t<Db>> _dynamic_expressions;
_names_t _dynamic_expression_names;
template<typename Db>
struct dynamic_select_expression_list
{
using _names_t = std::vector<std::string>;
std::vector<detail::named_serializable_t<Db>> _dynamic_expressions;
_names_t _dynamic_expression_names;
template<typename Expr>
template<typename Expr>
void push_back(Expr&& expr)
{
_dynamic_expression_names.push_back(std::decay<Expr>::type::_name_t::_get_name());
_dynamic_expressions.emplace_back(std::forward<Expr>(expr));
}
void serialize(std::ostream& os, Db& db, bool first) const
{
for (const auto column : _dynamic_expressions)
{
if (not first)
os << ',';
column.serialize(os, db);
first = false;
}
}
};
bool empty() const
{
return _dynamic_expressions.empty();
}
};
template<>
struct dynamic_select_expression_list<void>
@@ -93,14 +88,38 @@ namespace sqlpp
template<typename T>
void push_back(const T&) {}
template<typename Db>
void serialize(std::ostream&, Db&, bool) const
{
}
static constexpr bool empty()
{
return true;
}
};
}
template<typename Context, typename Db>
struct interpreter_t<Context, dynamic_select_expression_list<Db>>
{
using T = dynamic_select_expression_list<Db>;
static Context& _(const T& t, Context& context)
{
for (const auto column : t._dynamic_expressions)
{
interpret(column, context);
}
return context;
}
};
template<typename Context>
struct interpreter_t<Context, dynamic_select_expression_list<void>>
{
using T = dynamic_select_expression_list<void>;
static Context& _(const T& t, Context& context)
{
return context;
}
};
template<typename Database, typename... NamedExpr>
struct select_expression_list_t<Database, std::tuple<NamedExpr...>>
@@ -109,6 +128,9 @@ namespace sqlpp
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...>;
// check for at least one expression
static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
// check for duplicate select expressions
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
@@ -135,7 +157,7 @@ namespace sqlpp
dynamic_result_row_t<make_field_t<NamedExpr>...>,
result_row_t<make_field_t<NamedExpr>...>>::type;
using _dynamic_names_t = typename detail::dynamic_select_expression_list<Database>::_names_t;
using _dynamic_names_t = typename dynamic_select_expression_list<Database>::_names_t;
template <typename Select>
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
@@ -151,24 +173,23 @@ namespace sqlpp
_dynamic_expressions.push_back(std::forward<Expr>(namedExpr));
}
template<typename Db>
void serialize(std::ostream& os, Db& db) const
{
// check for at least one select expression
static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
detail::serialize_tuple(os, db, _expressions, ',');
_dynamic_expressions.serialize(os, db, sizeof...(NamedExpr) == 0);
}
size_t _set_parameter_index(size_t index)
{
index = set_parameter_index(_expressions, index);
return index;
}
_parameter_tuple_t _expressions;
detail::dynamic_select_expression_list<Database> _dynamic_expressions;
dynamic_select_expression_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... NamedExpr>
struct interpreter_t<Context, select_expression_list_t<Database, NamedExpr...>>
{
using T = select_expression_list_t<Database, NamedExpr...>;
static Context& _(const T& t, Context& context)
{
interpret_tuple(t._expressions, ',', context);
if (not t._dynamic_expressions.empty())
context << ',';
interpret(t._dynamic_expressions, context);
return context;
}
};
}

View File

@@ -43,45 +43,57 @@ namespace sqlpp
{
using _is_select_flag = std::true_type;
};
template<typename Db>
void serialize(std::ostream& os, const Db&) const
{
os << "ALL";
}
};
static constexpr all_t all = {};
template<typename Context>
struct interpreter_t<Context, all_t>
{
static Context& _(const all_t&, Context& context)
{
context << "ALL";
return context;
}
};
struct distinct_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
template<typename Db>
void serialize(std::ostream& os, const Db&) const
{
os << "DISTINCT";
}
};
static constexpr distinct_t distinct = {};
template<typename Context>
struct interpreter_t<Context, distinct_t>
{
static Context& _(const distinct_t&, Context& context)
{
context << "DISTINCT";
return context;
}
};
struct straight_join_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
template<typename Db>
void serialize(std::ostream& os, const Db&) const
{
os << "STRAIGHT_JOIN";
}
};
static constexpr straight_join_t straight_join = {};
template<typename Context>
struct interpreter_t<Context, straight_join_t>
{
static Context& _(const straight_join_t&, Context& context)
{
context << "STRAIGHT_JOIN";
return context;
}
};
// select_flag_list_t
template<typename... Flag>
struct select_flag_list_t<std::tuple<Flag...>>
@@ -105,6 +117,21 @@ namespace sqlpp
std::tuple<Flag...> _flags;
};
template<typename Context, typename... Flag>
struct interpreter_t<Context, select_flag_list_t<std::tuple<Flag...>>>
{
using T = select_flag_list_t<std::tuple<Flag...>>;
static Context& _(const T& t, Context& context)
{
interpret_tuple(t._flags, ' ', context);
if (sizeof...(Flag))
context << ' ';
return context;
}
};
}
#endif

View File

@@ -25,6 +25,7 @@
#include "TabSample.h"
#include "MockDb.h"
#include <sqlpp11/select.h>
#include <iostream>
@@ -41,5 +42,7 @@ int main()
sqlpp::text_operand o = {"kaesekuchen"};
interpret(t.beta + "kaesekuchen", printer).flush();
interpret(select(sqlpp::distinct, t.alpha, t.beta), printer).flush();
return 0;
}