From d957e8c0aedf33ac96a9802bfe95e0fd02100ea4 Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 12 Jan 2014 12:22:15 +0100 Subject: [PATCH] Added interpreter to select, select_flag_list, select_expression_list --- include/sqlpp11/noop.h | 14 ++- include/sqlpp11/select.h | 79 +++++++++++------ include/sqlpp11/select_expression_list.h | 105 ++++++++++++++--------- include/sqlpp11/select_flag_list.h | 63 ++++++++++---- tests/InterpretTest.cpp | 3 + 5 files changed, 175 insertions(+), 89 deletions(-) diff --git a/include/sqlpp11/noop.h b/include/sqlpp11/noop.h index d63bb31a..09124887 100644 --- a/include/sqlpp11/noop.h +++ b/include/sqlpp11/noop.h @@ -33,11 +33,19 @@ namespace sqlpp { struct noop { - template - void serialize(std::ostream& os, Db& db) const - {} }; + template + struct interpreter_t + { + using T = noop; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + template struct is_noop: std::is_same {}; diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 0616f7d3..99d4710c 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -547,32 +547,6 @@ namespace sqlpp *this).as(aliasProvider); } - // Serialize - template - 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 - select_t& serialize(std::ostream& os, Db& db) - { - const_cast(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 + struct interpreter_t> + { + using T = select_t; + + 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 { diff --git a/include/sqlpp11/select_expression_list.h b/include/sqlpp11/select_expression_list.h index cb1b25c3..30b0b381 100644 --- a/include/sqlpp11/select_expression_list.h +++ b/include/sqlpp11/select_expression_list.h @@ -57,32 +57,27 @@ namespace sqlpp using _value_type = typename T::_value_type; using _name_t = typename T::_name_t; }; + } - template - struct dynamic_select_expression_list - { - using _names_t = std::vector; - std::vector> _dynamic_expressions; - _names_t _dynamic_expression_names; + template + struct dynamic_select_expression_list + { + using _names_t = std::vector; + std::vector> _dynamic_expressions; + _names_t _dynamic_expression_names; - template + template void push_back(Expr&& expr) { _dynamic_expression_names.push_back(std::decay::type::_name_t::_get_name()); _dynamic_expressions.emplace_back(std::forward(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 @@ -93,14 +88,38 @@ namespace sqlpp template void push_back(const T&) {} - template - void serialize(std::ostream&, Db&, bool) const - { - } - + static constexpr bool empty() + { + return true; + } }; - } + template + struct interpreter_t> + { + using T = dynamic_select_expression_list; + + static Context& _(const T& t, Context& context) + { + for (const auto column : t._dynamic_expressions) + { + interpret(column, context); + } + return context; + } + }; + + template + struct interpreter_t> + { + using T = dynamic_select_expression_list; + + static Context& _(const T& t, Context& context) + { + return context; + } + }; + template struct select_expression_list_t> @@ -109,6 +128,9 @@ namespace sqlpp using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; using _parameter_tuple_t = std::tuple; + // 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::value, "at least one duplicate argument detected"); @@ -135,7 +157,7 @@ namespace sqlpp dynamic_result_row_t...>, result_row_t...>>::type; - using _dynamic_names_t = typename detail::dynamic_select_expression_list::_names_t; + using _dynamic_names_t = typename dynamic_select_expression_list::_names_t; template using _pseudo_table_t = select_pseudo_table_t; @@ -151,24 +173,23 @@ namespace sqlpp _dynamic_expressions.push_back(std::forward(namedExpr)); } - template - 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 _dynamic_expressions; + dynamic_select_expression_list _dynamic_expressions; + }; + + template + struct interpreter_t> + { + using T = select_expression_list_t; + + 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; + } }; } diff --git a/include/sqlpp11/select_flag_list.h b/include/sqlpp11/select_flag_list.h index 989f2d7a..44b10fa1 100644 --- a/include/sqlpp11/select_flag_list.h +++ b/include/sqlpp11/select_flag_list.h @@ -43,45 +43,57 @@ namespace sqlpp { using _is_select_flag = std::true_type; }; - - template - void serialize(std::ostream& os, const Db&) const - { - os << "ALL"; - } }; static constexpr all_t all = {}; + template + struct interpreter_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 - void serialize(std::ostream& os, const Db&) const - { - os << "DISTINCT"; - } }; static constexpr distinct_t distinct = {}; + template + struct interpreter_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 - void serialize(std::ostream& os, const Db&) const - { - os << "STRAIGHT_JOIN"; - } }; static constexpr straight_join_t straight_join = {}; + template + struct interpreter_t + { + static Context& _(const straight_join_t&, Context& context) + { + context << "STRAIGHT_JOIN"; + return context; + } + }; + // select_flag_list_t template struct select_flag_list_t> @@ -105,6 +117,21 @@ namespace sqlpp std::tuple _flags; }; + template + struct interpreter_t>> + { + using T = select_flag_list_t>; + + static Context& _(const T& t, Context& context) + { + interpret_tuple(t._flags, ' ', context); + if (sizeof...(Flag)) + context << ' '; + return context; + } + }; + + } #endif diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 6c48d56b..229b4933 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -25,6 +25,7 @@ #include "TabSample.h" #include "MockDb.h" +#include #include @@ -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; }