2
0
mirror of https://github.com/boostorg/mysql.git synced 2026-02-13 12:32:18 +00:00

Now network tests exercise async functions

Now statement::async_execute perform adequate param checking
This commit is contained in:
ruben
2020-02-10 04:26:27 +00:00
parent f7430308f5
commit 81d6482eb7
5 changed files with 77 additions and 14 deletions

View File

@@ -47,4 +47,5 @@ Technical debt
Take fetch_many() algorithm out into network_algorithms (e.g. read_many_rows)
Rename (De)SerializationContext
Test zero dates
clear_errors() function to clear error_info and error_code at once
clear_errors() function to clear error_info and error_code at once
Review .hpp/.ipp convention

View File

@@ -3,6 +3,26 @@
#include "mysql/impl/network_algorithms/execute_statement.hpp"
#include "mysql/impl/stringize.hpp"
#include <boost/beast/core/bind_handler.hpp>
template <typename Stream>
template <typename ForwardIterator>
void mysql::prepared_statement<Stream>::check_num_params(
ForwardIterator first,
ForwardIterator last,
error_code& err,
error_info& info
) const
{
auto param_count = std::distance(first, last);
if (param_count != num_params())
{
err = detail::make_error_code(Error::wrong_num_params);
info.set_message(detail::stringize(
"prepared_statement::execute: expected ", num_params(), " params, but got ", param_count));
}
}
template <typename Stream>
template <typename ForwardIterator>
@@ -16,18 +36,13 @@ mysql::resultset<Stream> mysql::prepared_statement<Stream>::execute(
assert(valid());
mysql::resultset<Stream> res;
err.clear();
info.clear();
auto param_count = std::distance(params_first, params_last);
if (param_count != num_params())
// Verify we got passed the right number of params
check_num_params(params_first, params_last, err, info);
if (!err)
{
err = detail::make_error_code(Error::wrong_num_params);
info.set_message(detail::stringize(
"prepared_statement::execute: expected ", num_params(), " params, but got ", param_count));
}
else
{
err.clear();
info.clear();
detail::execute_statement(
*channel_,
stmt_msg_.statement_id.value,
@@ -64,8 +79,26 @@ auto mysql::prepared_statement<StreamType>::async_execute(
CompletionToken&& token
) const
{
// TODO: actually return an error message here instead of crashing
assert(std::distance(params_first, params_last) == num_params());
// Check we got passed the right number of params
error_code err;
error_info info;
check_num_params(params_first, params_last, err, info);
if (err)
{
using HandlerSignature = void(error_code, error_info, resultset<StreamType>);
boost::asio::async_completion<CompletionToken, HandlerSignature> completion (token);
return boost::asio::post(
channel_->next_layer().get_executor(),
boost::beast::bind_front_handler(
std::move(completion.completion_handler),
err,
std::move(info),
resultset<StreamType>()
)
);
}
// Actually execute the statement
return detail::async_execute_statement(
*channel_,
stmt_msg_.statement_id.value,

View File

@@ -16,6 +16,9 @@ class prepared_statement
{
detail::channel<Stream>* channel_ {};
detail::com_stmt_prepare_ok_packet stmt_msg_;
template <typename ForwardIterator>
void check_num_params(ForwardIterator first, ForwardIterator last, error_code& err, error_info& info) const;
public:
prepared_statement() = default;
prepared_statement(detail::channel<Stream>& chan, const detail::com_stmt_prepare_ok_packet& msg) noexcept:

View File

@@ -33,6 +33,12 @@ struct ExecuteStatementIteratorTraits
{
return stmt.execute(first, last);
}
template <typename CompletionToken>
static auto async(const tcp_prepared_statement& stmt, listit first, listit last, CompletionToken&& token)
{
return stmt.async_execute(first, last, std::forward<CompletionToken>(token));
}
};
struct ExecuteStatementIteratorTest : public NetworkTest<ExecuteStatementIteratorTraits> {};
@@ -81,6 +87,12 @@ struct ExecuteStatementContainerTraits
{
return stmt.execute(v);
}
template <typename CompletionToken>
static auto async(const tcp_prepared_statement& stmt, const std::vector<value>& v, CompletionToken&& token)
{
return stmt.async_execute(v, std::forward<CompletionToken>(token));
}
};
struct ExecuteStatementContainerTest : public NetworkTest<ExecuteStatementContainerTraits> {};

View File

@@ -241,6 +241,12 @@ public:
template <typename TraitsType>
using traits_network_function = typename get_network_function_type<TraitsType>::type;
template <typename... T>
struct printer
{
static_assert(std::is_same_v<T..., int>);
};
template <typename TraitsType, typename R, typename... Args>
auto make_network_functions_impl(R(*)(Args...))
{
@@ -266,9 +272,17 @@ auto make_network_functions_impl(R(*)(Args...))
}
return res;
};
auto async = [](Args... args) {
std::promise<NetResultType> prom;
TraitsType::async(std::forward<Args>(args)..., [&prom](error_code errc, error_info info, auto retval) {
prom.set_value(NetResultType{errc, std::move(info), std::move(retval)});
});
return prom.get_future().get();
};
return std::vector<NetFunType>{
NetFunType("sync_errc", sync_errc),
NetFunType("sync_exc", sync_exc)
NetFunType("sync_exc", sync_exc),
NetFunType("async", async)
};
}