Improved client-side SQL formatting docs

close #223
This commit is contained in:
Ruben Perez 2024-03-15 19:59:14 +01:00
parent 84d83553b9
commit 9950b91519
4 changed files with 23 additions and 5 deletions

View File

@ -139,8 +139,9 @@ But don't do it in production code!
[heading:unknown_character_set Solving the unknown_character_set error]
If you are getting a `client_errc::unknown_character_set` error, your connection
is currently unaware of the character set it's using, which is required by format operations.
If you are getting a `boost::system::system_error` with a
`client_errc::unknown_character_set` error code (or getting this error code by other means),
your connection is currently unaware of the character set it's using, which is required by format operations.
Try the following:
* Make sure that you are performing connection establishment ([refmem any_connection connect] or

View File

@ -136,7 +136,9 @@ For a reference on how character set tracking works, please read [link mysql.cha
Passing an incorrect `format_options` value to formatting functions may cause
escaping to generate incorrect values, which may generate vulnerabilities.
Stay safe and always use [refmem any_connection format_opts] instead of
hand-crafting `format_options` values.
hand-crafting `format_options` values. Doing this, if the character set can't be safely
determined, you will get a [link mysql.sql_formatting.unknown_character_set `client_errc::unknown_character_set`]
error instead of a vulnerability.
]

View File

@ -117,6 +117,10 @@ static std::string compose_batch_insert(
emp.salary
);
is_first = false;
// If you find yourself repeating the formatting logic for a type
// like employee over and over, you can specialize boost::mysql::formatter<employee>
// employee objects usable as format arguments. See batch_inserts_generic for an example.
}
// fomat_context::get() returns the result of our formatting operation.

View File

@ -2176,9 +2176,10 @@ void section_sql_formatting(string_view server_hostname, string_view username, s
{
// We're trying to format a double infinity value, which is not
// supported by MySQL. This will throw an exception.
format_sql(opts, "SELECT {}", HUGE_VAL);
std::string formatted_query = format_sql(opts, "SELECT {}", HUGE_VAL);
//<-
ASSERT(false);
boost::ignore_unused(formatted_query);
//->
}
catch (const boost::system::system_error& err)
@ -2226,11 +2227,21 @@ void section_sql_formatting(string_view server_hostname, string_view username, s
#endif
{
//[sql_formatting_memory_reuse
std::string storage; // we want to re-use memory held by storage
// we want to re-use memory held by storage
std::string storage;
// storage is moved into ctx by the constructor. If any memory
// had been allocated by the string, it will be re-used.
boost::mysql::format_context ctx(conn.format_opts().value(), std::move(storage));
// Use ctx as you normally would
boost::mysql::format_sql_to(ctx, "SELECT {}", 42);
// When calling get(), the string is moved out of the context
std::string query = std::move(ctx).get().value();
//]
ASSERT(query == "SELECT 42");
}
}