#include "network_functions.hpp" #include using namespace mysql::test; using mysql::tcp_prepared_statement; using mysql::tcp_resultset; using mysql::tcp_connection; using mysql::error_info; using mysql::error_code; using mysql::detail::make_error_code; using mysql::Error; namespace { template auto sync_errc_impl(Callable&& cb) { using R = decltype(cb(std::declval(), std::declval())); network_result res; res.err = make_error_code(Error::no); res.info.set_message("Error info not cleared correctly"); res.value = cb(res.err, res.info); return res; } class sync_errc : public network_functions { public: network_result prepare_statement( tcp_connection& conn, std::string_view statement ) override { return sync_errc_impl([&conn, statement](error_code& err, error_info& info) { return conn.prepare_statement(statement, err, info); }); } network_result execute_statement( tcp_prepared_statement& stmt, value_list_it params_first, value_list_it params_last ) override { return sync_errc_impl([=, &stmt](error_code& err, error_info& info) { return stmt.execute(params_first, params_last, err, info); }); } network_result execute_statement( tcp_prepared_statement& stmt, const std::vector& values ) override { return sync_errc_impl([&stmt, &values](error_code& err, error_info& info) { return stmt.execute(values, err, info); }); } }; sync_errc sync_errc_obj; template auto sync_exc_impl(Callable&& cb) { using R = decltype(cb()); network_result res; try { res.value = cb(); } catch (const boost::system::system_error& err) { res.err = err.code(); res.info.set_message(err.what()); } return res; } class sync_exc : public network_functions { public: network_result prepare_statement( tcp_connection& conn, std::string_view statement ) override { return sync_exc_impl([&conn, statement] { return conn.prepare_statement(statement); }); } network_result execute_statement( tcp_prepared_statement& stmt, value_list_it params_first, value_list_it params_last ) override { return sync_exc_impl([&]{ return stmt.execute(params_first, params_last); }); } network_result execute_statement( tcp_prepared_statement& stmt, const std::vector& values ) override { return sync_exc_impl([&stmt, &values] { return stmt.execute(values); }); } }; sync_exc sync_exc_obj; template network_result async_impl(Callable&& cb) { std::promise> prom; cb([&prom](error_code errc, error_info info, auto retval) { prom.set_value(network_result{errc, std::move(info), std::move(retval)}); }); return prom.get_future().get(); } class async : public network_functions { public: network_result prepare_statement( tcp_connection& conn, std::string_view statement ) override { return async_impl([&conn, statement](auto&& token) { return conn.async_prepare_statement(statement, std::forward(token)); }); } network_result execute_statement( tcp_prepared_statement& stmt, value_list_it params_first, value_list_it params_last ) override { return async_impl([&](auto&& token) { return stmt.async_execute(params_first, params_last, std::forward(token)); }); } network_result execute_statement( tcp_prepared_statement& stmt, const std::vector& values ) override { return async_impl([&](auto&& token) { return stmt.async_execute(values, std::forward(token)); }); } }; async async_obj; } // Visible stuff mysql::test::network_functions* mysql::test::sync_errc_network_functions = &sync_errc_obj; mysql::test::network_functions* mysql::test::sync_exc_network_functions = &sync_exc_obj; mysql::test::network_functions* mysql::test::async_network_functions = &async_obj;