From abf4bb8e9a9e074bd4e31999a1aad9c3235a2661 Mon Sep 17 00:00:00 2001 From: rbock Date: Tue, 18 Feb 2014 17:45:08 +0100 Subject: [PATCH] Added serializer to interpreter The serializer has partial specializations for all templates. It is a good basis if the connector/database requires strings close to the standard. The interpreter is unspecialized (and uses a static assert to say so). It is a good basis if the connector/database requires a different interpretation, e.g. re-writing the expression tree. The interpretable_t implements three methods for interpretation: serializing with the sqlpp::serializer_context, serializing with the database's serialization context and interpretation with the database's interpretation context. --- include/sqlpp11/alias.h | 4 +- include/sqlpp11/all_of.h | 2 +- include/sqlpp11/any.h | 4 +- include/sqlpp11/avg.h | 7 +- include/sqlpp11/column.h | 4 +- include/sqlpp11/count.h | 6 +- include/sqlpp11/default_value.h | 2 +- include/sqlpp11/exists.h | 4 +- include/sqlpp11/functions.h | 8 +- include/sqlpp11/insert.h | 6 +- include/sqlpp11/join.h | 8 +- include/sqlpp11/max.h | 5 +- include/sqlpp11/min.h | 5 +- include/sqlpp11/multi_column.h | 4 +- include/sqlpp11/null.h | 2 +- include/sqlpp11/on.h | 2 +- include/sqlpp11/parameter.h | 2 +- include/sqlpp11/remove.h | 8 +- include/sqlpp11/select.h | 22 +-- include/sqlpp11/select_flags.h | 6 +- include/sqlpp11/serialize.h | 43 ++++++ .../{serializer.h => serializer_context.h} | 9 +- include/sqlpp11/some.h | 4 +- include/sqlpp11/sort_order.h | 4 +- include/sqlpp11/sum.h | 7 +- include/sqlpp11/table.h | 2 +- include/sqlpp11/table_alias.h | 4 +- include/sqlpp11/tvin.h | 9 +- include/sqlpp11/update.h | 8 +- include/sqlpp11/vendor/assignment.h | 15 +- include/sqlpp11/vendor/concat.h | 2 +- include/sqlpp11/vendor/expression.h | 30 ++-- include/sqlpp11/vendor/from.h | 4 +- include/sqlpp11/vendor/group_by.h | 4 +- include/sqlpp11/vendor/having.h | 4 +- include/sqlpp11/vendor/in.h | 4 +- include/sqlpp11/vendor/insert_value.h | 6 +- include/sqlpp11/vendor/insert_value_list.h | 10 +- include/sqlpp11/vendor/interpret_tuple.h | 4 +- include/sqlpp11/vendor/interpretable.h | 40 +++-- include/sqlpp11/vendor/interpretable_list.h | 2 +- include/sqlpp11/vendor/is_null.h | 4 +- include/sqlpp11/vendor/like.h | 6 +- include/sqlpp11/vendor/limit.h | 10 +- include/sqlpp11/vendor/named_interpretable.h | 39 +++-- include/sqlpp11/vendor/noop.h | 2 +- include/sqlpp11/vendor/offset.h | 10 +- include/sqlpp11/vendor/order_by.h | 4 +- include/sqlpp11/vendor/select_column_list.h | 12 +- include/sqlpp11/vendor/select_flag_list.h | 4 +- include/sqlpp11/vendor/select_pseudo_table.h | 4 +- include/sqlpp11/vendor/serializer.h | 48 ++++++ include/sqlpp11/vendor/simple_column.h | 4 +- include/sqlpp11/vendor/single_table.h | 4 +- include/sqlpp11/vendor/update_list.h | 4 +- include/sqlpp11/vendor/using.h | 4 +- include/sqlpp11/vendor/where.h | 6 +- include/sqlpp11/vendor/wrap_operand.h | 10 +- include/sqlpp11/verbatim_table.h | 2 +- tests/InsertTest.cpp | 12 +- tests/InterpretTest.cpp | 144 +++++++++--------- tests/MockDb.h | 21 ++- tests/RemoveTest.cpp | 10 +- tests/SelectTest.cpp | 14 +- tests/UpdateTest.cpp | 12 +- 65 files changed, 423 insertions(+), 293 deletions(-) create mode 100644 include/sqlpp11/serialize.h rename include/sqlpp11/{serializer.h => serializer_context.h} (90%) create mode 100644 include/sqlpp11/vendor/serializer.h diff --git a/include/sqlpp11/alias.h b/include/sqlpp11/alias.h index 179b6c50..f9d65fc4 100644 --- a/include/sqlpp11/alias.h +++ b/include/sqlpp11/alias.h @@ -48,14 +48,14 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = expression_alias_t; static Context& _(const T& t, Context& context) { context << '('; - interpret(t._expression, context); + serialize(t._expression, context); context << ") AS "; context << T::_name_t::_get_name(); return context; diff --git a/include/sqlpp11/all_of.h b/include/sqlpp11/all_of.h index fb4f50b3..7376490b 100644 --- a/include/sqlpp11/all_of.h +++ b/include/sqlpp11/all_of.h @@ -54,7 +54,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = all_of_t; diff --git a/include/sqlpp11/any.h b/include/sqlpp11/any.h index a5955455..6bacf054 100644 --- a/include/sqlpp11/any.h +++ b/include/sqlpp11/any.h @@ -76,14 +76,14 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = vendor::any_t; static Context& _(const T& t, Context& context) { context << "EXISTS("; - interpret(t._select, context); + serialize(t._select, context); context << ")"; return context; } diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index 9aabf960..cdd556fa 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -71,7 +71,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = verbatim_t; @@ -94,7 +94,7 @@ namespace sqlpp { static_assert(not make_parameter_list_t::type::size::value, "parameters not supported in flattened expressions"); context.clear(); - interpret(exp, context); + serialize(exp, context); return { context.str() }; } @@ -121,7 +121,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = value_list_t; @@ -135,7 +135,7 @@ namespace sqlpp else context << ','; - interpret(value(entry), context); + serialize(value(entry), context); } return context; } diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index e1ee5593..eb60554a 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -166,15 +166,15 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = insert_t; static Context& _(const T& t, Context& context) { context << "INSERT INTO "; - interpret(t._table, context); - interpret(t._insert_value_list, context); + serialize(t._table, context); + serialize(t._insert_value_list, context); return context; } }; diff --git a/include/sqlpp11/join.h b/include/sqlpp11/join.h index b8cffea7..23816184 100644 --- a/include/sqlpp11/join.h +++ b/include/sqlpp11/join.h @@ -145,18 +145,18 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = join_t; static Context& _(const T& t, Context& context) { static_assert(not vendor::is_noop::value, "joined tables require on()"); - interpret(t._lhs, context); + serialize(t._lhs, context); context << JoinType::_name; context << " JOIN "; - interpret(t._rhs, context); - interpret(t._on, context); + serialize(t._rhs, context); + serialize(t._on, context); return context; } }; diff --git a/include/sqlpp11/max.h b/include/sqlpp11/max.h index 9e36d2b8..241ab544 100644 --- a/include/sqlpp11/max.h +++ b/include/sqlpp11/max.h @@ -27,7 +27,6 @@ #ifndef SQLPP_MAX_H #define SQLPP_MAX_H -#include #include namespace sqlpp @@ -73,14 +72,14 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = vendor::max_t; static Context& _(const T& t, Context& context) { context << "MAX("; - interpret(t._expr, context); + serialize(t._expr, context); context << ")"; return context; } diff --git a/include/sqlpp11/min.h b/include/sqlpp11/min.h index 9e35549c..4fd7d5c8 100644 --- a/include/sqlpp11/min.h +++ b/include/sqlpp11/min.h @@ -27,7 +27,6 @@ #ifndef SQLPP_MIN_H #define SQLPP_MIN_H -#include #include namespace sqlpp @@ -73,14 +72,14 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = vendor::min_t; static Context& _(const T& t, Context& context) { context << "MIN("; - interpret(t._expr, context); + serialize(t._expr, context); context << ")"; return context; } diff --git a/include/sqlpp11/multi_column.h b/include/sqlpp11/multi_column.h index f75169e7..c6260b30 100644 --- a/include/sqlpp11/multi_column.h +++ b/include/sqlpp11/multi_column.h @@ -106,7 +106,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = multi_column_t; @@ -117,7 +117,7 @@ namespace sqlpp }; template - struct interpreter_t> + struct serializer_t> { using T = multi_column_alias_t; diff --git a/include/sqlpp11/null.h b/include/sqlpp11/null.h index 643511a8..af742da1 100644 --- a/include/sqlpp11/null.h +++ b/include/sqlpp11/null.h @@ -43,7 +43,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t + struct serializer_t { using Operand = null_t; diff --git a/include/sqlpp11/on.h b/include/sqlpp11/on.h index 68c1297d..96ade430 100644 --- a/include/sqlpp11/on.h +++ b/include/sqlpp11/on.h @@ -57,7 +57,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = on_t; diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 875e738a..260dc88a 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -54,7 +54,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = parameter_t; diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index 93807f8f..557b0f6d 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -189,16 +189,16 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = remove_t; static Context& _(const T& t, Context& context) { context << "DELETE FROM "; - interpret(t._table, context); - interpret(t._using, context); - interpret(t._where, context); + serialize(t._table, context); + serialize(t._using, context); + serialize(t._where, context); return context; } }; diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index aa5e5983..9ef444cf 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include @@ -540,7 +540,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = select_t; @@ -548,15 +548,15 @@ namespace sqlpp { context << "SELECT "; - interpret(t._flag_list, context); - interpret(t._column_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); + serialize(t._flag_list, context); + serialize(t._column_list, context); + serialize(t._from, context); + serialize(t._where, context); + serialize(t._group_by, context); + serialize(t._having, context); + serialize(t._order_by, context); + serialize(t._limit, context); + serialize(t._offset, context); return context; } diff --git a/include/sqlpp11/select_flags.h b/include/sqlpp11/select_flags.h index f59a6ae4..8335dd75 100644 --- a/include/sqlpp11/select_flags.h +++ b/include/sqlpp11/select_flags.h @@ -47,7 +47,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t + struct serializer_t { static Context& _(const all_t&, Context& context) { @@ -69,7 +69,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t + struct serializer_t { static Context& _(const distinct_t&, Context& context) { @@ -91,7 +91,7 @@ namespace sqlpp namespace vendor { template - struct interpreter_t + struct serializer_t { static Context& _(const straight_join_t&, Context& context) { diff --git a/include/sqlpp11/serialize.h b/include/sqlpp11/serialize.h new file mode 100644 index 00000000..8ff650ef --- /dev/null +++ b/include/sqlpp11/serialize.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_SERIALIZE_H +#define SQLPP_SERIALIZE_H + +#include + +namespace sqlpp +{ + template + auto serialize(const T& t, Context& context) + -> decltype(vendor::serializer_t::_(t, context)) + { + return vendor::serializer_t::_(t, context); + } + +} + +#endif diff --git a/include/sqlpp11/serializer.h b/include/sqlpp11/serializer_context.h similarity index 90% rename from include/sqlpp11/serializer.h rename to include/sqlpp11/serializer_context.h index d8bbaaee..8e3ee35d 100644 --- a/include/sqlpp11/serializer.h +++ b/include/sqlpp11/serializer_context.h @@ -23,16 +23,16 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SQLPP_SERIALIZER_H -#define SQLPP_SERIALIZER_H +#ifndef SQLPP_SERIALIZER_CONTEXT_H +#define SQLPP_SERIALIZER_CONTEXT_H #include namespace sqlpp { - struct serializer_t + struct serializer_context_t { - serializer_t(std::ostream& os): + serializer_context_t(std::ostream& os): _os(os) {} @@ -49,6 +49,7 @@ namespace sqlpp std::string escape(std::string arg) { +// FIXME: Need to do better escaping return arg; } diff --git a/include/sqlpp11/some.h b/include/sqlpp11/some.h index 268ec963..54a1fe5b 100644 --- a/include/sqlpp11/some.h +++ b/include/sqlpp11/some.h @@ -75,14 +75,14 @@ namespace sqlpp namespace vendor { template - struct interpreter_t> + struct serializer_t> { using T = vendor::some_t