Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:39:23

0001 //
0002 // Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_MYSQL_WITH_PARAMS_HPP
0009 #define BOOST_MYSQL_WITH_PARAMS_HPP
0010 
0011 #include <boost/mysql/constant_string_view.hpp>
0012 
0013 #include <boost/mysql/detail/format_sql.hpp>
0014 
0015 #include <tuple>
0016 #include <utility>
0017 
0018 namespace boost {
0019 namespace mysql {
0020 
0021 /**
0022  * \brief Type trait that applies the transformation performed by `std::make_tuple` to a single element.
0023  * \details
0024  * For example: \n
0025  *   - `make_tuple_element_t<int>` yields `int` \n
0026  *   - `make_tuple_element_t<const int&>` yields `int` \n
0027  *   - `make_tuple_element_t<std::reference_wrapper<int>>` yields `int&` \n
0028  * \n
0029  * Consult the <a href="https://en.cppreference.com/w/cpp/utility/tuple/make_tuple">`std::make_tuple`</a> docs
0030  * for more info.
0031  */
0032 template <class T>
0033 using make_tuple_element_t = typename std::tuple_element<0, decltype(std::make_tuple(std::declval<T&&>()))>::
0034     type;
0035 
0036 /**
0037  * \brief A query format string and format arguments that can be executed.
0038  * \details
0039  * Contains a query with placeholders (i.e. `{}`) and a set of parameters to
0040  * expand such placeholders. Satisfies `ExecutionRequest` and can thus be passed
0041  * to \ref any_connection::execute, \ref any_connection::start_execution and its
0042  * async counterparts.
0043  * \n
0044  * When executed, client-side SQL formatting is invoked
0045  * to expand the provided query with the supplied parameters. The resulting query is then sent to
0046  * the server for execution. Formally, given a `conn` variable of \ref any_connection type,
0047  * the query is generated as if the following was called:
0048  * ```
0049  *   format_sql(
0050  *       this->query,
0051  *       conn.format_opts().value(),
0052  *       std::get<i>(this->args)... // for i in [0, sizeof...(Formattable))
0053  *   );
0054  * ```
0055  * \n
0056  * Objects of this type are usually created using \ref with_params, which
0057  * creates `args` by calling `std::make_tuple`.
0058  *
0059  * \par Object lifetimes
0060  * The format string `query` is stored as a view, as a compile-time string should be used in most cases.
0061  * When using \ref with_params, `args` will usually contain copies of the passed parameters
0062  * (as per <a href="https://en.cppreference.com/w/cpp/utility/tuple/make_tuple">`std::make_tuple`</a>),
0063  * which is safe even when using async functions with deferred completion tokens.
0064  * You may disable such copies using `std::ref`, as you would when using `std::make_tuple`.
0065  *
0066  * \par Errors
0067  * When passed to \ref any_connection::execute, \ref any_connection::start_execution or
0068  * its async counterparts, in addition to the usual network and server-generated errors,
0069  * `with_params_t` may generate the following errors: \n
0070  *   - Any errors generated by \ref format_sql. This includes errors due to invalid format
0071  *     strings and unformattable arguments (e.g. invalid UTF-8).
0072  *   - \ref client_errc::unknown_character_set if the connection does not know the
0073  *     character set it's using when the query is executed (i.e. \ref any_connection::current_character_set
0074  *     would return an error.
0075  */
0076 template <BOOST_MYSQL_FORMATTABLE... Formattable>
0077 struct with_params_t
0078 {
0079     /// The query to be expanded and executed, which may contain `{}` placeholders.
0080     constant_string_view query;
0081 
0082     /// The arguments to use to expand the query.
0083     std::tuple<Formattable...> args;
0084 };
0085 
0086 /**
0087  * \brief Creates a query with parameters (client-side SQL formatting) that can be executed.
0088  * \details
0089  * Creates a \ref with_params_t object by packing the supplied arguments into a tuple,
0090  * calling <a href="https://en.cppreference.com/w/cpp/utility/tuple/make_tuple">`std::make_tuple`</a>.
0091  * As per `std::make_tuple`, parameters will be decay-copied into the resulting object.
0092  * This behavior can be disabled by passing `std::reference_wrapper` objects, which are
0093  * transformed into references.
0094  * \n
0095  * This function does not inspect the supplied query string and arguments.
0096  * Errors like missing format arguments are detected when the resulting object is executed.
0097  * This function does not involve communication with the server.
0098  * \n
0099  * The passed `args` must either satisfy `Formattable`, or be `std::reference_wrapper<T>`
0100  * with `T` satisfying `Formattable`.
0101  * \n
0102  * See \ref with_params_t for details on how the execution request works.
0103  * \n
0104  * \par Exception safety
0105  * Strong guarantee. Any exception thrown when copying `args` will be propagated.
0106  * \n
0107  */
0108 template <class... FormattableOrRefWrapper>
0109 auto with_params(constant_string_view query, FormattableOrRefWrapper&&... args)
0110     -> with_params_t<make_tuple_element_t<FormattableOrRefWrapper>...>
0111 {
0112     return {query, std::make_tuple(std::forward<FormattableOrRefWrapper>(args)...)};
0113 }
0114 
0115 }  // namespace mysql
0116 }  // namespace boost
0117 
0118 #include <boost/mysql/impl/with_params.hpp>
0119 
0120 #endif