diff --git a/example/batch_inserts.cpp b/example/batch_inserts.cpp index 53d510ff3..646529695 100644 --- a/example/batch_inserts.cpp +++ b/example/batch_inserts.cpp @@ -123,7 +123,7 @@ static std::string compose_batch_insert( // Formatting can fail (e.g. if you supply strings with invalid UTF-8), // so get() returns a boost::system::result. // Calling value() will retrieve the string or throw an exception on failure. - return ctx.get().value(); + return std::move(ctx).get().value(); } void main_impl(int argc, char** argv) diff --git a/example/dynamic_filters.cpp b/example/dynamic_filters.cpp index 2490f48db..b2085ac8c 100644 --- a/example/dynamic_filters.cpp +++ b/example/dynamic_filters.cpp @@ -163,7 +163,7 @@ std::string compose_get_employees_query(const boost::mysql::any_connection& conn ctx.append_value(boost::mysql::identifier(*filts.order_by)); } - return ctx.get().value(); + return std::move(ctx).get().value(); } void main_impl(int argc, char** argv) diff --git a/example/snippets.cpp b/example/snippets.cpp index 229993897..94b697f42 100644 --- a/example/snippets.cpp +++ b/example/snippets.cpp @@ -1579,7 +1579,7 @@ std::string compose_update_query( ctx.append_value(employee_id); // Retrieve the generated query string - return ctx.get().value(); + return std::move(ctx).get().value(); } //] #endif @@ -1842,7 +1842,7 @@ void section_sql_formatting(string_view server_hostname, string_view username, s boost::mysql::basic_format_context ctx(conn.format_opts().value()); // Compose your query as usual - std::pmr::string query = ctx.get().value(); + std::pmr::string query = std::move(ctx).get().value(); //] } #endif diff --git a/include/boost/mysql/format_sql.hpp b/include/boost/mysql/format_sql.hpp index 0c45d863e..31f3ce890 100644 --- a/include/boost/mysql/format_sql.hpp +++ b/include/boost/mysql/format_sql.hpp @@ -250,7 +250,15 @@ class format_context_base error_code error_state() const noexcept { return impl_.ec; } }; -/// (EXPERIMENTAL) Implements stream-like SQL formatting (TODO). +/** + * \brief (EXPERIMENTAL) Implements stream-like SQL formatting. + * - Concrete classes for SQL stream formatting + * - Owns an OutputString, to which characters will be appended when formatting. + * Should satisfy the OutputString concept. + * - See format_context for the most common type alias. + * - Move only + * - Create, append, then call get. + */ template class basic_format_context : public format_context_base { @@ -288,8 +296,7 @@ class basic_format_context : public format_context_base assign(rhs); } - // TODO: do we make this move-only? - system::result get() + system::result get() && { auto ec = error_state(); if (ec) @@ -334,7 +341,7 @@ std::string format_sql(constant_string_view format_str, const format_options& op { format_context ctx(opts); format_sql_to(format_str, ctx, args...); - return detail::check_format_result(ctx.get()); + return detail::check_format_result(std::move(ctx).get()); } } // namespace mysql diff --git a/include/boost/mysql/impl/internal/sansio/set_character_set.hpp b/include/boost/mysql/impl/internal/sansio/set_character_set.hpp index ff2fa0379..b5c6bccf8 100644 --- a/include/boost/mysql/impl/internal/sansio/set_character_set.hpp +++ b/include/boost/mysql/impl/internal/sansio/set_character_set.hpp @@ -42,7 +42,7 @@ class set_character_set_algo : public sansio_algorithm, asio::coroutine // For security, if the character set has non-ascii characters in it name, reject it. format_context ctx(format_options{ascii_charset, true}); ctx.append_raw("SET NAMES ").append_value(charset.name); - return ctx.get(); + return std::move(ctx).get(); } public: diff --git a/test/unit/test/format_sql.cpp b/test/unit/test/format_sql.cpp index 25b95c281..47b174a4c 100644 --- a/test/unit/test/format_sql.cpp +++ b/test/unit/test/format_sql.cpp @@ -499,7 +499,7 @@ error_code format_single_error(const Arg& arg) { format_context ctx(opts); ctx.append_value(arg); - return ctx.get().error(); + return std::move(ctx).get().error(); } BOOST_AUTO_TEST_CASE(individual_error) @@ -752,7 +752,7 @@ BOOST_AUTO_TEST_CASE(format_strings_invalid_arguments) BOOST_AUTO_TEST_CASE(format_context_success) { // Helper - auto get = [](format_context_base& ctx) { return static_cast(ctx).get().value(); }; + auto get = [](format_context_base& ctx) { return static_cast(ctx).get().value(); }; // Empty BOOST_TEST(format_context(opts).get().value() == ""); @@ -804,7 +804,7 @@ BOOST_AUTO_TEST_CASE(format_context_charset) .append_value("abd\xff{}") .append_raw(" + ") .append_value(identifier("i`d`ent\xff`ifier")); - BOOST_TEST(ctx.get().value() == "SELECT '\xff{abc' + 'abd\xff{}' + `i``d``ent\xff`ifier`"); + BOOST_TEST(std::move(ctx).get().value() == "SELECT '\xff{abc' + 'abd\xff{}' + `i``d``ent\xff`ifier`"); } BOOST_AUTO_TEST_CASE(format_context_backslashes) @@ -816,13 +816,13 @@ BOOST_AUTO_TEST_CASE(format_context_backslashes) .append_value("ab'cd\"ef") .append_raw(" + ") .append_value(identifier("identif`ier")); - BOOST_TEST(ctx.get().value() == "SELECT 'ab''cd\"ef' + `identif``ier`"); + BOOST_TEST(std::move(ctx).get().value() == "SELECT 'ab''cd\"ef' + `identif``ier`"); } BOOST_AUTO_TEST_CASE(format_context_error) { // Helper - auto get = [](format_context_base& ctx) { return static_cast(ctx).get().error(); }; + auto get = [](format_context_base& ctx) { return static_cast(ctx).get().error(); }; // Just an error BOOST_TEST(get(format_context(opts).append_value("bad\xff")) == client_errc::invalid_encoding);