mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-15 01:02:17 +00:00
New connection iface
This commit is contained in:
@@ -9,17 +9,20 @@
|
||||
#define BOOST_MYSQL_CONNECTION_HPP
|
||||
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN // For some arcane reason, Doxygen fails to expand Asio macros without this
|
||||
|
||||
#include <boost/mysql/detail/protocol/channel.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/protocol/protocol_types.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/handshake.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/value_type_traits.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/prepared_statement.hpp>
|
||||
#include <boost/mysql/connection_params.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/row.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,7 +64,7 @@ template <
|
||||
class connection
|
||||
{
|
||||
std::unique_ptr<detail::channel<Stream>> channel_;
|
||||
protected:
|
||||
|
||||
detail::channel<Stream>& get_channel() noexcept
|
||||
{
|
||||
assert(valid());
|
||||
@@ -338,7 +341,7 @@ public:
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
resultset<Stream> query(boost::string_view query_string, error_code&, error_info&);
|
||||
void query(boost::string_view query_string, resultset& result, error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Executes a SQL text query (sync with exceptions version).
|
||||
@@ -348,7 +351,7 @@ public:
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
resultset<Stream> query(boost::string_view query_string);
|
||||
void query(boost::string_view query_string, resultset& result);
|
||||
|
||||
/**
|
||||
* \brief Executes a SQL text query (async without [reflink error_info] version).
|
||||
@@ -362,19 +365,18 @@ public:
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
)
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_query(
|
||||
boost::string_view query_string,
|
||||
resultset& result,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_query(query_string, shared_info(), std::forward<CompletionToken>(token));
|
||||
return async_query(query_string, result, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,15 +391,14 @@ public:
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
)
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_query(
|
||||
boost::string_view query_string,
|
||||
resultset& result,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
@@ -408,7 +409,7 @@ public:
|
||||
* Prepared statements are only valid while the connection object on which
|
||||
* this function was called is alive and open.
|
||||
*/
|
||||
prepared_statement<Stream> prepare_statement(boost::string_view statement, error_code&, error_info&);
|
||||
void prepare_statement(boost::string_view statement, prepared_statement& result, error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Prepares a statement (sync with exceptions version).
|
||||
@@ -416,7 +417,7 @@ public:
|
||||
* Prepared statements are only valid while the connection object on which
|
||||
* this function was called is alive and open.
|
||||
*/
|
||||
prepared_statement<Stream> prepare_statement(boost::string_view statement);
|
||||
void prepare_statement(boost::string_view statement, prepared_statement& result);
|
||||
|
||||
/**
|
||||
* \brief Prepares a statement (async without [reflink error_info] version).
|
||||
@@ -428,19 +429,18 @@ public:
|
||||
* `void(boost::mysql::error_code, boost::mysql::prepared_statement<Stream>)`
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::prepared_statement<Stream>)
|
||||
)
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, prepared_statement<Stream>))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_prepare_statement(
|
||||
boost::string_view statement,
|
||||
prepared_statement& result,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_prepare_statement(statement, shared_info(), std::forward<CompletionToken>(token));
|
||||
return async_prepare_statement(statement, result, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,15 +453,477 @@ public:
|
||||
* `void(boost::mysql::error_code, boost::mysql::prepared_statement<Stream>)`
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::prepared_statement<Stream>)
|
||||
)
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, prepared_statement<Stream>))
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_prepare_statement(
|
||||
boost::string_view statement,
|
||||
prepared_statement& result,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection, sync with error code version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueCollection, class EnableIf = detail::enable_if_value_collection<ValueCollection>>
|
||||
void execute_statement(
|
||||
const prepared_statement& statement,
|
||||
const ValueCollection& params,
|
||||
resultset& result,
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
return execute_statement(make_execute_params(statement, params), result, err, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection, sync with exceptions version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueCollection, class EnableIf = detail::enable_if_value_collection<ValueCollection>>
|
||||
void execute_statement(
|
||||
const prepared_statement& statement,
|
||||
const ValueCollection& params,
|
||||
resultset& result
|
||||
)
|
||||
{
|
||||
return execute_statement(make_execute_params(statement, params), result);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection,
|
||||
* async without [reflink error_info] version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
* It is __not__ necessary to keep the collection of parameters or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueCollection,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type),
|
||||
class EnableIf = detail::enable_if_value_collection<ValueCollection>
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_execute_statement(
|
||||
const prepared_statement& statement,
|
||||
const ValueCollection& params,
|
||||
resultset& result,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_execute_statement(
|
||||
make_execute_params(statement, params),
|
||||
result,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection,
|
||||
* async with [reflink error_info] version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
* It is __not__ necessary to keep the collection of parameters or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueCollection,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type),
|
||||
class EnableIf = detail::enable_if_value_collection<ValueCollection>
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_execute_statement(
|
||||
const prepared_statement& statement,
|
||||
const ValueCollection& params,
|
||||
resultset& result,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_execute_statement(
|
||||
make_execute_params(statement, params),
|
||||
result,
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`, sync with error code version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueForwardIterator>
|
||||
void execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result,
|
||||
error_code& ec,
|
||||
error_info& info
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`, sync with exceptions version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueForwardIterator>
|
||||
void execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`,
|
||||
* async without [reflink error_info] version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*
|
||||
* It is __not__ necessary to keep the objects in
|
||||
* \\[`params.first()`, `params.last()`) or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_execute(params, result, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`,
|
||||
* async with [reflink error_info] version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*
|
||||
* It is __not__ necessary to keep the objects in
|
||||
* \\[`params.first()`, `params.last()`) or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_execute_statement(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
resultset& result,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(sync with error code version).
|
||||
* \details
|
||||
* After calling this function, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*/
|
||||
void close_statement(const prepared_statement&, error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(sync with exceptions version).
|
||||
* \details
|
||||
* After calling this function, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*/
|
||||
void close_statement(const prepared_statement&);
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(async without [reflink error_info] version).
|
||||
* \details
|
||||
* After the operation completes, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close_statement(
|
||||
const prepared_statement& stmt,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_close_statement(stmt, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(async with [reflink error_info] version).
|
||||
* \details
|
||||
* After the operation completes, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close_statement(
|
||||
const prepared_statement& stmt,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (sync with error code version).
|
||||
* \details Returns `true` if a row was read successfully, `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and returns `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but returns `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*/
|
||||
bool read_one_row(resultset& resultset, row& output, error_code& err, error_info& info);
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (sync with exceptions version).
|
||||
* \details Returns `true` if a row was read successfully, `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and returns `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but returns `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*/
|
||||
bool read_one_row(resultset& resultset, row& output);
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (async without [reflink error_info] version).
|
||||
* \details Completes with `true` if a row was read successfully, and with `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and completes with `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but completes with `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, bool)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, bool))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, bool))
|
||||
async_read_one_row(
|
||||
resultset& resultset,
|
||||
row& output,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_read_one_row(resultset, output, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (async with [reflink error_info] version).
|
||||
* \details Completes with `true` if a row was read successfully, and with `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and completes with `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but completes with `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, bool)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, bool))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, bool))
|
||||
async_read_one_row(
|
||||
resultset& resultset,
|
||||
row& output,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
bool read_some_rows(resultset& resultset, rows_view& output, error_code& err, error_info& info);
|
||||
bool read_some_rows(resultset& resultset, rows_view& output);
|
||||
|
||||
/**
|
||||
* \brief Reads several rows, up to a maximum
|
||||
* (async without [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, bool))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, bool))
|
||||
async_read_some_rows(
|
||||
resultset& resultset,
|
||||
rows_view& output,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_read_some_rows(resultset, output, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads several rows, up to a maximum
|
||||
* (async with [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, bool))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, bool))
|
||||
async_read_some_rows(
|
||||
resultset& resultset,
|
||||
rows_view& output,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
/// Reads all available rows (sync with error code version).
|
||||
void read_all_rows(resultset& resultset, rows& output, error_code& err, error_info& info);
|
||||
|
||||
/// Reads all available rows (sync with exceptions version).
|
||||
void read_all_rows(resultset& resultset, rows& output);
|
||||
|
||||
/**
|
||||
* \brief Reads all available rows (async without [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_read_all_rows(
|
||||
resultset& resultset,
|
||||
rows& output,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_read_all_rows(resultset, output, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads all available rows (async with [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_read_all_rows(
|
||||
resultset& resultset,
|
||||
rows& output,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
@@ -114,16 +114,6 @@ public:
|
||||
std::uint8_t& shared_sequence_number() noexcept { return shared_sequence_number_; }
|
||||
};
|
||||
|
||||
// Helper class to get move semantics right for some I/O object types
|
||||
template <class Stream>
|
||||
struct null_channel_deleter
|
||||
{
|
||||
void operator()(channel<Stream>*) const noexcept {}
|
||||
};
|
||||
|
||||
template <class Stream>
|
||||
using channel_observer_ptr = std::unique_ptr<channel<Stream>, null_channel_deleter<Stream>>;
|
||||
|
||||
} // detail
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <boost/mysql/error.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/detail/protocol/channel.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/common.hpp>
|
||||
#include <boost/mysql/detail/protocol/channel.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/protocol/protocol_types.hpp>
|
||||
#include <boost/mysql/connection_params.hpp>
|
||||
#include <boost/mysql/collation.hpp>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <boost/mysql/detail/network_algorithms/quit_connection.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/mysql/detail/protocol/channel.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/error.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define BOOST_MYSQL_EXECUTE_PARAMS_HPP
|
||||
|
||||
#include <boost/mysql/value.hpp>
|
||||
#include <boost/mysql/prepared_statement.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/value_type_traits.hpp>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
@@ -16,6 +17,7 @@
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
|
||||
|
||||
/**
|
||||
* \brief Represents the parameters required to execute a [reflink prepared_statement].
|
||||
* \details In essence, this class contains an iterator range \\[first, last), pointing
|
||||
@@ -32,14 +34,27 @@ namespace mysql {
|
||||
template <class ValueForwardIterator>
|
||||
class execute_params
|
||||
{
|
||||
std::uint32_t statement_id_;
|
||||
ValueForwardIterator first_;
|
||||
ValueForwardIterator last_;
|
||||
static_assert(detail::is_value_forward_iterator<ValueForwardIterator>::value,
|
||||
"ValueForwardIterator requirements not met");
|
||||
public:
|
||||
/// Constructor.
|
||||
constexpr execute_params(ValueForwardIterator first, ValueForwardIterator last) :
|
||||
first_(first), last_(last) {}
|
||||
constexpr execute_params(
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last
|
||||
) :
|
||||
statement_id_(statement_id),
|
||||
first_(first),
|
||||
last_(last)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr std::uint32_t statement_id() const noexcept { return statement_id_; }
|
||||
|
||||
void set_statement_id(std::uint32_t v) noexcept { statement_id_ = v; }
|
||||
|
||||
/// Retrieves the parameter value range's begin.
|
||||
constexpr ValueForwardIterator first() const { return first_; }
|
||||
@@ -65,11 +80,26 @@ template <
|
||||
>
|
||||
constexpr execute_params<ValueForwardIterator>
|
||||
make_execute_params(
|
||||
std::uint32_t statement_id,
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last
|
||||
)
|
||||
{
|
||||
return execute_params<ValueForwardIterator>(first, last);
|
||||
return execute_params<ValueForwardIterator>(statement_id, first, last);
|
||||
}
|
||||
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
class EnableIf = detail::enable_if_value_forward_iterator<ValueForwardIterator>
|
||||
>
|
||||
constexpr execute_params<ValueForwardIterator>
|
||||
make_execute_params(
|
||||
const prepared_statement& stmt,
|
||||
ValueForwardIterator first,
|
||||
ValueForwardIterator last
|
||||
)
|
||||
{
|
||||
return execute_params<ValueForwardIterator>(stmt.id(), first, last);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,8 +118,20 @@ constexpr auto make_execute_params(
|
||||
return make_execute_params(std::begin(col), std::end(col));
|
||||
}
|
||||
|
||||
template <
|
||||
class ValueCollection,
|
||||
class EnableIf = detail::enable_if_value_collection<ValueCollection>
|
||||
>
|
||||
constexpr auto make_execute_params(
|
||||
const prepared_statement& stmt,
|
||||
const ValueCollection& col
|
||||
) -> execute_params<decltype(std::begin(col))>
|
||||
{
|
||||
return make_execute_params(stmt.id(), std::begin(col), std::end(col));
|
||||
}
|
||||
}
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -89,7 +89,7 @@ inline boost::mysql::field_type boost::mysql::field_metadata::type() const noexc
|
||||
{
|
||||
if (field_type_ == field_type::_not_computed)
|
||||
{
|
||||
field_type_ = detail::compute_field_type(msg_.type, msg_.flags);
|
||||
field_type_ = detail::compute_field_type(type_, flags_);
|
||||
assert(field_type_ != field_type::_not_computed);
|
||||
}
|
||||
return field_type_;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/field_type.hpp>
|
||||
#include <boost/utility/string_view_fwd.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -23,10 +25,19 @@ namespace mysql {
|
||||
*/
|
||||
class field_metadata
|
||||
{
|
||||
detail::column_definition_packet msg_;
|
||||
std::string schema_;
|
||||
std::string table_; // virtual table
|
||||
std::string org_table_; // physical table
|
||||
std::string name_; // virtual column name
|
||||
std::string org_name_; // physical column name
|
||||
collation character_set_;
|
||||
std::uint32_t column_length_; // maximum length of the field
|
||||
detail::protocol_field_type type_; // type of the column as defined in enum_field_types
|
||||
std::uint16_t flags_; // Flags as defined in Column Definition Flags
|
||||
std::uint8_t decimals_; // max shown decimal digits. 0x00 for int/static strings; 0x1f for dynamic strings, double, float
|
||||
mutable field_type field_type_ { field_type::_not_computed };
|
||||
|
||||
bool flag_set(std::uint16_t flag) const noexcept { return msg_.flags & flag; }
|
||||
bool flag_set(std::uint16_t flag) const noexcept { return flags_ & flag; }
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
@@ -37,25 +48,39 @@ public:
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN
|
||||
// Private, do not use.
|
||||
field_metadata(const detail::column_definition_packet& msg) noexcept: msg_(msg) {};
|
||||
// TODO: hide this
|
||||
field_metadata(const detail::column_definition_packet& msg, bool copy_strings) :
|
||||
schema_(copy_strings ? msg.schema.value : boost::string_view()),
|
||||
table_(copy_strings ? msg.table.value : boost::string_view()),
|
||||
org_table_(copy_strings ? msg.org_table.value : boost::string_view()),
|
||||
name_(copy_strings ? msg.name.value : boost::string_view()),
|
||||
org_name_(copy_strings ? msg.org_name.value : boost::string_view()),
|
||||
character_set_(msg.character_set),
|
||||
column_length_(msg.column_length),
|
||||
type_(msg.type),
|
||||
flags_(msg.flags),
|
||||
decimals_(msg.decimals)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Returns the name of the database (schema) the field belongs to.
|
||||
boost::string_view database() const noexcept { return msg_.schema.value; }
|
||||
boost::string_view database() const noexcept { return schema_; }
|
||||
|
||||
/**
|
||||
* \brief Returns the name of the virtual table the field belongs to.
|
||||
* \details If the table was aliased, this will be the name of the alias
|
||||
* (e.g. in `"SELECT * FROM employees emp"`, `table()` will be `"emp"`).
|
||||
*/
|
||||
boost::string_view table() const noexcept { return msg_.table.value; }
|
||||
boost::string_view table() const noexcept { return table_; }
|
||||
|
||||
/**
|
||||
* \brief Returns the name of the physical table the field belongs to.
|
||||
* \details E.g. in `"SELECT * FROM employees emp"`,
|
||||
* `original_table()` will be `"employees"`.
|
||||
*/
|
||||
boost::string_view original_table() const noexcept { return msg_.org_table.value; }
|
||||
boost::string_view original_table() const noexcept { return org_table_; }
|
||||
|
||||
/**
|
||||
* \brief Returns the actual name of the field.
|
||||
@@ -63,31 +88,31 @@ public:
|
||||
* (e.g. in `"SELECT id AS employee_id FROM employees"`,
|
||||
* `field_name()` will be `"employee_id"`).
|
||||
*/
|
||||
boost::string_view field_name() const noexcept { return msg_.name.value; }
|
||||
boost::string_view field_name() const noexcept { return name_; }
|
||||
|
||||
/**
|
||||
* \brief Returns the original (physical) name of the field.
|
||||
* \details E.g. in `"SELECT id AS employee_id FROM employees"`,
|
||||
* `original_field_name()` will be `"id"`.
|
||||
*/
|
||||
boost::string_view original_field_name() const noexcept { return msg_.org_name.value; }
|
||||
boost::string_view original_field_name() const noexcept { return org_name_; }
|
||||
|
||||
/// Returns the character set ([reflink collation]) for the column.
|
||||
collation character_set() const noexcept { return msg_.character_set; }
|
||||
collation character_set() const noexcept { return character_set_; }
|
||||
|
||||
/// Returns the maximum length of the field.
|
||||
unsigned column_length() const noexcept { return msg_.column_length; }
|
||||
unsigned column_length() const noexcept { return column_length_; }
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN
|
||||
// Private, do not use
|
||||
detail::protocol_field_type protocol_type() const noexcept { return msg_.type; }
|
||||
// Private, do not use. TODO: hide this
|
||||
detail::protocol_field_type protocol_type() const noexcept { return type_; }
|
||||
#endif
|
||||
|
||||
/// Returns the type of the field (see [reflink field_type] for more info).
|
||||
field_type type() const noexcept;
|
||||
|
||||
/// Returns the number of decimals of the field.
|
||||
unsigned decimals() const noexcept { return msg_.decimals; }
|
||||
unsigned decimals() const noexcept { return decimals_; }
|
||||
|
||||
/// Returns `true` if the field is not allowed to be NULL, `false` if it is nullable.
|
||||
bool is_not_null() const noexcept { return flag_set(detail::column_flags::not_null); }
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
#ifndef BOOST_MYSQL_PREPARED_STATEMENT_HPP
|
||||
#define BOOST_MYSQL_PREPARED_STATEMENT_HPP
|
||||
|
||||
#include <boost/mysql/resultset.hpp>
|
||||
#include <boost/mysql/execute_params.hpp>
|
||||
#include <boost/mysql/detail/protocol/channel.hpp>
|
||||
|
||||
#include <boost/mysql/detail/protocol/prepared_statement_messages.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/value_type_traits.hpp>
|
||||
#include <type_traits>
|
||||
#include <boost/mysql/value.hpp>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -40,18 +39,14 @@ constexpr std::array<value, 0> no_statement_params {};
|
||||
* whose parent connection has been closed or destroyed results
|
||||
* in undefined behavior.
|
||||
*/
|
||||
template <class Stream>
|
||||
class prepared_statement
|
||||
{
|
||||
detail::channel_observer_ptr<Stream> channel_;
|
||||
bool valid_ {false};
|
||||
detail::com_stmt_prepare_ok_packet stmt_msg_;
|
||||
|
||||
template <class ValueForwardIterator>
|
||||
void check_num_params(ValueForwardIterator first, ValueForwardIterator last, error_code& err, error_info& info) const;
|
||||
|
||||
error_info& shared_info() noexcept { assert(channel_); return channel_->shared_info(); }
|
||||
|
||||
struct async_execute_initiation;
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
@@ -59,329 +54,28 @@ public:
|
||||
*/
|
||||
prepared_statement() = default;
|
||||
|
||||
/**
|
||||
* \brief Move constructor.
|
||||
* \details The constructed statement will be valid if `other` is valid.
|
||||
* After this operation, `other` is guaranteed to be invalid.
|
||||
*/
|
||||
prepared_statement(prepared_statement&& other) = default;
|
||||
|
||||
/**
|
||||
* \brief Move assignment.
|
||||
* \details The assigned-to statement will be valid if `other` is valid.
|
||||
*/
|
||||
prepared_statement& operator=(prepared_statement&& rhs) = default;
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN
|
||||
prepared_statement(const prepared_statement&) = delete;
|
||||
prepared_statement& operator=(const prepared_statement&) = delete;
|
||||
|
||||
// Private. Do not use.
|
||||
prepared_statement(detail::channel<Stream>& chan, const detail::com_stmt_prepare_ok_packet& msg) noexcept:
|
||||
channel_(&chan), stmt_msg_(msg) {}
|
||||
// Private. Do not use. TODO: hide this
|
||||
prepared_statement(const detail::com_stmt_prepare_ok_packet& msg) noexcept:
|
||||
valid_(true), stmt_msg_(msg) {}
|
||||
#endif
|
||||
|
||||
/// The executor type associated to this object.
|
||||
using executor_type = typename Stream::executor_type;
|
||||
|
||||
/// Retrieves the executor associated to this object.
|
||||
executor_type get_executor() { assert(channel_); return channel_->get_executor(); }
|
||||
|
||||
/// Retrieves the stream object associated with the underlying connection.
|
||||
Stream& next_layer() noexcept { assert(channel_); return channel_->next_layer(); }
|
||||
|
||||
/// Retrieves the stream object associated with the underlying connection.
|
||||
const Stream& next_layer() const noexcept { assert(channel_); return channel_->next_layer(); }
|
||||
|
||||
/**
|
||||
* \brief Returns `true` if the statement is not a default-constructed object.
|
||||
* \details Calling any function other than assignment on an statement for which
|
||||
* this function returns `false` results in undefined behavior.
|
||||
*/
|
||||
bool valid() const noexcept { return channel_ != nullptr; }
|
||||
bool valid() const noexcept { return valid_; }
|
||||
|
||||
/// Returns a server-side identifier for the statement (unique in a per-connection basis).
|
||||
unsigned id() const noexcept { assert(valid()); return stmt_msg_.statement_id; }
|
||||
std::uint32_t id() const noexcept { assert(valid()); return stmt_msg_.statement_id; }
|
||||
|
||||
/// Returns the number of parameters that should be provided when executing the statement.
|
||||
unsigned num_params() const noexcept { assert(valid()); return stmt_msg_.num_params; }
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection, sync with error code version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueCollection, class EnableIf = detail::enable_if_value_collection<ValueCollection>>
|
||||
resultset<Stream> execute(const ValueCollection& params, error_code& err, error_info& info)
|
||||
{
|
||||
return execute(make_execute_params(params), err, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection, sync with exceptions version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueCollection, class EnableIf = detail::enable_if_value_collection<ValueCollection>>
|
||||
resultset<Stream> execute(const ValueCollection& params)
|
||||
{
|
||||
return execute(make_execute_params(params));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection,
|
||||
* async without [reflink error_info] version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
* It is __not__ necessary to keep the collection of parameters or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueCollection,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type),
|
||||
class EnableIf = detail::enable_if_value_collection<ValueCollection>
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
async_execute(
|
||||
const ValueCollection& params,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_execute(
|
||||
make_execute_params(params),
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (collection,
|
||||
* async with [reflink error_info] version).
|
||||
* \details
|
||||
* ValueCollection should meet the [reflink ValueCollection] requirements.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
* It is __not__ necessary to keep the collection of parameters or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueCollection,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type),
|
||||
class EnableIf = detail::enable_if_value_collection<ValueCollection>
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
async_execute(
|
||||
const ValueCollection& params,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_execute(
|
||||
make_execute_params(params),
|
||||
output_info,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`, sync with error code version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueForwardIterator>
|
||||
resultset<Stream> execute(const execute_params<ValueForwardIterator>& params,
|
||||
error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`, sync with exceptions version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this function has returned, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*/
|
||||
template <class ValueForwardIterator>
|
||||
resultset<Stream> execute(const execute_params<ValueForwardIterator>& params);
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`,
|
||||
* async without [reflink error_info] version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*
|
||||
* It is __not__ necessary to keep the objects in
|
||||
* \\[`params.first()`, `params.last()`) or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
async_execute(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_execute(params, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Executes a statement (`execute_params`,
|
||||
* async with [reflink error_info] version).
|
||||
* \details
|
||||
* ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements.
|
||||
* The range \\[`params.first()`, `params.last()`) will be used as parameters for
|
||||
* statement execution. They should be a valid iterator range.
|
||||
*
|
||||
* After this operation completes, you should read the entire resultset
|
||||
* before calling any function that involves communication with the server over this
|
||||
* connection. Otherwise, the results are undefined.
|
||||
*
|
||||
* It is __not__ necessary to keep the objects in
|
||||
* \\[`params.first()`, `params.last()`) or the
|
||||
* values they may point to alive after the initiating function returns.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, boost::mysql::resultset<Stream>)`.
|
||||
*/
|
||||
template <
|
||||
class ValueForwardIterator,
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, ::boost::mysql::resultset<Stream>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
async_execute(
|
||||
const execute_params<ValueForwardIterator>& params,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(sync with error code version).
|
||||
* \details
|
||||
* After calling this function, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*/
|
||||
void close(error_code&, error_info&);
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(sync with exceptions version).
|
||||
* \details
|
||||
* After calling this function, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(async without [reflink error_info] version).
|
||||
* \details
|
||||
* After the operation completes, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close(CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
{
|
||||
return async_close(shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Closes a prepared statement, deallocating it from the server
|
||||
(async with [reflink error_info] version).
|
||||
* \details
|
||||
* After the operation completes, no further functions may be called on this prepared
|
||||
* statement, other than assignment. Failing to do so results in undefined behavior.
|
||||
*
|
||||
* The handler signature for this operation is `void(boost::mysql::error_code)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
async_close(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
/// Rebinds the prepared statement type to another executor.
|
||||
template <class Executor>
|
||||
struct rebind_executor
|
||||
{
|
||||
/// The prepared statement type when rebound to the specified executor.
|
||||
using other = prepared_statement<
|
||||
typename Stream:: template rebind_executor<Executor>::other
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
#include <boost/mysql/impl/prepared_statement.hpp>
|
||||
|
||||
#endif /* INCLUDE_BOOST_MYSQL_PREPARED_STATEMENT_HPP_ */
|
||||
|
||||
@@ -11,10 +11,14 @@
|
||||
#include <boost/mysql/row.hpp>
|
||||
#include <boost/mysql/metadata.hpp>
|
||||
#include <boost/mysql/detail/protocol/common_messages.hpp>
|
||||
#include <boost/mysql/detail/protocol/channel.hpp>
|
||||
#include <boost/mysql/detail/channel/channel.hpp>
|
||||
#include <boost/mysql/detail/auxiliar/bytestring.hpp>
|
||||
#include <boost/mysql/detail/network_algorithms/common.hpp> // deserialize_row_fn
|
||||
#include <boost/utility/string_view_fwd.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace mysql {
|
||||
@@ -32,281 +36,107 @@ namespace mysql {
|
||||
* and moved-from resultsets. Calling any member function on an invalid
|
||||
* resultset, other than assignment, results in undefined behavior.
|
||||
*/
|
||||
template <
|
||||
class Stream
|
||||
>
|
||||
class resultset
|
||||
{
|
||||
class ok_packet_data
|
||||
{
|
||||
bool has_data_ {false};
|
||||
std::uint64_t affected_rows_;
|
||||
std::uint64_t last_insert_id_;
|
||||
std::uint16_t warnings_;
|
||||
std::string info_;
|
||||
public:
|
||||
ok_packet_data() = default;
|
||||
ok_packet_data(const detail::ok_packet& pack)
|
||||
{
|
||||
assign(pack);
|
||||
}
|
||||
|
||||
void reset() noexcept { has_data_ = false; }
|
||||
void assign(const detail::ok_packet& pack)
|
||||
{
|
||||
has_data_ = true;
|
||||
affected_rows_ = pack.affected_rows.value;
|
||||
last_insert_id_ = pack.last_insert_id.value;
|
||||
warnings_ = pack.warnings;
|
||||
info_.assign(pack.info.value.begin(), pack.info.value.end());
|
||||
}
|
||||
|
||||
bool has_value() const noexcept { return has_data_; }
|
||||
std::uint64_t affected_rows() const noexcept { assert(has_data_); return affected_rows_; }
|
||||
std::uint64_t last_insert_id() const noexcept { assert(has_data_); return last_insert_id_; }
|
||||
unsigned warning_count() const noexcept { assert(has_data_); return warnings_; }
|
||||
boost::string_view info() const noexcept { assert(has_data_); return info_; }
|
||||
};
|
||||
|
||||
bool valid_ {false};
|
||||
detail::deserialize_row_fn deserializer_ {};
|
||||
detail::channel_observer_ptr<Stream> channel_;
|
||||
detail::resultset_metadata meta_;
|
||||
detail::bytestring ok_packet_buffer_;
|
||||
detail::ok_packet ok_packet_;
|
||||
bool eof_received_ {false};
|
||||
std::vector<field_metadata> meta_;
|
||||
ok_packet_data ok_packet_;
|
||||
|
||||
error_info& shared_info() noexcept { assert(channel_); return channel_->shared_info(); }
|
||||
|
||||
struct read_one_op;
|
||||
struct read_many_op;
|
||||
struct read_many_op_impl;
|
||||
|
||||
public:
|
||||
public:
|
||||
/// \brief Default constructor.
|
||||
/// \details Default constructed resultsets have [refmem resultset valid] return `false`.
|
||||
resultset(): channel_(nullptr) {};
|
||||
|
||||
/**
|
||||
* \brief Move constructor.
|
||||
* \details The constructed resultset will be valid if `other` is valid.
|
||||
* After this operation, `other` is guaranteed to be invalid.
|
||||
*/
|
||||
resultset(resultset&& other) = default;
|
||||
|
||||
/**
|
||||
* \brief Move assignment.
|
||||
* \details The assigned-to resultset will be valid if `other` is valid.
|
||||
*/
|
||||
resultset& operator=(resultset&& rhs) = default;
|
||||
resultset() = default;
|
||||
|
||||
#ifndef BOOST_MYSQL_DOXYGEN
|
||||
resultset(const resultset&) = delete;
|
||||
resultset& operator=(const resultset&) = delete;
|
||||
|
||||
// Private, do not use
|
||||
resultset(detail::channel<Stream>& channel, detail::resultset_metadata&& meta,
|
||||
detail::deserialize_row_fn deserializer):
|
||||
deserializer_(deserializer), channel_(&channel), meta_(std::move(meta)) {};
|
||||
resultset(detail::channel<Stream>& channel, detail::bytestring&& buffer,
|
||||
const detail::ok_packet& ok_pack):
|
||||
channel_(&channel), ok_packet_buffer_(std::move(buffer)), ok_packet_(ok_pack), eof_received_(true) {};
|
||||
// Private, do not use. TODO: hide these
|
||||
resultset(std::vector<field_metadata>&& meta, detail::deserialize_row_fn deserializer) noexcept:
|
||||
valid_(true),
|
||||
deserializer_(deserializer),
|
||||
meta_(std::move(meta))
|
||||
{
|
||||
};
|
||||
resultset(const detail::ok_packet& ok_pack):
|
||||
valid_(true),
|
||||
ok_packet_(ok_pack)
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
/// The executor type associated to the object.
|
||||
using executor_type = typename detail::channel<Stream>::executor_type;
|
||||
|
||||
/// Retrieves the executor associated to the object.
|
||||
executor_type get_executor() { assert(channel_); return channel_->get_executor(); }
|
||||
|
||||
/// Retrieves the stream object associated with the underlying connection.
|
||||
Stream& next_layer() noexcept { assert(channel_); return channel_->next_layer(); }
|
||||
|
||||
/// Retrieves the stream object associated with the underlying connection.
|
||||
const Stream& next_layer() const noexcept { assert(channel_); return channel_->next_layer(); }
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (sync with error code version).
|
||||
* \details Returns `true` if a row was read successfully, `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and returns `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but returns `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*/
|
||||
bool read_one(row& output, error_code& err, error_info& info);
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (sync with exceptions version).
|
||||
* \details Returns `true` if a row was read successfully, `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and returns `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but returns `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*/
|
||||
bool read_one(row& output);
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (async without [reflink error_info] version).
|
||||
* \details Completes with `true` if a row was read successfully, and with `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and completes with `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but completes with `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, bool)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, bool))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, bool))
|
||||
async_read_one(row& output, CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
{
|
||||
return async_read_one(output, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads a single row (async with [reflink error_info] version).
|
||||
* \details Completes with `true` if a row was read successfully, and with `false` if
|
||||
* there was an error or there were no more rows to read. Calling
|
||||
* this function on a complete resultset always returns `false`.
|
||||
*
|
||||
* If the operation succeeds and completes with `true`, the new row will be
|
||||
* read against `output`, possibly reusing its memory. If the operation
|
||||
* succeeds but completes with `false`, `output` will be set to the empty row
|
||||
* (as if [refmem row clear] was called). If the operation fails,
|
||||
* `output` is left in a valid but undetrmined state.
|
||||
*
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, bool)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, bool))
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, bool))
|
||||
async_read_one(
|
||||
row& output,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
/// Reads several rows, up to a maximum (sync with error code version).
|
||||
std::vector<row> read_many(std::size_t count, error_code& err, error_info& info);
|
||||
|
||||
/// Reads several rows, up to a maximum (sync with exceptions version).
|
||||
std::vector<row> read_many(std::size_t count);
|
||||
|
||||
/**
|
||||
* \brief Reads several rows, up to a maximum
|
||||
* (async without [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, std::vector<::boost::mysql::row>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, std::vector<row>))
|
||||
async_read_many(
|
||||
std::size_t count,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
)
|
||||
{
|
||||
return async_read_many(count, shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads several rows, up to a maximum
|
||||
* (async with [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, std::vector<::boost::mysql::row>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, std::vector<row>))
|
||||
async_read_many(
|
||||
std::size_t count,
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
/// Reads all available rows (sync with error code version).
|
||||
std::vector<row> read_all(error_code& err, error_info& info);
|
||||
|
||||
/// Reads all available rows (sync with exceptions version).
|
||||
std::vector<row> read_all();
|
||||
|
||||
/**
|
||||
* \brief Reads all available rows (async without [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, std::vector<::boost::mysql::row>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, std::vector<row>))
|
||||
async_read_all(CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
|
||||
{
|
||||
return async_read_all(shared_info(), std::forward<CompletionToken>(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads all available rows (async with [reflink error_info] version).
|
||||
* \details
|
||||
* The handler signature for this operation is
|
||||
* `void(boost::mysql::error_code, std::vector<boost::mysql::row>)`.
|
||||
*/
|
||||
template <
|
||||
BOOST_ASIO_COMPLETION_TOKEN_FOR(
|
||||
void(::boost::mysql::error_code, std::vector<::boost::mysql::row>)
|
||||
)
|
||||
CompletionToken
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)
|
||||
>
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, std::vector<row>))
|
||||
async_read_all(
|
||||
error_info& output_info,
|
||||
CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Returns whether this object represents a valid resultset.
|
||||
* \details Returns `false` for default-constructed and moved-from resultsets.
|
||||
* Calling any member function on an invalid resultset,
|
||||
* other than assignment, results in undefined behavior.
|
||||
*/
|
||||
bool valid() const noexcept { return channel_ != nullptr; }
|
||||
bool valid() const noexcept { return valid_; }
|
||||
|
||||
/// \brief Returns whether the resultset has been completely read or not.
|
||||
/// \details See [link mysql.resultsets.complete this section] for more info.
|
||||
bool complete() const noexcept { return eof_received_; }
|
||||
bool complete() const noexcept { return ok_packet_.has_value(); }
|
||||
|
||||
// TODO: hide this
|
||||
/**
|
||||
* \brief Returns [link mysql.resultsets.metadata metadata] about the fields in the query.
|
||||
* \details There will be as many [reflink field_metadata] objects as fields
|
||||
* in the SQL query, and in the same order.
|
||||
*/
|
||||
const std::vector<field_metadata>& fields() const noexcept { return meta_.fields(); }
|
||||
const std::vector<field_metadata>& fields() const noexcept { return meta_; }
|
||||
|
||||
// TODO: hide this
|
||||
std::vector<field_metadata>& fields() noexcept { return meta_; }
|
||||
|
||||
/**
|
||||
* \brief The number of rows affected by the SQL that generated this resultset.
|
||||
* \details The resultset __must be [link mysql.resultsets.complete complete]__
|
||||
* before calling this function.
|
||||
*/
|
||||
std::uint64_t affected_rows() const noexcept { assert(complete()); return ok_packet_.affected_rows.value; }
|
||||
std::uint64_t affected_rows() const noexcept { return ok_packet_.affected_rows(); }
|
||||
|
||||
/**
|
||||
* \brief The last insert ID produced by the SQL that generated this resultset.
|
||||
* \details The resultset __must be [link mysql.resultsets.complete complete]__
|
||||
* before calling this function.
|
||||
*/
|
||||
std::uint64_t last_insert_id() const noexcept { assert(complete()); return ok_packet_.last_insert_id.value; }
|
||||
std::uint64_t last_insert_id() const noexcept { return ok_packet_.last_insert_id(); }
|
||||
|
||||
/**
|
||||
* \brief The number of warnings produced by the SQL that generated this resultset.
|
||||
* \details The resultset __must be [link mysql.resultsets.complete complete]__
|
||||
* before calling this function.
|
||||
*/
|
||||
unsigned warning_count() const noexcept { assert(complete()); return ok_packet_.warnings; }
|
||||
unsigned warning_count() const noexcept { return ok_packet_.warning_count(); }
|
||||
|
||||
/**
|
||||
* \brief Additionat text information about the execution of
|
||||
@@ -315,22 +145,10 @@ class resultset
|
||||
* before calling this function. The returned string is guaranteed to be valid
|
||||
* until the resultset object is destroyed.
|
||||
*/
|
||||
boost::string_view info() const noexcept { assert(complete()); return ok_packet_.info.value; }
|
||||
|
||||
/// Rebinds the resultset type to another executor.
|
||||
template <class Executor>
|
||||
struct rebind_executor
|
||||
{
|
||||
/// The resultset type when rebound to the specified executor.
|
||||
using other = resultset<
|
||||
typename Stream:: template rebind_executor<Executor>::other
|
||||
>;
|
||||
};
|
||||
boost::string_view info() const noexcept { return ok_packet_.info(); }
|
||||
};
|
||||
|
||||
} // mysql
|
||||
} // boost
|
||||
|
||||
#include <boost/mysql/impl/resultset.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user