connection.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  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 BOOST_MYSQL_IMPL_CONNECTION_HPP
  8. #define BOOST_MYSQL_IMPL_CONNECTION_HPP
  9. #pragma once
  10. #include <boost/mysql/connection.hpp>
  11. #include <boost/mysql/diagnostics.hpp>
  12. #include <boost/mysql/execution_state.hpp>
  13. #include <boost/mysql/row.hpp>
  14. #include <boost/mysql/statement.hpp>
  15. #include <boost/mysql/detail/auxiliar/access_fwd.hpp>
  16. #include <boost/mysql/detail/auxiliar/error_helpers.hpp>
  17. #include <boost/mysql/detail/network_algorithms/close_connection.hpp>
  18. #include <boost/mysql/detail/network_algorithms/close_statement.hpp>
  19. #include <boost/mysql/detail/network_algorithms/connect.hpp>
  20. #include <boost/mysql/detail/network_algorithms/execute_statement.hpp>
  21. #include <boost/mysql/detail/network_algorithms/handshake.hpp>
  22. #include <boost/mysql/detail/network_algorithms/ping.hpp>
  23. #include <boost/mysql/detail/network_algorithms/prepare_statement.hpp>
  24. #include <boost/mysql/detail/network_algorithms/query.hpp>
  25. #include <boost/mysql/detail/network_algorithms/quit_connection.hpp>
  26. #include <boost/mysql/detail/network_algorithms/read_some_rows.hpp>
  27. #include <boost/mysql/detail/network_algorithms/start_query.hpp>
  28. #include <boost/mysql/detail/network_algorithms/start_statement_execution.hpp>
  29. #include <boost/asio/buffer.hpp>
  30. #include <boost/assert/source_location.hpp>
  31. #include <utility>
  32. // connect
  33. template <class Stream>
  34. template <class EndpointType>
  35. void boost::mysql::connection<Stream>::connect(
  36. const EndpointType& endpoint,
  37. const handshake_params& params,
  38. error_code& ec,
  39. diagnostics& diag
  40. )
  41. {
  42. detail::clear_errors(ec, diag);
  43. detail::connect(get_channel(), endpoint, params, ec, diag);
  44. }
  45. template <class Stream>
  46. template <class EndpointType>
  47. void boost::mysql::connection<Stream>::connect(const EndpointType& endpoint, const handshake_params& params)
  48. {
  49. detail::error_block blk;
  50. detail::connect(get_channel(), endpoint, params, blk.err, blk.diag);
  51. blk.check(BOOST_CURRENT_LOCATION);
  52. }
  53. template <class Stream>
  54. template <
  55. class EndpointType,
  56. BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  57. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  58. boost::mysql::connection<Stream>::async_connect(
  59. const EndpointType& endpoint,
  60. const handshake_params& params,
  61. diagnostics& diag,
  62. CompletionToken&& token
  63. )
  64. {
  65. return detail::async_connect(get_channel(), endpoint, params, diag, std::forward<CompletionToken>(token));
  66. }
  67. // handshake
  68. template <class Stream>
  69. void boost::mysql::connection<Stream>::handshake(
  70. const handshake_params& params,
  71. error_code& code,
  72. diagnostics& diag
  73. )
  74. {
  75. detail::clear_errors(code, diag);
  76. detail::handshake(get_channel(), params, code, diag);
  77. }
  78. template <class Stream>
  79. void boost::mysql::connection<Stream>::handshake(const handshake_params& params)
  80. {
  81. detail::error_block blk;
  82. handshake(params, blk.err, blk.diag);
  83. blk.check(BOOST_CURRENT_LOCATION);
  84. }
  85. template <class Stream>
  86. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  87. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  88. boost::mysql::connection<Stream>::async_handshake(
  89. const handshake_params& params,
  90. diagnostics& diag,
  91. CompletionToken&& token
  92. )
  93. {
  94. return detail::async_handshake(get_channel(), params, diag, std::forward<CompletionToken>(token));
  95. }
  96. template <class Stream>
  97. void boost::mysql::connection<Stream>::start_query(
  98. string_view query_string,
  99. execution_state& result,
  100. error_code& err,
  101. diagnostics& diag
  102. )
  103. {
  104. detail::clear_errors(err, diag);
  105. detail::start_query(get_channel(), query_string, result, err, diag);
  106. }
  107. template <class Stream>
  108. void boost::mysql::connection<Stream>::start_query(string_view query_string, execution_state& result)
  109. {
  110. detail::error_block blk;
  111. detail::start_query(get_channel(), query_string, result, blk.err, blk.diag);
  112. blk.check(BOOST_CURRENT_LOCATION);
  113. }
  114. template <class Stream>
  115. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  116. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  117. boost::mysql::connection<Stream>::async_start_query(
  118. string_view query_string,
  119. execution_state& result,
  120. diagnostics& diag,
  121. CompletionToken&& token
  122. )
  123. {
  124. return detail::async_start_query(
  125. get_channel(),
  126. query_string,
  127. result,
  128. diag,
  129. std::forward<CompletionToken>(token)
  130. );
  131. }
  132. template <class Stream>
  133. void boost::mysql::connection<Stream>::query(
  134. string_view query_string,
  135. results& result,
  136. error_code& err,
  137. diagnostics& diag
  138. )
  139. {
  140. detail::clear_errors(err, diag);
  141. detail::query(get_channel(), query_string, result, err, diag);
  142. }
  143. template <class Stream>
  144. void boost::mysql::connection<Stream>::query(string_view query_string, results& result)
  145. {
  146. detail::error_block blk;
  147. detail::query(get_channel(), query_string, result, blk.err, blk.diag);
  148. blk.check(BOOST_CURRENT_LOCATION);
  149. }
  150. template <class Stream>
  151. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  152. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  153. boost::mysql::connection<Stream>::async_query(
  154. string_view query_string,
  155. results& result,
  156. diagnostics& diag,
  157. CompletionToken&& token
  158. )
  159. {
  160. return detail::async_query(
  161. get_channel(),
  162. query_string,
  163. result,
  164. diag,
  165. std::forward<CompletionToken>(token)
  166. );
  167. }
  168. // Prepare statement
  169. template <class Stream>
  170. boost::mysql::statement boost::mysql::connection<Stream>::prepare_statement(
  171. string_view stmt,
  172. error_code& err,
  173. diagnostics& diag
  174. )
  175. {
  176. detail::clear_errors(err, diag);
  177. return detail::prepare_statement(get_channel(), stmt, err, diag);
  178. }
  179. template <class Stream>
  180. boost::mysql::statement boost::mysql::connection<Stream>::prepare_statement(string_view stmt)
  181. {
  182. detail::error_block blk;
  183. auto res = detail::prepare_statement(get_channel(), stmt, blk.err, blk.diag);
  184. blk.check(BOOST_CURRENT_LOCATION);
  185. return res;
  186. }
  187. template <class Stream>
  188. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::statement))
  189. CompletionToken>
  190. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code, boost::mysql::statement))
  191. boost::mysql::connection<Stream>::async_prepare_statement(
  192. string_view stmt,
  193. diagnostics& diag,
  194. CompletionToken&& token
  195. )
  196. {
  197. return detail::async_prepare_statement(get_channel(), stmt, diag, std::forward<CompletionToken>(token));
  198. }
  199. // execute statement
  200. template <class Stream>
  201. template <BOOST_MYSQL_FIELD_LIKE_TUPLE FieldLikeTuple, class>
  202. void boost::mysql::connection<Stream>::execute_statement(
  203. const statement& stmt,
  204. const FieldLikeTuple& params,
  205. results& result,
  206. error_code& err,
  207. diagnostics& diag
  208. )
  209. {
  210. detail::clear_errors(err, diag);
  211. detail::execute_statement(get_channel(), stmt, params, result, err, diag);
  212. }
  213. template <class Stream>
  214. template <BOOST_MYSQL_FIELD_LIKE_TUPLE FieldLikeTuple, class>
  215. void boost::mysql::connection<Stream>::execute_statement(
  216. const statement& stmt,
  217. const FieldLikeTuple& params,
  218. results& result
  219. )
  220. {
  221. detail::error_block blk;
  222. detail::execute_statement(get_channel(), stmt, params, result, blk.err, blk.diag);
  223. blk.check(BOOST_CURRENT_LOCATION);
  224. }
  225. template <class Stream>
  226. template <
  227. BOOST_MYSQL_FIELD_LIKE_TUPLE FieldLikeTuple,
  228. BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken,
  229. class>
  230. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  231. boost::mysql::connection<Stream>::async_execute_statement(
  232. const statement& stmt,
  233. FieldLikeTuple&& params,
  234. results& result,
  235. diagnostics& diag,
  236. CompletionToken&& token
  237. )
  238. {
  239. return detail::async_execute_statement(
  240. get_channel(),
  241. stmt,
  242. std::forward<FieldLikeTuple>(params),
  243. result,
  244. diag,
  245. std::forward<CompletionToken>(token)
  246. );
  247. }
  248. template <class Stream>
  249. template <BOOST_MYSQL_FIELD_LIKE_TUPLE FieldLikeTuple, class>
  250. void boost::mysql::connection<Stream>::start_statement_execution(
  251. const statement& stmt,
  252. const FieldLikeTuple& params,
  253. execution_state& result,
  254. error_code& err,
  255. diagnostics& diag
  256. )
  257. {
  258. detail::clear_errors(err, diag);
  259. detail::start_statement_execution(get_channel(), stmt, params, result, err, diag);
  260. }
  261. template <class Stream>
  262. template <BOOST_MYSQL_FIELD_LIKE_TUPLE FieldLikeTuple, class>
  263. void boost::mysql::connection<Stream>::start_statement_execution(
  264. const statement& stmt,
  265. const FieldLikeTuple& params,
  266. execution_state& result
  267. )
  268. {
  269. detail::error_block blk;
  270. detail::start_statement_execution(get_channel(), stmt, params, result, blk.err, blk.diag);
  271. blk.check(BOOST_CURRENT_LOCATION);
  272. }
  273. template <class Stream>
  274. template <
  275. BOOST_MYSQL_FIELD_LIKE_TUPLE FieldLikeTuple,
  276. BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken,
  277. class>
  278. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  279. boost::mysql::connection<Stream>::async_start_statement_execution(
  280. const statement& stmt,
  281. FieldLikeTuple&& params,
  282. execution_state& result,
  283. diagnostics& diag,
  284. CompletionToken&& token
  285. )
  286. {
  287. return detail::async_start_statement_execution(
  288. get_channel(),
  289. stmt,
  290. std::forward<FieldLikeTuple>(params),
  291. result,
  292. diag,
  293. std::forward<CompletionToken>(token)
  294. );
  295. }
  296. // Execute statement, with iterators
  297. template <class Stream>
  298. template <BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR FieldViewFwdIterator>
  299. void boost::mysql::connection<Stream>::start_statement_execution(
  300. const statement& stmt,
  301. FieldViewFwdIterator params_first,
  302. FieldViewFwdIterator params_last,
  303. execution_state& result,
  304. error_code& err,
  305. diagnostics& diag
  306. )
  307. {
  308. detail::clear_errors(err, diag);
  309. detail::start_statement_execution(get_channel(), stmt, params_first, params_last, result, err, diag);
  310. }
  311. template <class Stream>
  312. template <BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR FieldViewFwdIterator>
  313. void boost::mysql::connection<Stream>::start_statement_execution(
  314. const statement& stmt,
  315. FieldViewFwdIterator params_first,
  316. FieldViewFwdIterator params_last,
  317. execution_state& result
  318. )
  319. {
  320. detail::error_block blk;
  321. detail::start_statement_execution(
  322. get_channel(),
  323. stmt,
  324. params_first,
  325. params_last,
  326. result,
  327. blk.err,
  328. blk.diag
  329. );
  330. blk.check(BOOST_CURRENT_LOCATION);
  331. }
  332. template <class Stream>
  333. template <
  334. BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR FieldViewFwdIterator,
  335. BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  336. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  337. boost::mysql::connection<Stream>::async_start_statement_execution(
  338. const statement& stmt,
  339. FieldViewFwdIterator params_first,
  340. FieldViewFwdIterator params_last,
  341. execution_state& result,
  342. diagnostics& diag,
  343. CompletionToken&& token
  344. )
  345. {
  346. return detail::async_start_statement_execution(
  347. get_channel(),
  348. stmt,
  349. params_first,
  350. params_last,
  351. result,
  352. diag,
  353. std::forward<CompletionToken>(token)
  354. );
  355. }
  356. // Close statement
  357. template <class Stream>
  358. void boost::mysql::connection<Stream>::close_statement(
  359. const statement& stmt,
  360. error_code& code,
  361. diagnostics& diag
  362. )
  363. {
  364. detail::clear_errors(code, diag);
  365. detail::close_statement(get_channel(), stmt, code, diag);
  366. }
  367. template <class Stream>
  368. void boost::mysql::connection<Stream>::close_statement(const statement& stmt)
  369. {
  370. detail::error_block blk;
  371. detail::close_statement(get_channel(), stmt, blk.err, blk.diag);
  372. blk.check(BOOST_CURRENT_LOCATION);
  373. }
  374. template <class Stream>
  375. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  376. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  377. boost::mysql::connection<Stream>::async_close_statement(
  378. const statement& stmt,
  379. diagnostics& diag,
  380. CompletionToken&& token
  381. )
  382. {
  383. return detail::async_close_statement(get_channel(), stmt, diag, std::forward<CompletionToken>(token));
  384. }
  385. // read some rows
  386. template <class Stream>
  387. boost::mysql::rows_view boost::mysql::connection<Stream>::read_some_rows(
  388. execution_state& st,
  389. error_code& err,
  390. diagnostics& diag
  391. )
  392. {
  393. detail::clear_errors(err, diag);
  394. return detail::read_some_rows(get_channel(), st, err, diag);
  395. }
  396. template <class Stream>
  397. boost::mysql::rows_view boost::mysql::connection<Stream>::read_some_rows(execution_state& st)
  398. {
  399. detail::error_block blk;
  400. rows_view res = detail::read_some_rows(get_channel(), st, blk.err, blk.diag);
  401. blk.check(BOOST_CURRENT_LOCATION);
  402. return res;
  403. }
  404. template <class Stream>
  405. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::rows_view))
  406. CompletionToken>
  407. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code, boost::mysql::rows_view))
  408. boost::mysql::connection<Stream>::async_read_some_rows(
  409. execution_state& st,
  410. diagnostics& diag,
  411. CompletionToken&& token
  412. )
  413. {
  414. return detail::async_read_some_rows(get_channel(), st, diag, std::forward<CompletionToken>(token));
  415. }
  416. // ping
  417. template <class Stream>
  418. void boost::mysql::connection<Stream>::ping(error_code& err, diagnostics& diag)
  419. {
  420. detail::clear_errors(err, diag);
  421. detail::ping(get_channel(), err, diag);
  422. }
  423. template <class Stream>
  424. void boost::mysql::connection<Stream>::ping()
  425. {
  426. detail::error_block blk;
  427. detail::ping(get_channel(), blk.err, blk.diag);
  428. blk.check(BOOST_CURRENT_LOCATION);
  429. }
  430. template <class Stream>
  431. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  432. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  433. boost::mysql::connection<Stream>::async_ping(diagnostics& diag, CompletionToken&& token)
  434. {
  435. return detail::async_ping(get_channel(), diag, std::forward<CompletionToken>(token));
  436. }
  437. // Close
  438. template <class Stream>
  439. void boost::mysql::connection<Stream>::close(error_code& err, diagnostics& diag)
  440. {
  441. detail::clear_errors(err, diag);
  442. detail::close_connection(get_channel(), err, diag);
  443. }
  444. template <class Stream>
  445. void boost::mysql::connection<Stream>::close()
  446. {
  447. detail::error_block blk;
  448. detail::close_connection(get_channel(), blk.err, blk.diag);
  449. blk.check(BOOST_CURRENT_LOCATION);
  450. }
  451. template <class Stream>
  452. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  453. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  454. boost::mysql::connection<Stream>::async_close(diagnostics& diag, CompletionToken&& token)
  455. {
  456. return detail::async_close_connection(get_channel(), diag, std::forward<CompletionToken>(token));
  457. }
  458. // quit
  459. template <class Stream>
  460. void boost::mysql::connection<Stream>::quit(error_code& err, diagnostics& diag)
  461. {
  462. detail::clear_errors(err, diag);
  463. detail::quit_connection(get_channel(), err, diag);
  464. }
  465. template <class Stream>
  466. void boost::mysql::connection<Stream>::quit()
  467. {
  468. detail::error_block blk;
  469. detail::quit_connection(get_channel(), blk.err, blk.diag);
  470. blk.check(BOOST_CURRENT_LOCATION);
  471. }
  472. template <class Stream>
  473. template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken>
  474. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(boost::mysql::error_code))
  475. boost::mysql::connection<Stream>::async_quit(diagnostics& diag, CompletionToken&& token)
  476. {
  477. return detail::async_quit_connection(get_channel(), diag, std::forward<CompletionToken>(token));
  478. }
  479. struct boost::mysql::detail::connection_access
  480. {
  481. // Exposed for testing
  482. template <class Stream>
  483. static channel<Stream>& get_channel(connection<Stream>& conn) noexcept
  484. {
  485. return conn.get_channel();
  486. }
  487. };
  488. #endif