mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-17 01:42:17 +00:00
Added error_info
This commit is contained in:
@@ -85,7 +85,7 @@ public:
|
||||
const Stream& next_level() const { return next_level_; }
|
||||
|
||||
/// Performs the MySQL-level handshake (synchronous with error code version).
|
||||
void handshake(const connection_params& params, error_code& ec);
|
||||
void handshake(const connection_params& params, error_code& ec, error_info& info);
|
||||
|
||||
/// Performs the MySQL-level handshake (synchronous with exceptions version).
|
||||
void handshake(const connection_params& params);
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
* until the operation completes, as no copy is made by the library.
|
||||
*/
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info))
|
||||
async_handshake(const connection_params& params, CompletionToken&& token);
|
||||
|
||||
/**
|
||||
@@ -111,14 +111,14 @@ public:
|
||||
* \warning After query() has returned, you should read the entire resultset
|
||||
* before calling query() again. Otherwise, the results are undefined.
|
||||
*/
|
||||
resultset<Stream> query(std::string_view query_string, error_code&);
|
||||
resultset<Stream> query(std::string_view query_string, error_code&, error_info&);
|
||||
|
||||
/// Executes a SQL text query (sync with exceptions version).
|
||||
resultset<Stream> query(std::string_view query_string);
|
||||
|
||||
/// Executes a SQL text query (async version).
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, resultset<Stream>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info, resultset<Stream>))
|
||||
async_query(std::string_view query_string, CompletionToken&& token);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define MYSQL_ASIO_ERROR_HPP
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
@@ -27,6 +28,20 @@ enum class Error : int
|
||||
/// An alias for boost::system error codes.
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
/// Additional information about error conditions
|
||||
class error_info
|
||||
{
|
||||
std::string msg_;
|
||||
public:
|
||||
error_info(std::string&& err = {}): msg_(std::move(err)) {}
|
||||
const std::string& message() const noexcept { return msg_; }
|
||||
void set_message(std::string&& err) { msg_ = std::move(err); }
|
||||
void clear() noexcept { msg_.clear(); }
|
||||
};
|
||||
inline bool operator==(const error_info& lhs, const error_info& rhs) noexcept { return lhs.message() == rhs.message(); }
|
||||
inline bool operator!=(const error_info& lhs, const error_info& rhs) noexcept { return !(lhs==rhs); }
|
||||
inline std::ostream& operator<<(std::ostream& os, const error_info& v) { return os << v.message(); }
|
||||
|
||||
}
|
||||
|
||||
#include "mysql/impl/error.hpp"
|
||||
|
||||
@@ -28,10 +28,19 @@ inline handshake_params to_handshake_params(
|
||||
template <typename Stream>
|
||||
void mysql::connection<Stream>::handshake(
|
||||
const connection_params& params,
|
||||
error_code& errc
|
||||
error_code& errc,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
detail::hanshake(channel_, detail::to_handshake_params(params), buffer_, errc);
|
||||
errc.clear();
|
||||
info.clear();
|
||||
detail::hanshake(
|
||||
channel_,
|
||||
detail::to_handshake_params(params),
|
||||
buffer_,
|
||||
errc,
|
||||
info
|
||||
);
|
||||
// TODO: should we close() the stream in case of error?
|
||||
}
|
||||
|
||||
@@ -41,13 +50,14 @@ void mysql::connection<Stream>::handshake(
|
||||
)
|
||||
{
|
||||
error_code errc;
|
||||
handshake(params, errc);
|
||||
detail::check_error_code(errc);
|
||||
error_info info;
|
||||
handshake(params, errc, info);
|
||||
detail::check_error_code(errc, info);
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, mysql::error_info))
|
||||
mysql::connection<Stream>::async_handshake(
|
||||
const connection_params& params,
|
||||
CompletionToken&& token
|
||||
@@ -65,11 +75,14 @@ mysql::connection<Stream>::async_handshake(
|
||||
template <typename Stream>
|
||||
mysql::resultset<Stream> mysql::connection<Stream>::query(
|
||||
std::string_view query_string,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
err.clear();
|
||||
info.clear();
|
||||
resultset<Stream> res;
|
||||
detail::execute_query(channel_, query_string, res, err);
|
||||
detail::execute_query(channel_, query_string, res, err, info);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -80,14 +93,18 @@ mysql::resultset<Stream> mysql::connection<Stream>::query(
|
||||
{
|
||||
resultset<Stream> res;
|
||||
error_code err;
|
||||
detail::execute_query(channel_, query_string, res, err);
|
||||
detail::check_error_code(err);
|
||||
error_info info;
|
||||
detail::execute_query(channel_, query_string, res, err, info);
|
||||
detail::check_error_code(err, info);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, mysql::resultset<Stream>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(mysql::error_code, mysql::error_info, mysql::resultset<Stream>)
|
||||
)
|
||||
mysql::connection<Stream>::async_query(
|
||||
std::string_view query_string,
|
||||
CompletionToken&& token
|
||||
|
||||
@@ -64,11 +64,11 @@ inline boost::system::error_code make_error_code(Error error)
|
||||
);
|
||||
}
|
||||
|
||||
inline void check_error_code(const error_code& errc)
|
||||
inline void check_error_code(const error_code& errc, const error_info& info)
|
||||
{
|
||||
if (errc)
|
||||
{
|
||||
throw boost::system::system_error(errc);
|
||||
throw boost::system::system_error(errc, info.message());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,4 +78,4 @@ inline void check_error_code(const error_code& errc)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -26,11 +26,12 @@ void hanshake(
|
||||
ChannelType& channel,
|
||||
const handshake_params& params,
|
||||
bytestring& buffer,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
|
||||
template <typename ChannelType, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info))
|
||||
async_handshake(
|
||||
ChannelType& channel,
|
||||
const handshake_params& params,
|
||||
@@ -44,4 +45,4 @@ async_handshake(
|
||||
#include "mysql/impl/handshake.ipp"
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,8 @@ inline std::uint8_t get_collation_first_byte(collation value)
|
||||
|
||||
inline error_code deserialize_handshake(
|
||||
boost::asio::const_buffer buffer,
|
||||
handshake_packet& output
|
||||
handshake_packet& output,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
DeserializationContext ctx (boost::asio::buffer(buffer), capabilities());
|
||||
@@ -33,7 +34,7 @@ inline error_code deserialize_handshake(
|
||||
}
|
||||
else if (msg_type == error_packet_header)
|
||||
{
|
||||
return process_error_packet(ctx);
|
||||
return process_error_packet(ctx, info);
|
||||
}
|
||||
else if (msg_type != handshake_protocol_version_10)
|
||||
{
|
||||
@@ -127,11 +128,11 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
error_code process_handshake(bytestring& buffer)
|
||||
error_code process_handshake(bytestring& buffer, error_info& info)
|
||||
{
|
||||
// Deserialize server greeting
|
||||
handshake_packet handshake;
|
||||
auto err = deserialize_handshake(boost::asio::buffer(buffer), handshake);
|
||||
auto err = deserialize_handshake(boost::asio::buffer(buffer), handshake, info);
|
||||
if (err) return err;
|
||||
|
||||
// Check capabilities
|
||||
@@ -159,7 +160,8 @@ public:
|
||||
|
||||
error_code process_handshake_server_response(
|
||||
bytestring& buffer,
|
||||
bool& auth_complete
|
||||
bool& auth_complete,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
DeserializationContext ctx (boost::asio::buffer(buffer), negotiated_caps_);
|
||||
@@ -174,7 +176,7 @@ public:
|
||||
}
|
||||
else if (msg_type == error_packet_header)
|
||||
{
|
||||
return process_error_packet(ctx);
|
||||
return process_error_packet(ctx, info);
|
||||
}
|
||||
else if (msg_type != auth_switch_request_header)
|
||||
{
|
||||
@@ -200,7 +202,8 @@ public:
|
||||
}
|
||||
|
||||
error_code process_auth_switch_response(
|
||||
boost::asio::const_buffer buffer
|
||||
boost::asio::const_buffer buffer,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
DeserializationContext ctx (boost::asio::buffer(buffer), negotiated_caps_);
|
||||
@@ -208,7 +211,7 @@ public:
|
||||
if (err) return err;
|
||||
if (msg_type == error_packet_header)
|
||||
{
|
||||
return process_error_packet(ctx);
|
||||
return process_error_packet(ctx, info);
|
||||
}
|
||||
else if (msg_type != ok_packet_header)
|
||||
{
|
||||
@@ -228,9 +231,12 @@ void mysql::detail::hanshake(
|
||||
ChannelType& channel,
|
||||
const handshake_params& params,
|
||||
bytestring& buffer,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
info.clear();
|
||||
|
||||
// Set up processor
|
||||
handshake_processor processor (params);
|
||||
|
||||
@@ -239,7 +245,7 @@ void mysql::detail::hanshake(
|
||||
if (err) return;
|
||||
|
||||
// Process server greeting
|
||||
err = processor.process_handshake(buffer);
|
||||
err = processor.process_handshake(buffer, info);
|
||||
if (err) return;
|
||||
|
||||
// Send
|
||||
@@ -252,7 +258,7 @@ void mysql::detail::hanshake(
|
||||
|
||||
// Process it
|
||||
bool auth_complete = false;
|
||||
err = processor.process_handshake_server_response(buffer, auth_complete);
|
||||
err = processor.process_handshake_server_response(buffer, auth_complete, info);
|
||||
if (err) return;
|
||||
if (auth_complete)
|
||||
{
|
||||
@@ -269,14 +275,14 @@ void mysql::detail::hanshake(
|
||||
if (err) return;
|
||||
|
||||
// Process it
|
||||
err = processor.process_auth_switch_response(boost::asio::buffer(buffer));
|
||||
err = processor.process_auth_switch_response(boost::asio::buffer(buffer), info);
|
||||
if (err) return;
|
||||
|
||||
channel.set_current_capabilities(processor.negotiated_capabilities());
|
||||
}
|
||||
|
||||
template <typename ChannelType, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, mysql::error_info))
|
||||
mysql::detail::async_handshake(
|
||||
ChannelType& channel,
|
||||
const handshake_params& params,
|
||||
@@ -284,7 +290,7 @@ mysql::detail::async_handshake(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
using HandlerSignature = void(mysql::error_code);
|
||||
using HandlerSignature = void(error_code, error_info);
|
||||
using HandlerType = BOOST_ASIO_HANDLER_TYPE(CompletionToken, HandlerSignature);
|
||||
using StreamType = typename ChannelType::stream_type;
|
||||
using BaseType = boost::beast::async_base<HandlerType, typename StreamType::executor_type>;
|
||||
@@ -296,6 +302,7 @@ mysql::detail::async_handshake(
|
||||
ChannelType& channel_;
|
||||
bytestring& buffer_;
|
||||
handshake_processor processor_;
|
||||
error_info info_;
|
||||
|
||||
Op(
|
||||
HandlerType&& handler,
|
||||
@@ -313,7 +320,7 @@ mysql::detail::async_handshake(
|
||||
void complete(bool cont, error_code errc)
|
||||
{
|
||||
channel_.set_current_capabilities(processor_.negotiated_capabilities());
|
||||
BaseType::complete(cont, errc);
|
||||
BaseType::complete(cont, errc, std::move(info_));
|
||||
}
|
||||
|
||||
void operator()(
|
||||
@@ -333,7 +340,7 @@ mysql::detail::async_handshake(
|
||||
}
|
||||
|
||||
// Process server greeting
|
||||
err = processor_.process_handshake(buffer_);
|
||||
err = processor_.process_handshake(buffer_, info_);
|
||||
if (err)
|
||||
{
|
||||
complete(cont, err);
|
||||
@@ -357,7 +364,7 @@ mysql::detail::async_handshake(
|
||||
}
|
||||
|
||||
// Process it
|
||||
err = processor_.process_handshake_server_response(buffer_, auth_complete);
|
||||
err = processor_.process_handshake_server_response(buffer_, auth_complete, info_);
|
||||
if (auth_complete) err.clear();
|
||||
if (err || auth_complete)
|
||||
{
|
||||
@@ -382,7 +389,7 @@ mysql::detail::async_handshake(
|
||||
}
|
||||
|
||||
// Process it
|
||||
err = processor_.process_auth_switch_response(boost::asio::buffer(buffer_));
|
||||
err = processor_.process_auth_switch_response(boost::asio::buffer(buffer_), info_);
|
||||
if (err)
|
||||
{
|
||||
complete(cont, err);
|
||||
|
||||
@@ -232,7 +232,7 @@ inline std::pair<error_code, std::uint8_t> deserialize_message_type(
|
||||
DeserializationContext& ctx
|
||||
);
|
||||
|
||||
inline error_code process_error_packet(DeserializationContext& ctx);
|
||||
inline error_code process_error_packet(DeserializationContext& ctx, error_info& info);
|
||||
|
||||
|
||||
/*struct StmtPrepare
|
||||
|
||||
@@ -214,12 +214,14 @@ inline std::pair<mysql::error_code, std::uint8_t> mysql::detail::deserialize_mes
|
||||
}
|
||||
|
||||
inline mysql::error_code mysql::detail::process_error_packet(
|
||||
DeserializationContext& ctx
|
||||
DeserializationContext& ctx,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
err_packet error_packet;
|
||||
auto errc = deserialize_message(error_packet, ctx);
|
||||
if (errc) return errc;
|
||||
info.set_message(std::string(error_packet.error_message.value));
|
||||
return make_error_code(static_cast<Error>(error_packet.error_code.value));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define MYSQL_ASIO_IMPL_QUERY_HPP
|
||||
|
||||
#include "mysql/resultset.hpp"
|
||||
#include "mysql/error.hpp"
|
||||
#include "mysql/impl/capabilities.hpp"
|
||||
#include <string_view>
|
||||
|
||||
@@ -28,11 +29,12 @@ void execute_query(
|
||||
ChannelType& channel,
|
||||
std::string_view query,
|
||||
channel_resultset_type<ChannelType>& output,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
|
||||
template <typename ChannelType, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, channel_resultset_type<ChannelType>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info, channel_resultset_type<ChannelType>))
|
||||
async_execute_query(
|
||||
ChannelType& channel,
|
||||
std::string_view query,
|
||||
@@ -47,11 +49,12 @@ fetch_result fetch_text_row(
|
||||
bytestring& buffer,
|
||||
std::vector<value>& output_values,
|
||||
ok_packet& output_ok_packet,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
);
|
||||
|
||||
template <typename ChannelType, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, fetch_result))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info, fetch_result))
|
||||
async_fetch_text_row(
|
||||
ChannelType& channel,
|
||||
const std::vector<field_metadata>& meta,
|
||||
|
||||
@@ -41,7 +41,8 @@ public:
|
||||
std::optional<std::uint64_t> // has value if there are fields in the response
|
||||
process_query_response(
|
||||
channel_resultset_type<ChannelType>& output,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
// Response may be: ok_packet, err_packet, local infile request (not implemented)
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
}
|
||||
else if (msg_type == error_packet_header)
|
||||
{
|
||||
err = process_error_packet(ctx);
|
||||
err = process_error_packet(ctx, info);
|
||||
return {};
|
||||
}
|
||||
else
|
||||
@@ -117,7 +118,8 @@ inline fetch_result process_fetch_message(
|
||||
const bytestring& buffer,
|
||||
std::vector<value>& output_values,
|
||||
ok_packet& output_ok_packet,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
// Message type: row, error or eof?
|
||||
@@ -135,7 +137,7 @@ inline fetch_result process_fetch_message(
|
||||
else if (msg_type == error_packet_header)
|
||||
{
|
||||
// An error occurred during the generation of the rows
|
||||
err = process_error_packet(ctx);
|
||||
err = process_error_packet(ctx, info);
|
||||
return fetch_result::error;
|
||||
}
|
||||
else
|
||||
@@ -156,7 +158,8 @@ void mysql::detail::execute_query(
|
||||
ChannelType& channel,
|
||||
std::string_view query,
|
||||
resultset<channel_stream_type<ChannelType>>& output,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
// Compose a com_query message, reset seq num
|
||||
@@ -172,7 +175,7 @@ void mysql::detail::execute_query(
|
||||
if (err) return;
|
||||
|
||||
// Response may be: ok_packet, err_packet, local infile request (not implemented), or response with fields
|
||||
auto num_fields = processor.process_query_response(output, err);
|
||||
auto num_fields = processor.process_query_response(output, err, info);
|
||||
if (!num_fields) // ok or err
|
||||
{
|
||||
return;
|
||||
@@ -199,7 +202,7 @@ void mysql::detail::execute_query(
|
||||
template <typename ChannelType, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(mysql::error_code, mysql::detail::channel_resultset_type<ChannelType>)
|
||||
void(mysql::error_code, mysql::error_info, mysql::detail::channel_resultset_type<ChannelType>)
|
||||
)
|
||||
mysql::detail::async_execute_query(
|
||||
ChannelType& channel,
|
||||
@@ -207,7 +210,7 @@ mysql::detail::async_execute_query(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
using HandlerSignature = void(error_code, channel_resultset_type<ChannelType>);
|
||||
using HandlerSignature = void(error_code, error_info, channel_resultset_type<ChannelType>);
|
||||
using HandlerType = BOOST_ASIO_HANDLER_TYPE(CompletionToken, HandlerSignature);
|
||||
using StreamType = typename ChannelType::stream_type;
|
||||
using BaseType = boost::beast::async_base<HandlerType, typename StreamType::executor_type>;
|
||||
@@ -236,10 +239,11 @@ mysql::detail::async_execute_query(
|
||||
{
|
||||
ResultsetType resultset;
|
||||
error_code err;
|
||||
auto num_fields = processor_->process_query_response(resultset, err);
|
||||
error_info info;
|
||||
auto num_fields = processor_->process_query_response(resultset, err, info);
|
||||
if (!num_fields) // ok or err
|
||||
{
|
||||
this->complete(cont, err, std::move(resultset));
|
||||
this->complete(cont, err, std::move(info), std::move(resultset));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -253,7 +257,7 @@ mysql::detail::async_execute_query(
|
||||
{
|
||||
ResultsetType resultset;
|
||||
std::move(*processor_).create_resultset(resultset);
|
||||
this->complete(cont, error_code(), std::move(resultset));
|
||||
this->complete(cont, error_code(), error_info(), std::move(resultset));
|
||||
}
|
||||
|
||||
void operator()(
|
||||
@@ -270,7 +274,7 @@ mysql::detail::async_execute_query(
|
||||
);
|
||||
if (err)
|
||||
{
|
||||
this->complete(cont, err, ResultsetType());
|
||||
this->complete(cont, err, error_info(), ResultsetType());
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -281,7 +285,7 @@ mysql::detail::async_execute_query(
|
||||
);
|
||||
if (err)
|
||||
{
|
||||
this->complete(cont, err, ResultsetType());
|
||||
this->complete(cont, err, error_info(), ResultsetType());
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -308,7 +312,7 @@ mysql::detail::async_execute_query(
|
||||
|
||||
if (err)
|
||||
{
|
||||
this->complete(cont, err, ResultsetType());
|
||||
this->complete(cont, err, error_info(), ResultsetType());
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -339,7 +343,8 @@ mysql::detail::fetch_result mysql::detail::fetch_text_row(
|
||||
bytestring& buffer,
|
||||
std::vector<value>& output_values,
|
||||
ok_packet& output_ok_packet,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
// Read a packet
|
||||
@@ -352,13 +357,17 @@ mysql::detail::fetch_result mysql::detail::fetch_text_row(
|
||||
buffer,
|
||||
output_values,
|
||||
output_ok_packet,
|
||||
err
|
||||
err,
|
||||
info
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template <typename ChannelType, typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, mysql::detail::fetch_result))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(mysql::error_code, mysql::error_info, mysql::detail::fetch_result)
|
||||
)
|
||||
mysql::detail::async_fetch_text_row(
|
||||
ChannelType& channel,
|
||||
const std::vector<field_metadata>& meta,
|
||||
@@ -401,15 +410,17 @@ mysql::detail::async_fetch_text_row(
|
||||
void process_result(bool cont)
|
||||
{
|
||||
error_code err;
|
||||
error_info info;
|
||||
auto result = process_fetch_message(
|
||||
channel_.current_capabilities(),
|
||||
meta_,
|
||||
buffer_,
|
||||
output_values_,
|
||||
output_ok_packet_,
|
||||
err
|
||||
err,
|
||||
info
|
||||
);
|
||||
this->complete(cont, err, result);
|
||||
this->complete(cont, err, info, result);
|
||||
}
|
||||
|
||||
void operator()(
|
||||
@@ -422,7 +433,7 @@ mysql::detail::async_fetch_text_row(
|
||||
yield channel_.async_read(buffer_, std::move(*this));
|
||||
if (err)
|
||||
{
|
||||
this->complete(cont, err, fetch_result::error);
|
||||
this->complete(cont, err, error_info(), fetch_result::error);
|
||||
yield break;
|
||||
}
|
||||
process_result(cont);
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
|
||||
template <typename StreamType>
|
||||
const mysql::row* mysql::resultset<StreamType>::fetch_one(
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
assert(valid());
|
||||
|
||||
err.clear();
|
||||
info.clear();
|
||||
|
||||
if (complete())
|
||||
{
|
||||
err.clear();
|
||||
return nullptr;
|
||||
}
|
||||
auto result = detail::fetch_text_row(
|
||||
@@ -24,7 +28,8 @@ const mysql::row* mysql::resultset<StreamType>::fetch_one(
|
||||
buffer_,
|
||||
current_row_.values(),
|
||||
ok_packet_,
|
||||
err
|
||||
err,
|
||||
info
|
||||
);
|
||||
eof_received_ = result == detail::fetch_result::eof;
|
||||
return result == detail::fetch_result::row ? ¤t_row_ : nullptr;
|
||||
@@ -34,20 +39,24 @@ template <typename StreamType>
|
||||
const mysql::row* mysql::resultset<StreamType>::fetch_one()
|
||||
{
|
||||
error_code errc;
|
||||
const row* res = fetch_one(errc);
|
||||
detail::check_error_code(errc);
|
||||
error_info info;
|
||||
const row* res = fetch_one(errc, info);
|
||||
detail::check_error_code(errc, info);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename StreamType>
|
||||
std::vector<mysql::owning_row> mysql::resultset<StreamType>::fetch_many(
|
||||
std::size_t count,
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
assert(valid());
|
||||
|
||||
err.clear();
|
||||
info.clear();
|
||||
|
||||
std::vector<mysql::owning_row> res;
|
||||
|
||||
if (!complete()) // support calling fetch on already exhausted resultset
|
||||
@@ -63,7 +72,8 @@ std::vector<mysql::owning_row> mysql::resultset<StreamType>::fetch_many(
|
||||
buff,
|
||||
values,
|
||||
ok_packet_,
|
||||
err
|
||||
err,
|
||||
info
|
||||
);
|
||||
eof_received_ = result == detail::fetch_result::eof;
|
||||
if (result == detail::fetch_result::row)
|
||||
@@ -86,17 +96,19 @@ std::vector<mysql::owning_row> mysql::resultset<StreamType>::fetch_many(
|
||||
)
|
||||
{
|
||||
error_code errc;
|
||||
auto res = fetch_many(count, errc);
|
||||
detail::check_error_code(errc);
|
||||
error_info info;
|
||||
auto res = fetch_many(count, errc, info);
|
||||
detail::check_error_code(errc, info);
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename StreamType>
|
||||
std::vector<mysql::owning_row> mysql::resultset<StreamType>::fetch_all(
|
||||
error_code& err
|
||||
error_code& err,
|
||||
error_info& info
|
||||
)
|
||||
{
|
||||
return fetch_many(std::numeric_limits<std::size_t>::max(), err);
|
||||
return fetch_many(std::numeric_limits<std::size_t>::max(), err, info);
|
||||
}
|
||||
|
||||
template <typename StreamType>
|
||||
@@ -107,12 +119,15 @@ std::vector<mysql::owning_row> mysql::resultset<StreamType>::fetch_all()
|
||||
|
||||
template <typename StreamType>
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, const mysql::row*))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(mysql::error_code, mysql::error_info, const mysql::row*)
|
||||
)
|
||||
mysql::resultset<StreamType>::async_fetch_one(
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
using HandlerSignature = void(error_code, const row*);
|
||||
using HandlerSignature = void(error_code, error_info, const row*);
|
||||
using HandlerType = BOOST_ASIO_HANDLER_TYPE(CompletionToken, HandlerSignature);
|
||||
using BaseType = boost::beast::async_base<HandlerType, typename StreamType::executor_type>;
|
||||
|
||||
@@ -129,6 +144,7 @@ mysql::resultset<StreamType>::async_fetch_one(
|
||||
|
||||
void operator()(
|
||||
error_code err,
|
||||
error_info info,
|
||||
detail::fetch_result result,
|
||||
bool cont=true
|
||||
)
|
||||
@@ -137,7 +153,7 @@ mysql::resultset<StreamType>::async_fetch_one(
|
||||
{
|
||||
if (resultset_.complete())
|
||||
{
|
||||
this->complete(cont, error_code(), nullptr);
|
||||
this->complete(cont, error_code(), error_info(), nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -153,6 +169,7 @@ mysql::resultset<StreamType>::async_fetch_one(
|
||||
this->complete(
|
||||
cont,
|
||||
err,
|
||||
std::move(info),
|
||||
result == detail::fetch_result::row ? &resultset_.current_row_ : nullptr
|
||||
);
|
||||
}
|
||||
@@ -167,19 +184,22 @@ mysql::resultset<StreamType>::async_fetch_one(
|
||||
Op(
|
||||
std::move(initiator.completion_handler),
|
||||
*this
|
||||
)(error_code(), detail::fetch_result::error, false);
|
||||
)(error_code(), error_info(), detail::fetch_result::error, false);
|
||||
return initiator.result.get();
|
||||
}
|
||||
|
||||
template <typename StreamType>
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, std::vector<mysql::owning_row>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(mysql::error_code, mysql::error_info, std::vector<mysql::owning_row>)
|
||||
)
|
||||
mysql::resultset<StreamType>::async_fetch_many(
|
||||
std::size_t count,
|
||||
CompletionToken&& token
|
||||
)
|
||||
{
|
||||
using HandlerSignature = void(error_code, std::vector<owning_row>);
|
||||
using HandlerSignature = void(error_code, error_info, std::vector<owning_row>);
|
||||
using HandlerType = BOOST_ASIO_HANDLER_TYPE(CompletionToken, HandlerSignature);
|
||||
using BaseType = boost::beast::async_base<HandlerType, typename StreamType::executor_type>;
|
||||
|
||||
@@ -218,6 +238,7 @@ mysql::resultset<StreamType>::async_fetch_many(
|
||||
|
||||
void operator()(
|
||||
error_code err,
|
||||
error_info info,
|
||||
detail::fetch_result result,
|
||||
bool cont=true
|
||||
)
|
||||
@@ -236,7 +257,7 @@ mysql::resultset<StreamType>::async_fetch_many(
|
||||
);
|
||||
if (result == detail::fetch_result::error)
|
||||
{
|
||||
this->complete(cont, err, std::move(impl_->rows));
|
||||
this->complete(cont, err, std::move(info), std::move(impl_->rows));
|
||||
yield break;
|
||||
}
|
||||
else if (result == detail::fetch_result::eof)
|
||||
@@ -248,7 +269,7 @@ mysql::resultset<StreamType>::async_fetch_many(
|
||||
impl_->row_received();
|
||||
}
|
||||
}
|
||||
this->complete(cont, err, std::move(impl_->rows));
|
||||
this->complete(cont, err, error_info(), std::move(impl_->rows));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -260,13 +281,16 @@ mysql::resultset<StreamType>::async_fetch_many(
|
||||
Op(
|
||||
std::move(initiator.completion_handler),
|
||||
std::make_shared<OpImpl>(*this, count)
|
||||
)(error_code(), detail::fetch_result::error, false);
|
||||
)(error_code(), error_info(), detail::fetch_result::error, false);
|
||||
return initiator.result.get();
|
||||
}
|
||||
|
||||
template <typename StreamType>
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(mysql::error_code, std::vector<mysql::owning_row>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(
|
||||
CompletionToken,
|
||||
void(mysql::error_code, mysql::error_info, std::vector<mysql::owning_row>)
|
||||
)
|
||||
mysql::resultset<StreamType>::async_fetch_all(
|
||||
CompletionToken&& token
|
||||
)
|
||||
@@ -281,4 +305,4 @@ mysql::resultset<StreamType>::async_fetch_all(
|
||||
#include <boost/asio/unyield.hpp>
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
* fetch_one is the fetch method that performs the less memory allocations
|
||||
* of the three.
|
||||
*/
|
||||
const row* fetch_one(error_code& err);
|
||||
const row* fetch_one(error_code& err, error_info& info);
|
||||
|
||||
/// Fetches a single row (sync with exceptions version).
|
||||
const row* fetch_one();
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
* Only if count is **greater** than the available number of rows,
|
||||
* the resultset will be completed.
|
||||
*/
|
||||
std::vector<owning_row> fetch_many(std::size_t count, error_code& err);
|
||||
std::vector<owning_row> fetch_many(std::size_t count, error_code& err, error_info& info);
|
||||
|
||||
/// Fetches at most count rows (sync with exceptions version).
|
||||
std::vector<owning_row> fetch_many(std::size_t count);
|
||||
@@ -104,24 +104,24 @@ public:
|
||||
*
|
||||
* The resultset is guaranteed to be complete() after this call returns.
|
||||
*/
|
||||
std::vector<owning_row> fetch_all(error_code& err);
|
||||
std::vector<owning_row> fetch_all(error_code& err, error_info& info);
|
||||
|
||||
/// Fetches all available rows (sync with exceptions version).
|
||||
std::vector<owning_row> fetch_all();
|
||||
|
||||
/// Fetchs a single row (async version).
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, const row*))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info, const row*))
|
||||
async_fetch_one(CompletionToken&& token);
|
||||
|
||||
/// Fetches at most count rows (async version).
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, std::vector<owning_row>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info, std::vector<owning_row>))
|
||||
async_fetch_many(std::size_t count, CompletionToken&& token);
|
||||
|
||||
/// Fetches all available rows (async version).
|
||||
template <typename CompletionToken>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, std::vector<owning_row>))
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(error_code, error_info, std::vector<owning_row>))
|
||||
async_fetch_all(CompletionToken&& token);
|
||||
|
||||
/**
|
||||
@@ -177,6 +177,6 @@ using tcp_resultset = resultset<boost::asio::ip::tcp::socket>;
|
||||
|
||||
}
|
||||
|
||||
#include "mysql/impl/resultset.hpp"
|
||||
#include "mysql/impl/resultset.ipp"
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user