From 55324d1f71646fd1c54f4d2629a46b58d87979c7 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Sat, 17 Aug 2024 21:11:52 +0200 Subject: [PATCH] New tuple_to_sql_string --- include/sqlpp11/core/clause/cte.h | 2 +- include/sqlpp11/core/clause/from.h | 2 +- include/sqlpp11/core/clause/group_by.h | 4 +- include/sqlpp11/core/clause/having.h | 2 +- .../sqlpp11/core/clause/insert_value_list.h | 10 +-- include/sqlpp11/core/clause/order_by.h | 4 +- .../sqlpp11/core/clause/select_column_list.h | 4 +- .../sqlpp11/core/clause/select_flag_list.h | 4 +- include/sqlpp11/core/clause/select_flags.h | 2 +- include/sqlpp11/core/clause/union.h | 2 +- include/sqlpp11/core/clause/union_flags.h | 2 +- include/sqlpp11/core/clause/update_list.h | 4 +- include/sqlpp11/core/clause/using.h | 6 +- include/sqlpp11/core/clause/where.h | 2 +- include/sqlpp11/core/clause/with.h | 4 +- .../sqlpp11/core/database/parameter_list.h | 2 +- include/sqlpp11/core/operator/in_expression.h | 5 +- include/sqlpp11/core/query/custom_query.h | 4 +- ...nterpret_tuple.h => tuple_to_sql_string.h} | 87 ++++++++++++------- include/sqlpp11/mysql/serializer.h | 12 +-- .../postgresql/on_conflict_do_update.h | 12 +-- .../postgresql/returning_column_list.h | 9 +- 22 files changed, 99 insertions(+), 86 deletions(-) rename include/sqlpp11/core/{interpret_tuple.h => tuple_to_sql_string.h} (52%) diff --git a/include/sqlpp11/core/clause/cte.h b/include/sqlpp11/core/clause/cte.h index 88a7c09e..ab6fecef 100644 --- a/include/sqlpp11/core/clause/cte.h +++ b/include/sqlpp11/core/clause/cte.h @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include #include diff --git a/include/sqlpp11/core/clause/from.h b/include/sqlpp11/core/clause/from.h index 5bdf2490..d4732362 100644 --- a/include/sqlpp11/core/clause/from.h +++ b/include/sqlpp11/core/clause/from.h @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include #include diff --git a/include/sqlpp11/core/clause/group_by.h b/include/sqlpp11/core/clause/group_by.h index 687a3798..691b2b26 100644 --- a/include/sqlpp11/core/clause/group_by.h +++ b/include/sqlpp11/core/clause/group_by.h @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include #include @@ -153,7 +153,7 @@ namespace sqlpp template auto to_sql_string(Context& context, const group_by_data_t& t) -> std::string { - return " GROUP BY " + interpret_tuple(t._columns, ',', context); + return " GROUP BY " + tuple_to_sql_string(context, t._columns, tuple_operand{", "}); } template diff --git a/include/sqlpp11/core/clause/having.h b/include/sqlpp11/core/clause/having.h index f455a292..214799c4 100644 --- a/include/sqlpp11/core/clause/having.h +++ b/include/sqlpp11/core/clause/having.h @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include #include diff --git a/include/sqlpp11/core/clause/insert_value_list.h b/include/sqlpp11/core/clause/insert_value_list.h index ff2e4ed0..90831ec2 100644 --- a/include/sqlpp11/core/clause/insert_value_list.h +++ b/include/sqlpp11/core/clause/insert_value_list.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -405,7 +405,7 @@ namespace sqlpp auto to_sql_string(Context& context, const column_list_data_t& t) -> std::string { auto result = std::string{" ("}; - result += interpret_tuple(t._columns, ",", context); + result += tuple_to_sql_string(context, t._columns, ","); result += ")"; bool first = true; for (const auto& row : t._insert_values) @@ -420,7 +420,7 @@ namespace sqlpp result += ','; } result += '('; - result += interpret_tuple(row, ",", context); + result += tuple_to_sql_string(context, row, ","); result += ')'; } @@ -431,9 +431,9 @@ namespace sqlpp auto to_sql_string(Context& context, const insert_list_data_t& t) -> std::string { auto result = std::string{" ("}; - result += interpret_tuple(t._columns, ",", context); + result += tuple_to_sql_string(context, t._columns, tuple_operand{", "}); result += ") VALUES("; - result += interpret_tuple(t._values, ",", context); + result += tuple_to_sql_string(context, t._values, tuple_operand{", "}); result += ")"; return result; } diff --git a/include/sqlpp11/core/clause/order_by.h b/include/sqlpp11/core/clause/order_by.h index 10a4e066..a62e5107 100644 --- a/include/sqlpp11/core/clause/order_by.h +++ b/include/sqlpp11/core/clause/order_by.h @@ -27,7 +27,7 @@ */ #include -#include +#include #include #include #include @@ -148,7 +148,7 @@ namespace sqlpp template auto to_sql_string(Context& context, const order_by_data_t& t) -> std::string { - return " ORDER BY " + interpret_tuple(t._expressions, ',', context); + return " ORDER BY " + tuple_to_sql_string(context, t._expressions, tuple_operand{", "}); } template diff --git a/include/sqlpp11/core/clause/select_column_list.h b/include/sqlpp11/core/clause/select_column_list.h index 5ba0aff1..4c2d78a8 100644 --- a/include/sqlpp11/core/clause/select_column_list.h +++ b/include/sqlpp11/core/clause/select_column_list.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -330,7 +330,7 @@ namespace sqlpp template auto to_sql_string(Context& context, const std::tuple& t) -> std::string { - return interpret_tuple(t, ",", context); + return tuple_to_sql_string(context, t, tuple_operand{", "}); } template diff --git a/include/sqlpp11/core/clause/select_flag_list.h b/include/sqlpp11/core/clause/select_flag_list.h index ab232d5d..42e76052 100644 --- a/include/sqlpp11/core/clause/select_flag_list.h +++ b/include/sqlpp11/core/clause/select_flag_list.h @@ -27,7 +27,7 @@ */ #include -#include +#include #include #include #include @@ -137,7 +137,7 @@ namespace sqlpp template auto to_sql_string(Context& context, const select_flag_list_data_t& t) -> std::string { - return interpret_tuple(t._flags, "", context); + return tuple_to_sql_string(context, t._flags, tuple_operand{" "}); } template diff --git a/include/sqlpp11/core/clause/select_flags.h b/include/sqlpp11/core/clause/select_flags.h index eaa18143..a446dc3a 100644 --- a/include/sqlpp11/core/clause/select_flags.h +++ b/include/sqlpp11/core/clause/select_flags.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include namespace sqlpp diff --git a/include/sqlpp11/core/clause/union.h b/include/sqlpp11/core/clause/union.h index 5441497a..c8572554 100644 --- a/include/sqlpp11/core/clause/union.h +++ b/include/sqlpp11/core/clause/union.h @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include #include diff --git a/include/sqlpp11/core/clause/union_flags.h b/include/sqlpp11/core/clause/union_flags.h index 07846425..ac334d92 100644 --- a/include/sqlpp11/core/clause/union_flags.h +++ b/include/sqlpp11/core/clause/union_flags.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include namespace sqlpp diff --git a/include/sqlpp11/core/clause/update_list.h b/include/sqlpp11/core/clause/update_list.h index a53903c6..c8eb3a92 100644 --- a/include/sqlpp11/core/clause/update_list.h +++ b/include/sqlpp11/core/clause/update_list.h @@ -27,7 +27,7 @@ */ #include -#include +#include #include namespace sqlpp @@ -167,6 +167,6 @@ namespace sqlpp template auto to_sql_string(Context& context, const update_list_data_t& t) -> std::string { - return " SET " + interpret_tuple(t._assignments, ",", context); + return " SET " + tuple_to_sql_string(context, t._assignments, tuple_operand{", "}); } } // namespace sqlpp diff --git a/include/sqlpp11/core/clause/using.h b/include/sqlpp11/core/clause/using.h index 96b55a16..6e23eec3 100644 --- a/include/sqlpp11/core/clause/using.h +++ b/include/sqlpp11/core/clause/using.h @@ -27,7 +27,7 @@ */ #include -#include +#include #include #include @@ -138,8 +138,6 @@ namespace sqlpp template auto to_sql_string(Context& context, const using_data_t& t) -> std::string { - context << " USING "; - interpret_tuple(t._tables, ',', context); - return context; + return " USING " + tuple_to_sql_string(context, t._tables, tuple_operand{", "}); } } // namespace sqlpp diff --git a/include/sqlpp11/core/clause/where.h b/include/sqlpp11/core/clause/where.h index a37dcdaf..e4715d69 100644 --- a/include/sqlpp11/core/clause/where.h +++ b/include/sqlpp11/core/clause/where.h @@ -26,7 +26,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include #include diff --git a/include/sqlpp11/core/clause/with.h b/include/sqlpp11/core/clause/with.h index 8cb161c7..a5c03c07 100644 --- a/include/sqlpp11/core/clause/with.h +++ b/include/sqlpp11/core/clause/with.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -132,7 +132,7 @@ namespace sqlpp { context << "RECURSIVE "; } - interpret_tuple(t._expressions, ',', context); + tuple_to_sql_string(context, t._expressions, tuple_operand{", "}); context << ' '; return context; } diff --git a/include/sqlpp11/core/database/parameter_list.h b/include/sqlpp11/core/database/parameter_list.h index 51bead7e..fbfd16b1 100644 --- a/include/sqlpp11/core/database/parameter_list.h +++ b/include/sqlpp11/core/database/parameter_list.h @@ -59,7 +59,7 @@ namespace sqlpp template void _bind_impl(Target& target, const ::sqlpp::index_sequence& /*unused*/) const { - using swallow = int[]; // see core/interpret_tuple.h + using swallow = int[]; // see coretuple_to_sql_string.h (void)swallow{0, (std::tuple_element::type::operator()()._bind(target, Is), 0)...}; } }; diff --git a/include/sqlpp11/core/operator/in_expression.h b/include/sqlpp11/core/operator/in_expression.h index 47006911..9de5aba2 100644 --- a/include/sqlpp11/core/operator/in_expression.h +++ b/include/sqlpp11/core/operator/in_expression.h @@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include +#include namespace sqlpp { @@ -127,8 +127,7 @@ namespace sqlpp } else { -#warning: interpret_tuple arguments should take Context first, too - result += interpret_tuple(t._r, ", ", context); + result += tuple_to_sql_string(context, t._r, tuple_operand{", "}); } result += ")"; return result; diff --git a/include/sqlpp11/core/query/custom_query.h b/include/sqlpp11/core/query/custom_query.h index a26d8cf7..d336746a 100644 --- a/include/sqlpp11/core/query/custom_query.h +++ b/include/sqlpp11/core/query/custom_query.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include namespace sqlpp @@ -125,7 +125,7 @@ namespace sqlpp template auto to_sql_string(Context& context, const custom_query_t& t) -> std::string { - return interpret_tuple_without_braces(t._parts, " ", context); + return tuple_to_sql_string(context, t._parts, tuple_clause{" "}); } template diff --git a/include/sqlpp11/core/interpret_tuple.h b/include/sqlpp11/core/tuple_to_sql_string.h similarity index 52% rename from include/sqlpp11/core/interpret_tuple.h rename to include/sqlpp11/core/tuple_to_sql_string.h index 84ffe8be..41e3902a 100644 --- a/include/sqlpp11/core/interpret_tuple.h +++ b/include/sqlpp11/core/tuple_to_sql_string.h @@ -1,7 +1,7 @@ #pragma once /* - * Copyright (c) 2013-2015, Roland Bock + * Copyright (c) 2024, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -33,53 +33,80 @@ namespace sqlpp { - template - static auto interpret_tuple_element( - const Element& element, const Separator& separator, Context& context, const UseBraces& /*unused*/, size_t index) -> std::string + struct tuple_operand { - const auto prefix = index ? std::string{separator} : std::string{}; - if (UseBraces::value) + template + auto operator()(Context& context, const T& t, size_t index) const -> std::string { - return prefix + operand_to_sql_string(context, element); + const auto prefix = index ? std::string{separator} : std::string{}; + return prefix + operand_to_sql_string(context, t); } - else - { - return prefix + to_sql_string(context, element); - } - } - template - auto interpret_tuple_impl(const Tuple& t, - const Separator& separator, - Context& context, - const UseBraces& useBraces, - const ::sqlpp::index_sequence & - /*unused*/) -> std::string + sqlpp::string_view separator; + }; + +#warning: to be used by group_by and update + struct tuple_operand_no_dynamic + { + template + auto operator()(Context& context, const T& t, size_t ) const -> std::string + { + const auto prefix = need_prefix ? std::string{separator} : std::string{}; + need_prefix = true; + return prefix + operand_to_sql_string(context, t); + } + + template + auto operator()(Context& context, const sqlpp::dynamic_t& t, size_t index) const -> std::string + { + if (t._condition) + { + return operator()(context, t._expr, index); + } + return ""; + } + + sqlpp::string_view separator; + bool need_prefix = false; + }; + + struct tuple_clause + { + template + auto operator()(Context& context, const T& t, size_t index) const -> std::string + { + const auto prefix = index ? std::string{separator} : std::string{}; + return prefix + to_sql_string(context, t); + } + + sqlpp::string_view separator; + }; + + template + auto tuple_to_sql_string_impl(Context& context, + const Tuple& t, + const Strategy& strategy, + const ::sqlpp::index_sequence& + /*unused*/) -> std::string { // Note: A braced-init-list does guarantee the order of evaluation according to 12.6.1 [class.explicit.init] // paragraph 2 and 8.5.4 [dcl.init.list] paragraph 4. // See for example: "http://en.cppreference.com/w/cpp/utility/integer_sequence" // See also: "http://stackoverflow.com/questions/6245735/pretty-print-stdtuple/6245777#6245777" // Beware of gcc-bug: "http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51253", otherwise an empty swallow struct could - // be used + // be used. auto result = std::string{}; using swallow = int[]; (void)swallow{0, // workaround against -Wpedantic GCC warning "zero-size array 'int [0]'" - (result += interpret_tuple_element(std::get(t), separator, context, useBraces, Is), 0)...}; + (result += strategy(context, std::get(t), Is), 0)...}; return result; } - template - auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context) -> std::string + template + auto tuple_to_sql_string(Context& context, const Tuple& t, const Strategy& strategy) -> std::string { - return interpret_tuple_impl(t, separator, context, std::true_type{}, + return tuple_to_sql_string_impl(context, t, strategy, ::sqlpp::make_index_sequence::value>{}); } - template - auto interpret_tuple_without_braces(const Tuple& t, const Separator& separator, Context& context) -> std::string - { - return interpret_tuple_impl(t, separator, context, std::false_type{}, - ::sqlpp::make_index_sequence::value>{}); - } } // namespace sqlpp diff --git a/include/sqlpp11/mysql/serializer.h b/include/sqlpp11/mysql/serializer.h index 43494c04..83ad42ee 100644 --- a/include/sqlpp11/mysql/serializer.h +++ b/include/sqlpp11/mysql/serializer.h @@ -32,17 +32,13 @@ namespace sqlpp { template - mysql::context_t& to_sql_string(const concat_t& t, mysql::context_t& ctx) + auto to_sql_string(mysql::context_t& ctx, const concat_t& t, mysql::context_t& ctx) -> std::string { - ctx << "CONCAT("; - interpret_tuple(t._args, ',', ctx); - ctx << ')'; - return ctx; + return "CONCAT(" + tuple_to_sql_string(context, t._args, tuple_operand(", ")) + ")"; } - inline mysql::context_t& to_sql_string(const insert_default_values_data_t&, mysql::context_t& ctx) + inline auto to_sql_string(mysql::context_t&, const insert_default_values_data_t&) -> std::string { - ctx << " () VALUES()"; - return ctx; + return " () VALUES()"; } } diff --git a/include/sqlpp11/postgresql/on_conflict_do_update.h b/include/sqlpp11/postgresql/on_conflict_do_update.h index 813235ed..ef287f2e 100644 --- a/include/sqlpp11/postgresql/on_conflict_do_update.h +++ b/include/sqlpp11/postgresql/on_conflict_do_update.h @@ -28,7 +28,7 @@ */ #include -#include +#include #include #include @@ -139,14 +139,10 @@ namespace sqlpp }; template - postgresql::context_t& to_sql_string( - const postgresql::on_conflict_do_update_data_t& o, - postgresql::context_t& context) + auto to_sql_string(postgresql::context_t& context, + const postgresql::on_conflict_do_update_data_t& o) -> std::string { - to_sql_string(context, o._conflict_target); - context << "DO UPDATE SET "; - interpret_tuple(o._assignments, ",", context); - return context; + return to_sql_string(context, o._conflict_target) + "DO UPDATE SET " + tuple_to_sql_string(context, o._assignments, tuple_operand{", "}); } template diff --git a/include/sqlpp11/postgresql/returning_column_list.h b/include/sqlpp11/postgresql/returning_column_list.h index 7cd28bc7..ad2ff468 100644 --- a/include/sqlpp11/postgresql/returning_column_list.h +++ b/include/sqlpp11/postgresql/returning_column_list.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include @@ -293,12 +293,9 @@ namespace sqlpp // Serialization template - postgresql::context_t& to_sql_string(const postgresql::returning_column_list_data_t& t, - postgresql::context_t& context) + auto to_sql_string(postgresql::context_t& context, const postgresql::returning_column_list_data_t& t) -> std::string { - context << " RETURNING "; - interpret_tuple(t._columns, ',', context); - return context; + return " RETURNING " + tuple_to_sql_string(context, t._columns, tuple_operand{", "}); } } } // namespace sqlpp