network_algorithms.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. //
  2. // Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BHO_MYSQL_DETAIL_NETWORK_ALGORITHMS_HPP
  8. #define BHO_MYSQL_DETAIL_NETWORK_ALGORITHMS_HPP
  9. #include <asio2/bho/mysql/diagnostics.hpp>
  10. #include <asio2/bho/mysql/error_code.hpp>
  11. #include <asio2/bho/mysql/execution_state.hpp>
  12. #include <asio2/bho/mysql/field_view.hpp>
  13. #include <asio2/bho/mysql/handshake_params.hpp>
  14. #include <asio2/bho/mysql/rows_view.hpp>
  15. #include <asio2/bho/mysql/statement.hpp>
  16. #include <asio2/bho/mysql/string_view.hpp>
  17. #include <asio2/bho/mysql/detail/access.hpp>
  18. #include <asio2/bho/mysql/detail/any_execution_request.hpp>
  19. #include <asio2/bho/mysql/detail/channel_ptr.hpp>
  20. #include <asio2/bho/mysql/detail/config.hpp>
  21. #include <asio2/bho/mysql/detail/execution_processor/execution_processor.hpp>
  22. #include <asio2/bho/mysql/detail/typing/get_type_index.hpp>
  23. #include <asio/any_completion_handler.hpp>
  24. #include <asio2/bho/mp11/integer_sequence.hpp>
  25. #include <array>
  26. #include <cstddef>
  27. namespace bho {
  28. namespace mysql {
  29. template <class... StaticRow>
  30. class static_execution_state;
  31. namespace detail {
  32. class channel;
  33. template <class T>
  34. using any_handler = asio::any_completion_handler<void(error_code, T)>;
  35. using any_void_handler = asio::any_completion_handler<void(error_code)>;
  36. // execution helpers
  37. template <class... T, std::size_t... I>
  38. std::array<field_view, sizeof...(T)> tuple_to_array_impl(const std::tuple<T...>& t, mp11::index_sequence<I...>) noexcept
  39. {
  40. return std::array<field_view, sizeof...(T)>{{to_field(std::get<I>(t))...}};
  41. }
  42. template <class... T>
  43. std::array<field_view, sizeof...(T)> tuple_to_array(const std::tuple<T...>& t) noexcept
  44. {
  45. return tuple_to_array_impl(t, mp11::make_index_sequence<sizeof...(T)>());
  46. }
  47. struct query_request_getter
  48. {
  49. any_execution_request value;
  50. any_execution_request get() const noexcept { return value; }
  51. };
  52. inline query_request_getter make_request_getter(string_view q, channel&) noexcept
  53. {
  54. return query_request_getter{q};
  55. }
  56. struct stmt_it_request_getter
  57. {
  58. statement stmt;
  59. span<const field_view> params; // Points into channel shared_fields()
  60. any_execution_request get() const noexcept { return any_execution_request(stmt, params); }
  61. };
  62. template <class FieldViewFwdIterator>
  63. inline stmt_it_request_getter make_request_getter(
  64. const bound_statement_iterator_range<FieldViewFwdIterator>& req,
  65. channel& chan
  66. )
  67. {
  68. auto& impl = access::get_impl(req);
  69. auto& shared_fields = get_shared_fields(chan);
  70. shared_fields.assign(impl.first, impl.last);
  71. return {impl.stmt, shared_fields};
  72. }
  73. template <std::size_t N>
  74. struct stmt_tuple_request_getter
  75. {
  76. statement stmt;
  77. std::array<field_view, N> params;
  78. any_execution_request get() const noexcept { return any_execution_request(stmt, params); }
  79. };
  80. template <class WritableFieldTuple>
  81. stmt_tuple_request_getter<std::tuple_size<WritableFieldTuple>::value>
  82. make_request_getter(const bound_statement_tuple<WritableFieldTuple>& req, channel&)
  83. {
  84. auto& impl = access::get_impl(req);
  85. return {impl.stmt, tuple_to_array(impl.params)};
  86. }
  87. //
  88. // connect
  89. //
  90. BHO_MYSQL_DECL
  91. void connect_erased(
  92. channel& chan,
  93. const void* endpoint,
  94. const handshake_params& params,
  95. error_code& err,
  96. diagnostics& diag
  97. );
  98. BHO_MYSQL_DECL
  99. void async_connect_erased(
  100. channel& chan,
  101. const void* endpoint,
  102. const handshake_params& params,
  103. diagnostics& diag,
  104. any_void_handler handler
  105. );
  106. // Handles casting from the generic EndpointType we've got in the interface to the concrete endpoint type
  107. template <class Stream>
  108. void connect_interface(
  109. channel& chan,
  110. const typename Stream::lowest_layer_type::endpoint_type& ep,
  111. const handshake_params& params,
  112. error_code& err,
  113. diagnostics& diag
  114. )
  115. {
  116. connect_erased(chan, &ep, params, err, diag);
  117. }
  118. template <class Stream>
  119. struct connect_initiation
  120. {
  121. template <class Handler>
  122. void operator()(
  123. Handler&& handler,
  124. channel* chan,
  125. const typename Stream::lowest_layer_type::endpoint_type& endpoint,
  126. handshake_params params,
  127. diagnostics* diag
  128. )
  129. {
  130. async_connect_erased(*chan, &endpoint, params, *diag, std::forward<Handler>(handler));
  131. }
  132. };
  133. template <class Stream, class CompletionToken>
  134. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  135. async_connect_interface(
  136. channel& chan,
  137. const typename Stream::lowest_layer_type::endpoint_type& endpoint,
  138. const handshake_params& params,
  139. diagnostics& diag,
  140. CompletionToken&& token
  141. )
  142. {
  143. return asio::async_initiate<CompletionToken, void(error_code)>(
  144. connect_initiation<Stream>(),
  145. token,
  146. &chan,
  147. endpoint,
  148. params,
  149. &diag
  150. );
  151. }
  152. //
  153. // handshake
  154. //
  155. BHO_MYSQL_DECL
  156. void handshake_erased(channel& channel, const handshake_params& params, error_code& err, diagnostics& diag);
  157. BHO_MYSQL_DECL
  158. void async_handshake_erased(
  159. channel& chan,
  160. const handshake_params& params,
  161. diagnostics& diag,
  162. any_void_handler
  163. );
  164. inline void handshake_interface(
  165. channel& channel,
  166. const handshake_params& params,
  167. error_code& err,
  168. diagnostics& diag
  169. )
  170. {
  171. handshake_erased(channel, params, err, diag);
  172. }
  173. struct handshake_initiation
  174. {
  175. template <class Handler>
  176. void operator()(Handler&& handler, channel* chan, handshake_params params, diagnostics* diag)
  177. {
  178. async_handshake_erased(*chan, params, *diag, std::forward<Handler>(handler));
  179. }
  180. };
  181. template <class CompletionToken>
  182. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  183. async_handshake_interface(
  184. channel& chan,
  185. const handshake_params& params,
  186. diagnostics& diag,
  187. CompletionToken&& token
  188. )
  189. {
  190. return asio::async_initiate<CompletionToken, void(error_code)>(
  191. handshake_initiation(),
  192. token,
  193. &chan,
  194. params,
  195. &diag
  196. );
  197. }
  198. //
  199. // execute
  200. //
  201. BHO_MYSQL_DECL
  202. void execute_erased(
  203. channel& channel,
  204. const any_execution_request& req,
  205. execution_processor& output,
  206. error_code& err,
  207. diagnostics& diag
  208. );
  209. BHO_MYSQL_DECL void async_execute_erased(
  210. channel& chan,
  211. const any_execution_request& req,
  212. execution_processor& output,
  213. diagnostics& diag,
  214. any_void_handler handler
  215. );
  216. struct initiate_execute
  217. {
  218. template <class Handler, class ExecutionRequest>
  219. void operator()(
  220. Handler&& handler,
  221. channel& chan,
  222. const ExecutionRequest& req,
  223. execution_processor& proc,
  224. diagnostics& diag
  225. )
  226. {
  227. auto getter = make_request_getter(req, chan);
  228. async_execute_erased(chan, getter.get(), proc, diag, std::forward<Handler>(handler));
  229. }
  230. };
  231. template <class ExecutionRequest, class ResultsType>
  232. void execute_interface(
  233. channel& channel,
  234. const ExecutionRequest& req,
  235. ResultsType& result,
  236. error_code& err,
  237. diagnostics& diag
  238. )
  239. {
  240. auto getter = make_request_getter(req, channel);
  241. execute_erased(channel, getter.get(), access::get_impl(result).get_interface(), err, diag);
  242. }
  243. template <class ExecutionRequest, class ResultsType, class CompletionToken>
  244. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  245. async_execute_interface(
  246. channel& chan,
  247. ExecutionRequest&& req,
  248. ResultsType& result,
  249. diagnostics& diag,
  250. CompletionToken&& token
  251. )
  252. {
  253. return asio::async_initiate<CompletionToken, void(error_code)>(
  254. initiate_execute(),
  255. token,
  256. std::ref(chan),
  257. std::forward<ExecutionRequest>(req),
  258. std::ref(access::get_impl(result).get_interface()),
  259. std::ref(diag)
  260. );
  261. }
  262. //
  263. // start_execution
  264. //
  265. BHO_MYSQL_DECL
  266. void start_execution_erased(
  267. channel& channel,
  268. const any_execution_request& req,
  269. execution_processor& proc,
  270. error_code& err,
  271. diagnostics& diag
  272. );
  273. BHO_MYSQL_DECL
  274. void async_start_execution_erased(
  275. channel& channel,
  276. const any_execution_request& req,
  277. execution_processor& proc,
  278. diagnostics& diag,
  279. any_void_handler handler
  280. );
  281. struct initiate_start_execution
  282. {
  283. template <class Handler, class ExecutionRequest>
  284. void operator()(
  285. Handler&& handler,
  286. channel& chan,
  287. const ExecutionRequest& req,
  288. execution_processor& proc,
  289. diagnostics& diag
  290. )
  291. {
  292. auto getter = make_request_getter(req, chan);
  293. async_start_execution_erased(chan, getter.get(), proc, diag, std::forward<Handler>(handler));
  294. }
  295. };
  296. template <class ExecutionRequest, class ExecutionStateType>
  297. void start_execution_interface(
  298. channel& channel,
  299. const ExecutionRequest& req,
  300. ExecutionStateType& st,
  301. error_code& err,
  302. diagnostics& diag
  303. )
  304. {
  305. auto getter = make_request_getter(req, channel);
  306. start_execution_erased(channel, getter.get(), access::get_impl(st).get_interface(), err, diag);
  307. }
  308. template <class ExecutionRequest, class ExecutionStateType, class CompletionToken>
  309. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  310. async_start_execution_interface(
  311. channel& chan,
  312. ExecutionRequest&& req,
  313. ExecutionStateType& st,
  314. diagnostics& diag,
  315. CompletionToken&& token
  316. )
  317. {
  318. return asio::async_initiate<CompletionToken, void(error_code)>(
  319. initiate_start_execution(),
  320. token,
  321. std::ref(chan),
  322. std::forward<ExecutionRequest>(req),
  323. std::ref(access::get_impl(st).get_interface()),
  324. std::ref(diag)
  325. );
  326. }
  327. //
  328. // prepare_statement
  329. //
  330. BHO_MYSQL_DECL
  331. statement prepare_statement_erased(channel& chan, string_view stmt, error_code& err, diagnostics& diag);
  332. BHO_MYSQL_DECL void async_prepare_statement_erased(
  333. channel& chan,
  334. string_view stmt,
  335. diagnostics& diag,
  336. any_handler<statement> handler
  337. );
  338. struct prepare_statement_initiation
  339. {
  340. template <class Handler>
  341. void operator()(Handler&& handler, channel* chan, string_view stmt_sql, diagnostics* diag)
  342. {
  343. async_prepare_statement_erased(*chan, stmt_sql, *diag, std::forward<Handler>(handler));
  344. }
  345. };
  346. inline statement prepare_statement_interface(
  347. channel& chan,
  348. string_view stmt,
  349. error_code& err,
  350. diagnostics& diag
  351. )
  352. {
  353. return prepare_statement_erased(chan, stmt, err, diag);
  354. }
  355. template <class CompletionToken>
  356. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(bho::mysql::error_code, bho::mysql::statement))
  357. async_prepare_statement_interface(channel& chan, string_view stmt, diagnostics& diag, CompletionToken&& token)
  358. {
  359. return asio::async_initiate<CompletionToken, void(error_code, statement)>(
  360. prepare_statement_initiation(),
  361. token,
  362. &chan,
  363. stmt,
  364. &diag
  365. );
  366. }
  367. //
  368. // close_statement
  369. //
  370. BHO_MYSQL_DECL
  371. void close_statement_erased(channel& chan, const statement& stmt, error_code& err, diagnostics& diag);
  372. BHO_MYSQL_DECL
  373. void async_close_statement_erased(
  374. channel& chan,
  375. const statement& stmt,
  376. diagnostics& diag,
  377. any_void_handler handler
  378. );
  379. struct close_statement_initiation
  380. {
  381. template <class Handler>
  382. void operator()(Handler&& handler, channel* chan, statement stmt, diagnostics* diag)
  383. {
  384. async_close_statement_erased(*chan, stmt, *diag, std::forward<Handler>(handler));
  385. }
  386. };
  387. inline void close_statement_interface(
  388. channel& chan,
  389. const statement& stmt,
  390. error_code& err,
  391. diagnostics& diag
  392. )
  393. {
  394. close_statement_erased(chan, stmt, err, diag);
  395. }
  396. template <class CompletionToken>
  397. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  398. async_close_statement_interface(
  399. channel& chan,
  400. const statement& stmt,
  401. diagnostics& diag,
  402. CompletionToken&& token
  403. )
  404. {
  405. return asio::async_initiate<CompletionToken, void(error_code)>(
  406. close_statement_initiation(),
  407. token,
  408. &chan,
  409. stmt,
  410. &diag
  411. );
  412. }
  413. //
  414. // read_some_rows (dynamic)
  415. //
  416. BHO_MYSQL_DECL
  417. rows_view read_some_rows_dynamic_erased(
  418. channel& chan,
  419. execution_state_impl& st,
  420. error_code& err,
  421. diagnostics& diag
  422. );
  423. BHO_MYSQL_DECL void async_read_some_rows_dynamic_erased(
  424. channel& chan,
  425. execution_state_impl& st,
  426. diagnostics& diag,
  427. any_handler<rows_view> handler
  428. );
  429. struct read_some_rows_dynamic_initiation
  430. {
  431. template <class Handler>
  432. void operator()(Handler&& handler, channel* chan, execution_state_impl* st, diagnostics* diag)
  433. {
  434. async_read_some_rows_dynamic_erased(*chan, *st, *diag, std::forward<Handler>(handler));
  435. }
  436. };
  437. inline rows_view read_some_rows_dynamic_interface(
  438. channel& chan,
  439. execution_state& st,
  440. error_code& err,
  441. diagnostics& diag
  442. )
  443. {
  444. return read_some_rows_dynamic_erased(chan, access::get_impl(st), err, diag);
  445. }
  446. template <class CompletionToken>
  447. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, rows_view))
  448. async_read_some_rows_dynamic_interface(
  449. channel& chan,
  450. execution_state& st,
  451. diagnostics& diag,
  452. CompletionToken&& token
  453. )
  454. {
  455. return asio::async_initiate<CompletionToken, void(error_code, rows_view)>(
  456. read_some_rows_dynamic_initiation(),
  457. token,
  458. &chan,
  459. &access::get_impl(st).get_interface(),
  460. &diag
  461. );
  462. }
  463. //
  464. // read_some_rows (static)
  465. //
  466. BHO_MYSQL_DECL
  467. std::size_t read_some_rows_static_erased(
  468. channel& chan,
  469. execution_processor& proc,
  470. const output_ref& output,
  471. error_code& err,
  472. diagnostics& diag
  473. );
  474. BHO_MYSQL_DECL
  475. void async_read_some_rows_erased(
  476. channel& chan,
  477. execution_processor& proc,
  478. const output_ref& output,
  479. diagnostics& diag,
  480. any_handler<std::size_t> handler
  481. );
  482. template <class SpanRowType, class... RowType>
  483. std::size_t read_some_rows_static_interface(
  484. channel& chan,
  485. static_execution_state<RowType...>& st,
  486. span<SpanRowType> output,
  487. error_code& err,
  488. diagnostics& diag
  489. )
  490. {
  491. constexpr std::size_t index = get_type_index<SpanRowType, RowType...>();
  492. static_assert(index != index_not_found, "SpanRowType must be one of the types returned by the query");
  493. return read_some_rows_static_erased(
  494. chan,
  495. access::get_impl(st).get_interface(),
  496. output_ref(output, index),
  497. err,
  498. diag
  499. );
  500. }
  501. struct read_some_rows_static_initiation
  502. {
  503. template <class Handler>
  504. void operator()(
  505. Handler&& handler,
  506. channel* chan,
  507. execution_processor* proc,
  508. const output_ref& output,
  509. diagnostics* diag
  510. )
  511. {
  512. async_read_some_rows_erased(*chan, *proc, output, *diag, std::forward<Handler>(handler));
  513. }
  514. };
  515. template <
  516. class SpanRowType,
  517. class... RowType,
  518. ASIO_COMPLETION_TOKEN_FOR(void(::bho::mysql::error_code, std::size_t)) CompletionToken>
  519. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code, rows_view))
  520. async_read_some_rows_static_interface(
  521. channel& chan,
  522. static_execution_state<RowType...>& st,
  523. span<SpanRowType> output,
  524. diagnostics& diag,
  525. CompletionToken&& token
  526. )
  527. {
  528. constexpr std::size_t index = get_type_index<SpanRowType, RowType...>();
  529. static_assert(index != index_not_found, "SpanRowType must be one of the types returned by the query");
  530. return asio::async_initiate<CompletionToken, void(error_code, std::size_t)>(
  531. read_some_rows_static_initiation(),
  532. token,
  533. &chan,
  534. &access::get_impl(st).get_interface(),
  535. output_ref(output, index),
  536. &diag
  537. );
  538. }
  539. //
  540. // read_resultset_head
  541. //
  542. BHO_MYSQL_DECL
  543. void read_resultset_head_erased(
  544. channel& channel,
  545. execution_processor& proc,
  546. error_code& err,
  547. diagnostics& diag
  548. );
  549. BHO_MYSQL_DECL
  550. void async_read_resultset_head_erased(
  551. channel& chan,
  552. execution_processor& proc,
  553. diagnostics& diag,
  554. any_void_handler handler
  555. );
  556. template <class ExecutionStateType>
  557. void read_resultset_head_interface(
  558. channel& channel,
  559. ExecutionStateType& st,
  560. error_code& err,
  561. diagnostics& diag
  562. )
  563. {
  564. read_resultset_head_erased(channel, access::get_impl(st).get_interface(), err, diag);
  565. }
  566. struct read_resultset_head_initiation
  567. {
  568. template <class Handler>
  569. void operator()(Handler&& handler, channel* chan, execution_processor* proc, diagnostics* diag)
  570. {
  571. async_read_resultset_head_erased(*chan, *proc, *diag, std::forward<Handler>(handler));
  572. }
  573. };
  574. template <class CompletionToken, class ExecutionStateType>
  575. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  576. async_read_resultset_head_interface(
  577. channel& chan,
  578. ExecutionStateType& st,
  579. diagnostics& diag,
  580. CompletionToken&& token
  581. )
  582. {
  583. return asio::async_initiate<CompletionToken, void(error_code)>(
  584. read_resultset_head_initiation(),
  585. token,
  586. &chan,
  587. &access::get_impl(st).get_interface(),
  588. &diag
  589. );
  590. }
  591. //
  592. // ping
  593. //
  594. BHO_MYSQL_DECL
  595. void ping_erased(channel& chan, error_code& code, diagnostics& diag);
  596. BHO_MYSQL_DECL
  597. void async_ping_erased(channel& chan, diagnostics& diag, any_void_handler handler);
  598. struct ping_initiation
  599. {
  600. template <class Handler>
  601. void operator()(Handler&& handler, channel* chan, diagnostics* diag)
  602. {
  603. async_ping_erased(*chan, *diag, std::forward<Handler>(handler));
  604. }
  605. };
  606. inline void ping_interface(channel& chan, error_code& code, diagnostics& diag)
  607. {
  608. ping_erased(chan, code, diag);
  609. }
  610. template <class CompletionToken>
  611. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  612. async_ping_interface(channel& chan, diagnostics& diag, CompletionToken&& token)
  613. {
  614. return asio::async_initiate<CompletionToken, void(error_code)>(ping_initiation(), token, &chan, &diag);
  615. }
  616. //
  617. // reset_connection
  618. //
  619. BHO_MYSQL_DECL
  620. void reset_connection_erased(channel& chan, error_code& code, diagnostics& diag);
  621. BHO_MYSQL_DECL
  622. void async_reset_connection_erased(channel& chan, diagnostics& diag, any_void_handler handler);
  623. struct reset_connection_initiation
  624. {
  625. template <class Handler>
  626. void operator()(Handler&& handler, channel* chan, diagnostics* diag)
  627. {
  628. async_reset_connection_erased(*chan, *diag, std::forward<Handler>(handler));
  629. }
  630. };
  631. inline void reset_connection_interface(channel& chan, error_code& code, diagnostics& diag)
  632. {
  633. reset_connection_erased(chan, code, diag);
  634. }
  635. template <class CompletionToken>
  636. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  637. async_reset_connection_interface(channel& chan, diagnostics& diag, CompletionToken&& token)
  638. {
  639. return asio::async_initiate<CompletionToken, void(error_code)>(
  640. reset_connection_initiation(),
  641. token,
  642. &chan,
  643. &diag
  644. );
  645. }
  646. //
  647. // close connection
  648. //
  649. BHO_MYSQL_DECL
  650. void close_connection_erased(channel& chan, error_code& code, diagnostics& diag);
  651. BHO_MYSQL_DECL
  652. void async_close_connection_erased(channel& chan, diagnostics& diag, any_void_handler handler);
  653. struct close_connection_initiation
  654. {
  655. template <class Handler>
  656. void operator()(Handler&& handler, channel* chan, diagnostics* diag)
  657. {
  658. async_close_connection_erased(*chan, *diag, std::forward<Handler>(handler));
  659. }
  660. };
  661. inline void close_connection_interface(channel& chan, error_code& code, diagnostics& diag)
  662. {
  663. close_connection_erased(chan, code, diag);
  664. }
  665. template <class CompletionToken>
  666. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  667. async_close_connection_interface(channel& chan, diagnostics& diag, CompletionToken&& token)
  668. {
  669. return asio::async_initiate<CompletionToken, void(error_code)>(
  670. close_connection_initiation(),
  671. token,
  672. &chan,
  673. &diag
  674. );
  675. }
  676. //
  677. // quit connection
  678. //
  679. BHO_MYSQL_DECL
  680. void quit_connection_erased(channel& chan, error_code& err, diagnostics& diag);
  681. BHO_MYSQL_DECL
  682. void async_quit_connection_erased(channel& chan, diagnostics& diag, any_void_handler handler);
  683. struct quit_connection_initiation
  684. {
  685. template <class Handler>
  686. void operator()(Handler&& handler, channel* chan, diagnostics* diag)
  687. {
  688. async_quit_connection_erased(*chan, *diag, std::forward<Handler>(handler));
  689. }
  690. };
  691. inline void quit_connection_interface(channel& chan, error_code& err, diagnostics& diag)
  692. {
  693. quit_connection_erased(chan, err, diag);
  694. }
  695. template <class CompletionToken>
  696. ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code))
  697. async_quit_connection_interface(channel& chan, diagnostics& diag, CompletionToken&& token)
  698. {
  699. return asio::async_initiate<CompletionToken, void(error_code)>(
  700. quit_connection_initiation(),
  701. token,
  702. &chan,
  703. &diag
  704. );
  705. }
  706. } // namespace detail
  707. } // namespace mysql
  708. } // namespace bho
  709. #ifdef BHO_MYSQL_HEADER_ONLY
  710. #include <asio2/bho/mysql/impl/network_algorithms.ipp>
  711. #endif
  712. #endif