MySQL 8.0.33
Source Code Documentation
classic_protocol_codec_message.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019, 2023, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24
25#ifndef MYSQL_ROUTER_CLASSIC_PROTOCOL_CODEC_MESSAGE_H_
26#define MYSQL_ROUTER_CLASSIC_PROTOCOL_CODEC_MESSAGE_H_
27
28#include <cstddef> // size_t
29#include <cstdint> // uint8_t
30#include <system_error> // error_code
31#include <utility> // move
32
41
42namespace classic_protocol {
43
44/**
45 * codec for server Greeting message.
46 *
47 * 3.21 (protocol_version 9)
48 *
49 * FixedInt<1> protocol_version [0x09]
50 * NulTermString server_version
51 * FixedInt<4> connection_id
52 * NulTermString auth-method-data
53 *
54 * 3.21 and later (protocol_version 10)
55 *
56 * FixedInt<1> protocol_version [0x0a]
57 * NulTermString server_version
58 * FixedInt<4> connection_id
59 * NulTermString auth-method-data
60 * FixedInt<2> capabilities (lower 16bit)
61 *
62 * 3.23 and later add:
63 *
64 * FixedInt<1> collation
65 * FixedInt<2> status flags
66 * FixedInt<2> capabilities (upper 16bit)
67 * FixedInt<1> length of auth-method-data or 0x00
68 * String<10> reserved
69 *
70 * if capabilities.secure_connection is set, adds
71 *
72 * String<len> auth-method-data-2
73 *
74 * if capabilities.plugin_auth is set, adds
75 *
76 * NulTermString auth-method
77 */
78template <bool Borrowed>
79class Codec<borrowable::message::server::Greeting<Borrowed>>
80 : public impl::EncodeBase<
81 Codec<borrowable::message::server::Greeting<Borrowed>>> {
82 template <class Accumulator>
83 constexpr auto accumulate_fields(Accumulator &&accu) const {
84 namespace bw = borrowable::wire;
85
86 if (v_.protocol_version() == 0x09) {
87 return accu.step(bw::FixedInt<1>(v_.protocol_version()))
88 .step(bw::NulTermString<Borrowed>(v_.version()))
89 .step(bw::FixedInt<4>(v_.connection_id()))
90 .step(bw::NulTermString<Borrowed>(v_.auth_method_data().substr(0, 8)))
91 .result();
92 } else {
93 uint8_t auth_method_data_size{0};
95 auth_method_data_size = v_.auth_method_data().size();
96 }
97
98 accu.step(bw::FixedInt<1>(v_.protocol_version()))
99 .step(bw::NulTermString<Borrowed>(v_.version()))
100 .step(bw::FixedInt<4>(v_.connection_id()))
101 .step(bw::NulTermString<Borrowed>(v_.auth_method_data().substr(0, 8)))
102 .step(bw::FixedInt<2>(v_.capabilities().to_ulong() & 0xffff));
103
104 if ((v_.capabilities().to_ullong() >= (1 << 16)) ||
105 v_.status_flags().any() || (v_.collation() != 0)) {
106 accu.step(bw::FixedInt<1>(v_.collation()))
107 .step(bw::FixedInt<2>(v_.status_flags().to_ulong()))
108 .step(
109 bw::FixedInt<2>((v_.capabilities().to_ulong() >> 16) & 0xffff))
110 .step(bw::FixedInt<1>(auth_method_data_size))
111 .step(bw::String<Borrowed>(std::string(10, '\0')));
112 if (v_.capabilities()
114 accu.step(bw::String<Borrowed>(v_.auth_method_data().substr(8)));
115 if (v_.capabilities()
117 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_name()));
118 }
119 }
120 }
121 return accu.result();
122 }
123 }
124
125 public:
126 using value_type = borrowable::message::server::Greeting<Borrowed>;
128
129 friend __base;
130
132 : __base(caps), v_{std::move(v)} {}
133
137
138 namespace bw = borrowable::wire;
139
140 // proto-version
141 auto protocol_version_res = accu.template step<bw::FixedInt<1>>();
142 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
143
144 if (protocol_version_res->value() != 0x09 &&
145 protocol_version_res->value() != 0x0a) {
147 }
148
149 auto version_res = accu.template step<bw::NulTermString<Borrowed>>();
150 auto connection_id_res = accu.template step<bw::FixedInt<4>>();
151 auto auth_method_data_res =
152 accu.template step<bw::NulTermString<Borrowed>>();
153
154 if (protocol_version_res->value() == 0x09) {
155 return std::make_pair(
156 accu.result().value(),
157 value_type(protocol_version_res->value(), version_res->value(),
158 connection_id_res->value(), auth_method_data_res->value(),
159 0, 0, 0, {}));
160 } else {
161 // capabilities are split into two a lower-2-byte part and a
162 // higher-2-byte
163 auto cap_lower_res = accu.template step<bw::FixedInt<2>>();
164 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
165
166 // 3.21.x doesn't send more.
167 if (buffer_size(buffer) <= accu.result().value()) {
168 return std::make_pair(
169 accu.result().value(),
170 value_type(protocol_version_res->value(), version_res->value(),
171 connection_id_res->value(),
172 auth_method_data_res->value(), cap_lower_res->value(),
173 0x0, 0x0, {}));
174 }
175
176 // if there's more data
177 auto collation_res = accu.template step<bw::FixedInt<1>>();
178 auto status_flags_res = accu.template step<bw::FixedInt<2>>();
179 auto cap_hi_res = accu.template step<bw::FixedInt<2>>();
180
181 // before we use cap_hi|cap_low check they don't have an error
182 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
183
185 cap_lower_res->value() | (cap_hi_res->value() << 16));
186
187 size_t auth_method_data_len{13};
189 auto auth_method_data_len_res = accu.template step<bw::FixedInt<1>>();
190 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
191
192 // should be 21, but least 8
193 if (auth_method_data_len_res->value() < 8) {
196 }
197 auth_method_data_len = auth_method_data_len_res->value() - 8;
198 } else {
199 accu.template step<void>(1); // should be 0 ...
200 }
201
202 accu.template step<void>(10); // skip the filler
203
205 auth_method_data_2_res;
207 auth_method_res;
208 if (capabilities
210 // auth-method-data
211 auth_method_data_2_res =
212 accu.template step<bw::String<Borrowed>>(auth_method_data_len);
213
215 // auth_method
216 auth_method_res = accu.template step<bw::NulTermString<Borrowed>>();
217 }
218 }
219
220 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
221
222 return std::make_pair(
223 accu.result().value(),
225 protocol_version_res->value(), version_res->value(),
226 connection_id_res->value(),
227 auth_method_data_res->value() + auth_method_data_2_res->value(),
228 capabilities, collation_res->value(), status_flags_res->value(),
229 auth_method_res->value()));
230 }
231 }
232
233 private:
235};
236
237/**
238 * codec for server::AuthMethodSwitch message.
239 */
240template <bool Borrowed>
241class Codec<borrowable::message::server::AuthMethodSwitch<Borrowed>>
242 : public impl::EncodeBase<
243 Codec<borrowable::message::server::AuthMethodSwitch<Borrowed>>> {
244 template <class Accumulator>
245 constexpr auto accumulate_fields(Accumulator &&accu) const {
246 namespace bw = borrowable::wire;
247
248 accu.step(bw::FixedInt<1>(cmd_byte()));
249
251 accu.step(bw::NulTermString<Borrowed>(v_.auth_method()))
252 .step(bw::String<Borrowed>(v_.auth_method_data()));
253 }
254
255 return accu.result();
256 }
257
258 public:
259 using value_type = borrowable::message::server::AuthMethodSwitch<Borrowed>;
261
262 friend __base;
263
265 : __base(caps), v_{std::move(v)} {}
266
267 static constexpr uint8_t cmd_byte() noexcept { return 0xfe; }
268
272
273 namespace bw = borrowable::wire;
274
275 // proto-version
276 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
277 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
278
279 if (cmd_byte_res->value() != cmd_byte()) {
281 }
282
284 return std::make_pair(accu.result().value(), value_type());
285 }
286
287 auto auth_method_res = accu.template step<bw::NulTermString<Borrowed>>();
288 auto auth_method_data_res = accu.template step<bw::String<Borrowed>>();
289
290 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
291
292 return std::make_pair(
293 accu.result().value(),
294 value_type(auth_method_res->value(), auth_method_data_res->value()));
295 }
296
297 private:
299};
300
301/**
302 * codec for server::AuthMethodData message.
303 */
304template <bool Borrowed>
305class Codec<borrowable::message::server::AuthMethodData<Borrowed>>
306 : public impl::EncodeBase<
307 Codec<borrowable::message::server::AuthMethodData<Borrowed>>> {
308 template <class Accumulator>
309 constexpr auto accumulate_fields(Accumulator &&accu) const {
310 namespace bw = borrowable::wire;
311
312 return accu.step(bw::FixedInt<1>(cmd_byte()))
313 .step(bw::String<Borrowed>(v_.auth_method_data()))
314 .result();
315 }
316
317 public:
318 using value_type = borrowable::message::server::AuthMethodData<Borrowed>;
320
321 friend __base;
322
324 : __base(caps), v_{std::move(v)} {}
325
326 static constexpr uint8_t cmd_byte() noexcept { return 0x01; }
327
331
332 namespace bw = borrowable::wire;
333
334 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
335 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
336
337 if (cmd_byte_res->value() != cmd_byte()) {
339 }
340 auto auth_method_data_res = accu.template step<bw::String<Borrowed>>();
341
342 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
343
344 return std::make_pair(accu.result().value(),
345 value_type(auth_method_data_res->value()));
346 }
347
348 private:
350};
351
352/**
353 * codec for server-side Ok message.
354 */
355template <bool Borrowed>
356class Codec<borrowable::message::server::Ok<Borrowed>>
357 : public impl::EncodeBase<
358 Codec<borrowable::message::server::Ok<Borrowed>>> {
359 template <class Accumulator>
360 constexpr auto accumulate_fields(Accumulator &&accu) const {
361 namespace bw = borrowable::wire;
362
363 accu.step(bw::FixedInt<1>(cmd_byte()))
364 .step(bw::VarInt(v_.affected_rows()))
365 .step(bw::VarInt(v_.last_insert_id()));
366
367 if (this->caps()[capabilities::pos::protocol_41] ||
368 this->caps()[capabilities::pos::transactions]) {
369 accu.step(bw::FixedInt<2>(v_.status_flags().to_ulong()));
370 if (this->caps().test(capabilities::pos::protocol_41)) {
371 accu.step(bw::FixedInt<2>(v_.warning_count()));
372 }
373 }
374
375 if (this->caps().test(capabilities::pos::session_track)) {
376 accu.step(bw::VarString<Borrowed>(v_.message()));
377 if (v_.status_flags().test(status::pos::session_state_changed)) {
378 accu.step(bw::VarString<Borrowed>(v_.session_changes()));
379 }
380 } else {
381 accu.step(bw::String<Borrowed>(v_.message()));
382 }
383
384 return accu.result();
385 }
386
387 public:
388 using value_type = borrowable::message::server::Ok<Borrowed>;
390
391 friend __base;
392
394 : __base(caps), v_{std::move(v)} {}
395
396 static constexpr uint8_t cmd_byte() noexcept { return 0x00; }
397
398 /**
399 * decode a server::Ok message from a buffer-sequence.
400 *
401 * precondition:
402 * - input starts with cmd_byte()
403 *
404 * @param buffer input buffser sequence
405 * @param caps protocol capabilities
406 *
407 * @retval std::pair<size_t, message::server::Ok> on success, with bytes
408 * processed
409 * @retval codec_errc::invalid_input if preconditions aren't met
410 * @retval codec_errc::not_enough_input not enough data to parse the whole
411 * message
412 */
416
417 namespace bw = borrowable::wire;
418
419 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
420 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
421
422 if (cmd_byte_res->value() != cmd_byte()) {
424 }
425
426 auto affected_rows_res = accu.template step<bw::VarInt>();
427 auto last_insert_id_res = accu.template step<bw::VarInt>();
428
429 stdx::expected<bw::FixedInt<2>, std::error_code> status_flags_res(0);
430 stdx::expected<bw::FixedInt<2>, std::error_code> warning_count_res(0);
433 status_flags_res = accu.template step<bw::FixedInt<2>>();
435 warning_count_res = accu.template step<bw::FixedInt<2>>();
436 }
437 }
438
439 stdx::expected<bw::String<Borrowed>, std::error_code> message_res;
441 session_changes_res;
443 // if there is more data.
444 const auto var_message_res =
445 accu.template try_step<bw::VarString<Borrowed>>();
446 if (var_message_res) {
447 // set the message from the var-string
448 message_res = var_message_res.value();
449 }
450
451 if (status_flags_res->value() &
453 session_changes_res = accu.template step<bw::VarString<Borrowed>>();
454 }
455 } else {
456 message_res = accu.template step<bw::String<Borrowed>>();
457 }
458
459 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
460
461 return std::make_pair(
462 accu.result().value(),
463 value_type(affected_rows_res->value(), last_insert_id_res->value(),
464 status_flags_res->value(), warning_count_res->value(),
465 message_res->value(), session_changes_res->value()));
466 }
467
468 private:
470};
471
472/**
473 * codec for server-side Eof message.
474 *
475 * Eof message is encoded differently dependending on protocol capabiltiies,
476 * but always starts with:
477 *
478 * - 0xef
479 *
480 * If capabilities has text_result_with_session_tracking, it is followed by
481 * - [rest of Ok packet]
482 *
483 * otherwise, if capabilities has protocol_41
484 * - FixedInt<2> warning-count
485 * - FixedInt<2> status flags
486 *
487 * otherwise
488 * - nothing
489 */
490template <bool Borrowed>
491class Codec<borrowable::message::server::Eof<Borrowed>>
492 : public impl::EncodeBase<
493 Codec<borrowable::message::server::Eof<Borrowed>>> {
494 template <class Accumulator>
495 constexpr auto accumulate_fields(Accumulator &&accu) const {
496 namespace bw = borrowable::wire;
497
498 accu.step(bw::FixedInt<1>(cmd_byte()));
499
500 auto shared_caps = this->caps();
501
502 if (shared_caps.test(
504 accu.step(bw::VarInt(v_.affected_rows()))
505 .step(bw::VarInt(v_.last_insert_id()));
506
507 if (shared_caps[capabilities::pos::protocol_41] ||
508 shared_caps[capabilities::pos::transactions]) {
509 accu.step(bw::FixedInt<2>(v_.status_flags().to_ulong()));
510 if (shared_caps[capabilities::pos::protocol_41]) {
511 accu.step(bw::FixedInt<2>(v_.warning_count()));
512 }
513 }
514
515 if (shared_caps[capabilities::pos::session_track]) {
516 if (!v_.message().empty() ||
517 v_.status_flags()[status::pos::session_state_changed]) {
518 // only write message and session-changes if both of them aren't
519 // empty.
520 accu.step(bw::VarString<Borrowed>(v_.message()));
521 if (v_.status_flags()[status::pos::session_state_changed]) {
522 accu.step(bw::VarString<Borrowed>(v_.session_changes()));
523 }
524 }
525 } else {
526 accu.step(bw::String<Borrowed>(v_.message()));
527 }
528 } else if (shared_caps[capabilities::pos::protocol_41]) {
529 accu.step(bw::FixedInt<2>(v_.warning_count()))
530 .step(bw::FixedInt<2>(v_.status_flags().to_ulong()));
531 }
532
533 return accu.result();
534 }
535
536 public:
537 using value_type = borrowable::message::server::Eof<Borrowed>;
539
540 friend __base;
541
543 : __base(caps), v_{std::move(v)} {}
544
545 static constexpr uint8_t cmd_byte() noexcept { return 0xfe; }
546
547 /**
548 * decode a server::Eof message from a buffer-sequence.
549 *
550 * capabilities checked:
551 * - protocol_41
552 * - text_resultset_with_session_tracking
553 *
554 * precondition:
555 * - input starts with cmd_byte()
556 *
557 * @param buffer input buffser sequence
558 * @param caps protocol capabilities
559 *
560 * @retval std::pair<size_t, message::server::Eof> on success, with bytes
561 * processed
562 * @retval codec_errc::invalid_input if preconditions aren't met
563 * @retval codec_errc::not_enough_input not enough data to parse the whole
564 * message
565 */
569
570 namespace bw = borrowable::wire;
571
572 const auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
573 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
574
575 if (cmd_byte_res->value() != cmd_byte()) {
577 }
578
580 const auto affected_rows_res = accu.template step<bw::VarInt>();
581 const auto last_insert_id_res = accu.template step<bw::VarInt>();
582
583 stdx::expected<bw::FixedInt<2>, std::error_code> status_flags_res(0);
584 stdx::expected<bw::FixedInt<2>, std::error_code> warning_count_res(0);
587 status_flags_res = accu.template step<bw::FixedInt<2>>();
589 warning_count_res = accu.template step<bw::FixedInt<2>>();
590 }
591 }
592
593 stdx::expected<bw::String<Borrowed>, std::error_code> message_res;
595 session_state_info_res;
597 // when session-track is supported, the 'message' part is a VarString.
598 // But only if there is actually session-data and the message has data.
599 const auto var_message_res =
600 accu.template try_step<bw::VarString<Borrowed>>();
601 if (var_message_res) {
602 // set the message from the var-string
603 message_res = var_message_res.value();
604 }
605
606 if (status_flags_res->value() &
608 session_state_info_res =
609 accu.template step<bw::VarString<Borrowed>>();
610 }
611 } else {
612 message_res = accu.template step<bw::String<Borrowed>>();
613 }
614
615 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
616
617 return std::make_pair(
618 accu.result().value(),
619 value_type(affected_rows_res->value(), last_insert_id_res->value(),
620 status_flags_res->value(), warning_count_res->value(),
621 message_res->value(), session_state_info_res->value()));
622 } else if (caps[capabilities::pos::protocol_41]) {
623 const auto warning_count_res = accu.template step<bw::FixedInt<2>>();
624 const auto status_flags_res = accu.template step<bw::FixedInt<2>>();
625
626 return std::make_pair(
627 accu.result().value(),
628 value_type(status_flags_res->value(), warning_count_res->value()));
629 } else {
630 return std::make_pair(accu.result().value(), value_type());
631 }
632 }
633
634 private:
636};
637
638/**
639 * codec for Error message.
640 *
641 * note: Format overview:
642 *
643 * 3.21: protocol_version <= 9 [not supported]
644 *
645 * FixedInt<1> 0xff
646 * String message
647 *
648 * 3.21: protocol_version > 9
649 *
650 * FixedInt<1> 0xff
651 * FixedInt<2> error_code
652 * String message
653 *
654 * 4.1 and later:
655 *
656 * FixedInt<1> 0xff
657 * FixedInt<2> error_code
658 * '#'
659 * String<5> sql_state
660 * String message
661 */
662template <bool Borrowed>
663class Codec<borrowable::message::server::Error<Borrowed>>
664 : public impl::EncodeBase<
665 Codec<borrowable::message::server::Error<Borrowed>>> {
666 template <class Accumulator>
667 constexpr auto accumulate_fields(Accumulator &&accu) const {
668 namespace bw = borrowable::wire;
669
670 accu.step(bw::FixedInt<1>(cmd_byte()))
671 .step(bw::FixedInt<2>(v_.error_code()));
672 if (this->caps()[capabilities::pos::protocol_41]) {
673 accu.step(bw::FixedInt<1>('#'))
674 .step(bw::String<Borrowed>(v_.sql_state()));
675 }
676
677 return accu.step(bw::String<Borrowed>(v_.message())).result();
678 }
679
680 public:
681 using value_type = borrowable::message::server::Error<Borrowed>;
683
684 friend __base;
685
687 : __base(caps), v_{std::move(v)} {}
688
689 static constexpr uint8_t cmd_byte() { return 0xff; }
690
691 static constexpr size_t max_size() noexcept {
692 return std::numeric_limits<size_t>::max();
693 }
694
698
699 namespace bw = borrowable::wire;
700
701 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
702 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
703
704 if (cmd_byte_res->value() != cmd_byte()) {
706 }
707
708 // decode all fields, check result later before they are used.
709 auto error_code_res = accu.template step<bw::FixedInt<2>>();
710 stdx::expected<bw::String<Borrowed>, std::error_code> sql_state_res;
712 auto sql_state_hash_res = accu.template step<bw::FixedInt<1>>();
713 sql_state_res = accu.template step<bw::String<Borrowed>>(5);
714 }
715 auto message_res = accu.template step<bw::String<Borrowed>>();
716
717 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
718
719 return std::make_pair(
720 accu.result().value(),
721 value_type(error_code_res->value(), message_res->value(),
722 sql_state_res->value()));
723 }
724
725 private:
727};
728
729/**
730 * codec for ColumnCount message.
731 */
732template <>
734 : public impl::EncodeBase<Codec<borrowable::message::server::ColumnCount>> {
735 template <class Accumulator>
736 constexpr auto accumulate_fields(Accumulator &&accu) const {
737 namespace bw = borrowable::wire;
738
739 return accu.step(bw::VarInt(v_.count())).result();
740 }
741
742 public:
745
746 friend __base;
747
749 : __base(caps), v_{std::move(v)} {}
750
751 static constexpr size_t max_size() noexcept {
752 return std::numeric_limits<size_t>::max();
753 }
754
758
759 namespace bw = borrowable::wire;
760
761 auto count_res = accu.template step<bw::VarInt>();
762 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
763
764 return std::make_pair(accu.result().value(),
765 value_type(count_res->value()));
766 }
767
768 private:
770};
771
772/**
773 * Codec of ColumnMeta.
774 *
775 * capabilities checked:
776 * - protocol_41
777 */
778template <bool Borrowed>
779class Codec<borrowable::message::server::ColumnMeta<Borrowed>>
780 : public impl::EncodeBase<
781 Codec<borrowable::message::server::ColumnMeta<Borrowed>>> {
782 template <class Accumulator>
783 auto accumulate_fields(Accumulator &&accu) const {
784 namespace bw = borrowable::wire;
785
786 if (!this->caps()[capabilities::pos::protocol_41]) {
787 accu.step(bw::VarString<Borrowed>(v_.table()))
788 .step(bw::VarString<Borrowed>(v_.name()))
789 .step(bw::VarInt(3))
790 .step(bw::FixedInt<3>(v_.column_length()))
791 .step(bw::VarInt(1))
792 .step(bw::FixedInt<1>(v_.type()));
793
794 if (this->caps()[capabilities::pos::long_flag]) {
795 accu.step(bw::VarInt(3))
796 .step(bw::FixedInt<2>(v_.flags().to_ulong()))
797 .step(bw::FixedInt<1>(v_.decimals()));
798 } else {
799 accu.step(bw::VarInt(2))
800 .step(bw::FixedInt<1>(v_.flags().to_ulong()))
801 .step(bw::FixedInt<1>(v_.decimals()));
802 }
803
804 return accu.result();
805 } else {
806 return accu.step(bw::VarString<Borrowed>(v_.catalog()))
807 .step(bw::VarString<Borrowed>(v_.schema()))
808 .step(bw::VarString<Borrowed>(v_.table()))
809 .step(bw::VarString<Borrowed>(v_.orig_table()))
810 .step(bw::VarString<Borrowed>(v_.name()))
811 .step(bw::VarString<Borrowed>(v_.orig_name()))
812 .step(bw::VarInt(12))
813 .step(bw::FixedInt<2>(v_.collation()))
814 .step(bw::FixedInt<4>(v_.column_length()))
815 .step(bw::FixedInt<1>(v_.type()))
816 .step(bw::FixedInt<2>(v_.flags().to_ulong()))
817 .step(bw::FixedInt<1>(v_.decimals()))
818 .step(bw::FixedInt<2>(0))
819 .result();
820 }
821 }
822
823 public:
824 using value_type = borrowable::message::server::ColumnMeta<Borrowed>;
826
827 friend __base;
828
830 : __base(caps), v_{std::move(v)} {}
831
832 static size_t max_size() noexcept {
833 return std::numeric_limits<size_t>::max();
834 }
835
839
840 namespace bw = borrowable::wire;
841
843 // 3.2x protocol used up to 4.0.x
844
845 // bit-size of the 'flags' field
846 const uint8_t flags_size = caps[capabilities::pos::long_flag] ? 2 : 1;
847
848 const auto table_res = accu.template step<bw::VarString<Borrowed>>();
849 const auto name_res = accu.template step<bw::VarString<Borrowed>>();
850
851 const auto column_length_len_res = accu.template step<bw::VarInt>();
852 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
853
854 if (column_length_len_res->value() != 3) {
857 }
858
859 const auto column_length_res = accu.template step<bw::FixedInt<3>>();
860 const auto type_len_res = accu.template step<bw::VarInt>();
861 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
862
863 if (type_len_res->value() != 1) {
866 }
867
868 const auto type_res = accu.template step<bw::FixedInt<1>>();
869 const auto flags_and_decimals_len_res = accu.template step<bw::VarInt>();
870 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
871
872 if (flags_and_decimals_len_res->value() != flags_size + 1) {
875 }
876
877 stdx::expected<bw::FixedInt<3>, std::error_code> flags_and_decimals_res(
878 0);
879 if (flags_size == 2) {
880 flags_and_decimals_res = accu.template step<bw::FixedInt<3>>();
881 } else {
882 const auto small_flags_and_decimals_res =
883 accu.template step<bw::FixedInt<2>>();
884 if (small_flags_and_decimals_res) {
885 flags_and_decimals_res =
886 bw::FixedInt<3>(small_flags_and_decimals_res->value());
887 }
888 }
889
890 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
891
892 const uint16_t flags =
893 flags_and_decimals_res->value() & ((1 << (flags_size * 8)) - 1);
894 const uint8_t decimals =
895 flags_and_decimals_res->value() >> (flags_size * 8);
896
897 return std::make_pair(
898 accu.result().value(),
899 value_type({}, {}, table_res->value(), {}, name_res->value(), {}, {},
900 column_length_res->value(), type_res->value(), flags,
901 decimals));
902 } else {
903 const auto catalog_res = accu.template step<bw::VarString<Borrowed>>();
904 const auto schema_res = accu.template step<bw::VarString<Borrowed>>();
905 const auto table_res = accu.template step<bw::VarString<Borrowed>>();
906 const auto orig_table_res = accu.template step<bw::VarString<Borrowed>>();
907 const auto name_res = accu.template step<bw::VarString<Borrowed>>();
908 const auto orig_name_res = accu.template step<bw::VarString<Borrowed>>();
909
910 /* next is a collection of fields which is wrapped inside a varstring of
911 * 12-bytes size */
912 const auto other_len_res = accu.template step<bw::VarInt>();
913
914 if (other_len_res->value() != 12) {
917 }
918
919 const auto collation_res = accu.template step<bw::FixedInt<2>>();
920 const auto column_length_res = accu.template step<bw::FixedInt<4>>();
921 const auto type_res = accu.template step<bw::FixedInt<1>>();
922 const auto flags_res = accu.template step<bw::FixedInt<2>>();
923 const auto decimals_res = accu.template step<bw::FixedInt<1>>();
924
925 accu.template step<void>(2); // fillers
926
927 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
928
929 return std::make_pair(
930 accu.result().value(),
931 value_type(catalog_res->value(), schema_res->value(),
932 table_res->value(), orig_table_res->value(),
933 name_res->value(), orig_name_res->value(),
934 collation_res->value(), column_length_res->value(),
935 type_res->value(), flags_res->value(),
936 decimals_res->value()));
937 }
938 }
939
940 private:
942};
943
944/**
945 * codec for server's SendFileRequest response.
946 *
947 * sent as response after client::Query
948 *
949 * layout:
950 *
951 * 0xfb<filename>
952 */
953template <bool Borrowed>
954class Codec<borrowable::message::server::SendFileRequest<Borrowed>>
955 : public impl::EncodeBase<
956 Codec<borrowable::message::server::SendFileRequest<Borrowed>>> {
957 template <class Accumulator>
958 constexpr auto accumulate_fields(Accumulator &&accu) const {
959 namespace bw = borrowable::wire;
960
961 return accu.step(bw::FixedInt<1>(cmd_byte()))
962 .step(bw::String<Borrowed>(v_.filename()))
963 .result();
964 }
965
966 public:
967 using value_type = borrowable::message::server::SendFileRequest<Borrowed>;
969
970 friend __base;
971
973 : __base(caps), v_{std::move(v)} {}
974
975 static constexpr uint8_t cmd_byte() noexcept { return 0xfb; }
976
980
981 namespace bw = borrowable::wire;
982
983 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
984 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
985
986 if (cmd_byte_res->value() != cmd_byte()) {
988 }
989
990 auto filename_res = accu.template step<bw::String<Borrowed>>();
991 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
992
993 return std::make_pair(accu.result().value(),
994 value_type(filename_res->value()));
995 }
996
997 private:
999};
1000
1001/**
1002 * codec for server::StmtPrepareOk message.
1003 *
1004 * format:
1005 *
1006 * - FixedInt<1> == 0x00 [ok]
1007 * - FixedInt<4> stmt-id
1008 * - FixedInt<2> column-count
1009 * - FixedInt<2> param-count
1010 * - FixedInt<1> == 0x00 [filler]
1011 * - FixedInt<2> warning-count
1012 *
1013 * If caps contains optional_resultset_metadata:
1014 *
1015 * - FixedInt<1> with_metadata
1016 *
1017 * sent as response after a client::StmtPrepare
1018 */
1019template <>
1021 : public impl::EncodeBase<
1022 Codec<borrowable::message::server::StmtPrepareOk>> {
1023 template <class Accumulator>
1024 constexpr auto accumulate_fields(Accumulator &&accu) const {
1025 namespace bw = borrowable::wire;
1026
1027 accu.step(bw::FixedInt<1>(cmd_byte()))
1028 .step(bw::FixedInt<4>(v_.statement_id()))
1029 .step(bw::FixedInt<2>(v_.column_count()))
1030 .step(bw::FixedInt<2>(v_.param_count()))
1031 .step(bw::FixedInt<1>(0))
1032 .step(bw::FixedInt<2>(v_.warning_count()));
1033
1035 accu.step(bw::FixedInt<1>(v_.with_metadata()));
1036 }
1037
1038 return accu.result();
1039 }
1040
1041 public:
1044
1045 friend __base;
1046
1048 : __base(caps), v_{std::move(v)} {}
1049
1050 constexpr static uint8_t cmd_byte() noexcept { return 0x00; }
1051
1055
1056 namespace bw = borrowable::wire;
1057
1058 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1059 auto stmt_id_res = accu.template step<bw::FixedInt<4>>();
1060 auto column_count_res = accu.template step<bw::FixedInt<2>>();
1061 auto param_count_res = accu.template step<bw::FixedInt<2>>();
1062 auto filler_res = accu.template step<bw::FixedInt<1>>();
1063 auto warning_count_res = accu.template step<bw::FixedInt<2>>();
1064
1065 // by default, metadata isn't optional
1066 int8_t with_metadata{1};
1068 auto with_metadata_res = accu.template step<bw::FixedInt<1>>();
1069
1070 if (with_metadata_res) {
1071 with_metadata = with_metadata_res->value();
1072 }
1073 }
1074
1075 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1076
1077 return std::make_pair(
1078 accu.result().value(),
1079 value_type(stmt_id_res->value(), column_count_res->value(),
1080 param_count_res->value(), warning_count_res->value(),
1081 with_metadata));
1082 }
1083
1084 private:
1086};
1087
1088/**
1089 * codec for a Row from the server.
1090 */
1091template <bool Borrowed>
1092class Codec<borrowable::message::server::Row<Borrowed>>
1093 : public impl::EncodeBase<
1094 Codec<borrowable::message::server::Row<Borrowed>>> {
1095 template <class Accumulator>
1096 auto accumulate_fields(Accumulator &&accu) const {
1097 namespace bw = borrowable::wire;
1098
1099 for (const auto &field : v_) {
1100 if (field) {
1101 accu.step(bw::VarString<Borrowed>(*field));
1102 } else {
1103 accu.step(bw::Null());
1104 }
1105 }
1106
1107 return accu.result();
1108 }
1109
1110 public:
1111 using value_type = borrowable::message::server::Row<Borrowed>;
1113
1114 friend __base;
1115
1117 : __base(caps), v_{std::move(v)} {}
1118
1119 static size_t max_size() noexcept {
1120 return std::numeric_limits<size_t>::max();
1121 }
1122
1126
1127 namespace bw = borrowable::wire;
1128
1129 std::vector<typename value_type::value_type> fields;
1130
1131 const size_t buf_size = buffer_size(buffer);
1132
1133 while (accu.result() && (accu.result().value() < buf_size)) {
1134 // field may other be a Null or a VarString
1135 auto null_res = accu.template try_step<bw::Null>();
1136 if (null_res) {
1137 fields.emplace_back(std::nullopt);
1138 } else {
1139 auto field_res = accu.template step<bw::VarString<Borrowed>>();
1140 if (!field_res) return stdx::make_unexpected(field_res.error());
1141
1142 fields.emplace_back(field_res->value());
1143 }
1144 }
1145
1146 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1147
1148 return std::make_pair(accu.result().value(), value_type(fields));
1149 }
1150
1151 private:
1153};
1154
1155/**
1156 * codec for a StmtRow from the server.
1157 *
1158 * StmtRow is the Row of a StmtExecute's resultset.
1159 *
1160 * - 0x00
1161 * - NULL bitmap
1162 * - non-NULL-values in binary encoding
1163 *
1164 * both encode and decode require type information to know:
1165 *
1166 * - size the NULL bitmap
1167 * - length of each field
1168 */
1169template <bool Borrowed>
1170class Codec<borrowable::message::server::StmtRow<Borrowed>>
1171 : public impl::EncodeBase<
1172 Codec<borrowable::message::server::StmtRow<Borrowed>>> {
1173 template <class Accumulator>
1174 auto accumulate_fields(Accumulator &&accu) const {
1175 namespace bw = borrowable::wire;
1176
1177 accu.step(bw::FixedInt<1>(0));
1178
1179 std::string nullbits;
1180 nullbits.resize(bytes_per_bits(v_.types().size()));
1181
1182 // null-bitmap starts with a 2-bit offset
1183 size_t bit_pos{2};
1184 size_t byte_pos{};
1185 for (const auto &field : v_) {
1186 if (bit_pos > 7) {
1187 bit_pos = 0;
1188 ++byte_pos;
1189 }
1190
1191 if (!field) {
1192 nullbits[byte_pos] |= 1 << bit_pos;
1193 }
1194 }
1195
1196 accu.step(bw::String<Borrowed>(nullbits));
1197
1198 size_t n{};
1199 for (const auto &field : v_) {
1200 if (field) {
1201 switch (v_.types()[n++]) {
1202 case field_type::Bit:
1203 case field_type::Blob:
1206 case field_type::Set:
1207 case field_type::String:
1208 case field_type::Enum:
1215 accu.step(bw::VarInt(field->size()));
1216 break;
1217 case field_type::Date:
1220 case field_type::Time:
1221 accu.step(bw::FixedInt<1>(field->size()));
1222 break;
1224 case field_type::Double:
1225 case field_type::Long:
1226 case field_type::Int24:
1227 case field_type::Float:
1228 case field_type::Short:
1229 case field_type::Year:
1230 case field_type::Tiny:
1231 // fixed size
1232 break;
1233 }
1234 accu.step(bw::String<Borrowed>(*field));
1235 }
1236 }
1237
1238 return accu.result();
1239 }
1240
1241 public:
1242 using value_type = borrowable::message::server::StmtRow<Borrowed>;
1244
1245 friend __base;
1246
1248 : __base(caps), v_{std::move(v)} {}
1249
1250 static size_t max_size() noexcept {
1251 return std::numeric_limits<size_t>::max();
1252 }
1253
1256 std::vector<field_type::value_type> types) {
1257 namespace bw = borrowable::wire;
1258
1260
1261 const auto row_byte_res = accu.template step<bw::FixedInt<1>>();
1262 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1263
1264 // first byte is 0x00
1265 if (row_byte_res->value() != 0x00) {
1267 }
1268
1269 const auto nullbits_res =
1270 accu.template step<bw::String<Borrowed>>(bytes_per_bits(types.size()));
1271 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1272
1273 const auto nullbits = nullbits_res->value();
1274
1275 std::vector<typename value_type::value_type> values;
1276
1277 for (size_t n{}, bit_pos{2}, byte_pos{}; n < types.size(); ++n, ++bit_pos) {
1278 if (bit_pos > 7) {
1279 bit_pos = 0;
1280 ++byte_pos;
1281 }
1282
1283 if (!(nullbits[byte_pos] & (1 << bit_pos))) {
1286 make_error_code(std::errc::invalid_argument)));
1287 switch (types[n]) {
1288 case field_type::Bit:
1289 case field_type::Blob:
1292 case field_type::Set:
1293 case field_type::String:
1294 case field_type::Enum:
1300 case field_type::Geometry: {
1301 auto string_field_size_res = accu.template step<bw::VarInt>();
1302 if (!accu.result())
1303 return stdx::make_unexpected(accu.result().error());
1304
1305 field_size_res = string_field_size_res->value();
1306 } break;
1307 case field_type::Date:
1310 case field_type::Time: {
1311 auto time_field_size_res = accu.template step<bw::FixedInt<1>>();
1312 if (!accu.result())
1313 return stdx::make_unexpected(accu.result().error());
1314
1315 field_size_res = time_field_size_res->value();
1316 } break;
1318 case field_type::Double:
1319 field_size_res = 8;
1320 break;
1321 case field_type::Long:
1322 case field_type::Int24:
1323 case field_type::Float:
1324 field_size_res = 4;
1325 break;
1326 case field_type::Short:
1327 case field_type::Year:
1328 field_size_res = 2;
1329 break;
1330 case field_type::Tiny:
1331 field_size_res = 1;
1332 break;
1333 }
1334
1335 if (!field_size_res) {
1336 return stdx::make_unexpected(
1338 }
1339
1340 const auto value_res =
1341 accu.template step<bw::String<Borrowed>>(field_size_res.value());
1342 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1343
1344 values.push_back(value_res->value());
1345 } else {
1346 values.emplace_back(std::nullopt);
1347 }
1348 }
1349
1350 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1351
1352 return std::make_pair(accu.result().value(), value_type(types, values));
1353 }
1354
1355 private:
1357};
1358
1359/**
1360 * codec for server::Statistics message.
1361 */
1362template <bool Borrowed>
1363class Codec<borrowable::message::server::Statistics<Borrowed>>
1364 : public impl::EncodeBase<
1365 Codec<borrowable::message::server::Statistics<Borrowed>>> {
1366 template <class Accumulator>
1367 constexpr auto accumulate_fields(Accumulator &&accu) const {
1368 namespace bw = borrowable::wire;
1369
1370 return accu.step(bw::String<Borrowed>(v_.stats())).result();
1371 }
1372
1373 public:
1374 using value_type = borrowable::message::server::Statistics<Borrowed>;
1376
1377 friend __base;
1378
1380 : __base(caps), v_{std::move(v)} {}
1381
1385
1386 namespace bw = borrowable::wire;
1387
1388 auto stats_res = accu.template step<bw::String<Borrowed>>();
1389
1390 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1391
1392 return std::make_pair(accu.result().value(),
1393 value_type(stats_res->value()));
1394 }
1395
1396 private:
1398};
1399
1400/**
1401 * CRTP base for client-side commands that are encoded as a single byte.
1402 */
1403template <class Base, class ValueType>
1405 : public impl::EncodeBase<CodecSimpleCommand<Base, ValueType>> {
1406 template <class Accumulator>
1407 constexpr auto accumulate_fields(Accumulator &&accu) const {
1408 namespace bw = borrowable::wire;
1409
1410 return accu.step(bw::FixedInt<1>(Base::cmd_byte())).result();
1411 }
1412
1413 public:
1415
1416 friend __base;
1417
1419
1420 static constexpr size_t max_size() noexcept { return 1; }
1421
1425
1426 namespace bw = borrowable::wire;
1427
1428 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1429 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1430
1431 if (cmd_byte_res->value() != Base::cmd_byte()) {
1433 }
1434
1435 return std::make_pair(accu.result().value(), ValueType());
1436 }
1437};
1438
1439enum class CommandByte {
1440 Quit = 0x01,
1441 InitSchema,
1442 Query,
1443 ListFields,
1444 CreateDb,
1445 DropDb,
1446 Refresh,
1447 Shutdown,
1448 Statistics,
1450 Connect,
1452 Debug,
1453 Ping,
1454 Time,
1456 ChangeUser,
1457 BinlogDump,
1458 TableDump,
1459 ConnectOut,
1464 StmtClose,
1465 StmtReset,
1466 SetOption,
1467 StmtFetch,
1468 Deamon,
1471 Clone
1472};
1473
1474/**
1475 * codec for client's Quit command.
1476 */
1477template <>
1479 : public CodecSimpleCommand<Codec<borrowable::message::client::Quit>,
1480 borrowable::message::client::Quit> {
1481 public:
1484
1486
1487 constexpr static uint8_t cmd_byte() noexcept {
1488 return static_cast<uint8_t>(CommandByte::Quit);
1489 }
1490};
1491
1492/**
1493 * codec for client's ResetConnection command.
1494 */
1495template <>
1497 : public CodecSimpleCommand<
1498 Codec<borrowable::message::client::ResetConnection>,
1499 borrowable::message::client::ResetConnection> {
1500 public:
1503
1505
1506 constexpr static uint8_t cmd_byte() noexcept {
1507 return static_cast<uint8_t>(CommandByte::ResetConnection);
1508 }
1509};
1510
1511/**
1512 * codec for client's Ping command.
1513 */
1514template <>
1516 : public CodecSimpleCommand<Codec<borrowable::message::client::Ping>,
1517 borrowable::message::client::Ping> {
1518 public:
1521
1523
1524 constexpr static uint8_t cmd_byte() noexcept {
1525 return static_cast<uint8_t>(CommandByte::Ping);
1526 }
1527};
1528
1529/**
1530 * codec for client's Statistics command.
1531 */
1532template <>
1534 : public CodecSimpleCommand<Codec<borrowable::message::client::Statistics>,
1535 borrowable::message::client::Statistics> {
1536 public:
1539
1541
1542 constexpr static uint8_t cmd_byte() noexcept {
1543 return static_cast<uint8_t>(CommandByte::Statistics);
1544 }
1545};
1546
1547/**
1548 * codec for client's InitSchema command.
1549 */
1550template <bool Borrowed>
1551class Codec<borrowable::message::client::InitSchema<Borrowed>>
1552 : public impl::EncodeBase<
1553 Codec<borrowable::message::client::InitSchema<Borrowed>>> {
1554 template <class Accumulator>
1555 constexpr auto accumulate_fields(Accumulator &&accu) const {
1556 namespace bw = borrowable::wire;
1557
1558 return accu.step(bw::FixedInt<1>(cmd_byte()))
1559 .step(bw::String<Borrowed>(v_.schema()))
1560 .result();
1561 }
1562
1563 public:
1566
1567 friend __base;
1568
1570 : __base(caps), v_{std::move(v)} {}
1571
1572 constexpr static uint8_t cmd_byte() noexcept {
1573 return static_cast<uint8_t>(CommandByte::InitSchema);
1574 }
1575
1579
1580 namespace bw = borrowable::wire;
1581
1582 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1583 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1584
1585 if (cmd_byte_res->value() != cmd_byte()) {
1587 }
1588
1589 auto schema_res = accu.template step<bw::String<Borrowed>>();
1590 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1591
1592 return std::make_pair(accu.result().value(),
1593 value_type(schema_res->value()));
1594 }
1595
1596 private:
1598};
1599
1600/**
1601 * codec for client's Query command.
1602 */
1603template <bool Borrowed>
1604class Codec<borrowable::message::client::Query<Borrowed>>
1605 : public impl::EncodeBase<
1606 Codec<borrowable::message::client::Query<Borrowed>>> {
1607 template <class Accumulator>
1608 constexpr auto accumulate_fields(Accumulator &&accu) const {
1609 namespace bw = borrowable::wire;
1610
1611 return accu.step(bw::FixedInt<1>(cmd_byte()))
1612 .step(bw::String<Borrowed>(v_.statement()))
1613 .result();
1614 }
1615
1616 public:
1619
1620 friend __base;
1621
1623 : __base(caps), v_{std::move(v)} {}
1624
1625 constexpr static uint8_t cmd_byte() noexcept {
1626 return static_cast<uint8_t>(CommandByte::Query);
1627 }
1628
1632
1633 namespace bw = borrowable::wire;
1634
1635 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1636 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1637
1638 if (cmd_byte_res->value() != cmd_byte()) {
1640 }
1641
1642 auto statement_res = accu.template step<bw::String<Borrowed>>();
1643 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1644
1645 return std::make_pair(accu.result().value(),
1646 value_type(statement_res->value()));
1647 }
1648
1649 private:
1651};
1652
1653/**
1654 * codec for client::SendFile message.
1655 *
1656 * sent by client as response to server::SendFileRequest
1657 *
1658 * format:
1659 *
1660 * - String payload
1661 */
1662template <bool Borrowed>
1663class Codec<borrowable::message::client::SendFile<Borrowed>>
1664 : public impl::EncodeBase<
1665 Codec<borrowable::message::client::SendFile<Borrowed>>> {
1666 template <class Accumulator>
1667 constexpr auto accumulate_fields(Accumulator &&accu) const {
1668 namespace bw = borrowable::wire;
1669
1670 return accu.step(bw::String<Borrowed>(v_.payload())).result();
1671 }
1672
1673 public:
1676
1677 friend __base;
1678
1680 : __base(caps), v_{std::move(v)} {}
1681
1685
1686 namespace bw = borrowable::wire;
1687
1688 auto payload_res = accu.template step<bw::String<Borrowed>>();
1689 if (!accu.result()) return accu.result().get_unexpected();
1690
1691 return std::make_pair(accu.result().value(),
1692 value_type(payload_res->value()));
1693 }
1694
1695 private:
1697};
1698
1699/**
1700 * codec for client's ListFields command.
1701 */
1702template <bool Borrowed>
1703class Codec<borrowable::message::client::ListFields<Borrowed>>
1704 : public impl::EncodeBase<
1705 Codec<borrowable::message::client::ListFields<Borrowed>>> {
1706 template <class Accumulator>
1707 constexpr auto accumulate_fields(Accumulator &&accu) const {
1708 namespace bw = borrowable::wire;
1709
1710 return accu.step(bw::FixedInt<1>(cmd_byte()))
1711 .step(bw::NulTermString<Borrowed>(v_.table_name()))
1712 .step(bw::String<Borrowed>(v_.wildcard()))
1713 .result();
1714 }
1715
1716 public:
1719
1720 friend __base;
1721
1723 : __base(caps), v_{std::move(v)} {}
1724
1725 constexpr static uint8_t cmd_byte() noexcept {
1726 return static_cast<uint8_t>(CommandByte::ListFields);
1727 }
1728
1732
1733 namespace bw = borrowable::wire;
1734
1735 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1736 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1737
1738 if (cmd_byte_res->value() != cmd_byte()) {
1740 }
1741
1742 auto table_name_res = accu.template step<bw::NulTermString<Borrowed>>();
1743 auto wildcard_res = accu.template step<bw::String<Borrowed>>();
1744 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1745
1746 return std::make_pair(
1747 accu.result().value(),
1748 value_type(table_name_res->value(), wildcard_res->value()));
1749 }
1750
1751 private:
1753};
1754
1755/**
1756 * codec for client's Reload command.
1757 */
1758template <>
1760 : public impl::EncodeBase<Codec<borrowable::message::client::Reload>> {
1761 template <class Accumulator>
1762 constexpr auto accumulate_fields(Accumulator &&accu) const {
1763 namespace bw = borrowable::wire;
1764
1765 return accu.step(bw::FixedInt<1>(cmd_byte()))
1766 .step(bw::FixedInt<1>(v_.cmds().to_ulong()))
1767 .result();
1768 }
1769
1770 public:
1773
1774 friend __base;
1775
1777 : __base(caps), v_{std::move(v)} {}
1778
1779 constexpr static uint8_t cmd_byte() noexcept {
1780 return static_cast<uint8_t>(CommandByte::Refresh);
1781 }
1782
1786
1787 namespace bw = borrowable::wire;
1788
1789 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1790 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1791
1792 if (cmd_byte_res->value() != cmd_byte()) {
1794 }
1795
1796 auto cmds_res = accu.template step<bw::FixedInt<1>>();
1797 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1798
1799 return std::make_pair(accu.result().value(), value_type(cmds_res->value()));
1800 }
1801
1802 private:
1804};
1805
1806/**
1807 * codec for client's Kill command.
1808 *
1809 * format:
1810 *
1811 * - FixedInt<1> == 0x0c, ProcessKill
1812 * - FixedInt<4> id
1813 */
1814template <>
1816 : public impl::EncodeBase<Codec<borrowable::message::client::Kill>> {
1817 template <class Accumulator>
1818 constexpr auto accumulate_fields(Accumulator &&accu) const {
1819 namespace bw = borrowable::wire;
1820
1821 return accu.step(bw::FixedInt<1>(cmd_byte()))
1822 .step(bw::FixedInt<4>(v_.connection_id()))
1823 .result();
1824 }
1825
1826 public:
1829
1830 friend __base;
1831
1833 : __base(caps), v_{std::move(v)} {}
1834
1835 constexpr static uint8_t cmd_byte() noexcept {
1836 return static_cast<uint8_t>(CommandByte::ProcessKill);
1837 }
1838
1842
1843 namespace bw = borrowable::wire;
1844
1845 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1846 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1847
1848 if (cmd_byte_res->value() != cmd_byte()) {
1850 }
1851
1852 auto connection_id_res = accu.template step<bw::FixedInt<4>>();
1853 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1854
1855 return std::make_pair(accu.result().value(),
1856 value_type(connection_id_res->value()));
1857 }
1858
1859 private:
1861};
1862
1863/**
1864 * codec for client's Prepared Statement command.
1865 */
1866template <bool Borrowed>
1867class Codec<borrowable::message::client::StmtPrepare<Borrowed>>
1868 : public impl::EncodeBase<
1869 Codec<borrowable::message::client::StmtPrepare<Borrowed>>> {
1870 template <class Accumulator>
1871 constexpr auto accumulate_fields(Accumulator &&accu) const {
1872 namespace bw = borrowable::wire;
1873
1874 return accu.step(bw::FixedInt<1>(cmd_byte()))
1875 .step(bw::String<Borrowed>(v_.statement()))
1876 .result();
1877 }
1878
1879 public:
1882
1883 friend __base;
1884
1886 : __base(caps), v_{std::move(v)} {}
1887
1888 constexpr static uint8_t cmd_byte() noexcept {
1889 return static_cast<uint8_t>(CommandByte::StmtPrepare);
1890 }
1891
1895
1896 namespace bw = borrowable::wire;
1897
1898 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
1899 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1900
1901 if (cmd_byte_res->value() != cmd_byte()) {
1903 }
1904
1905 auto statement_res = accu.template step<bw::String<Borrowed>>();
1906 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
1907
1908 return std::make_pair(accu.result().value(),
1909 value_type(statement_res->value()));
1910 }
1911
1912 private:
1914};
1915
1916/**
1917 * codec for client's Execute Statement command.
1918 */
1919template <bool Borrowed>
1920class Codec<borrowable::message::client::StmtExecute<Borrowed>>
1921 : public impl::EncodeBase<
1922 Codec<borrowable::message::client::StmtExecute<Borrowed>>> {
1923 template <class Accumulator>
1924 auto accumulate_fields(Accumulator &&accu) const {
1925 namespace bw = borrowable::wire;
1926
1927 accu.step(bw::FixedInt<1>(cmd_byte()))
1928 .step(bw::FixedInt<4>(v_.statement_id()))
1929 .step(bw::FixedInt<1>(v_.flags().to_ullong()))
1930 .step(bw::FixedInt<4>(v_.iteration_count()));
1931
1932 // values.size() and types.size() MUST be the same
1933 if (v_.values().empty()) return accu.result();
1934
1935 // mark all that are NULL in the nullbits
1936 //
1937 // - one bit per parameter to send
1938 // - if a parameter is NULL, the bit is set, and later no value is added.
1939 std::vector<uint8_t> nullbits(bytes_per_bits(v_.values().size()));
1940
1941 {
1942 size_t byte_pos{}, bit_pos{};
1943 for (auto const &v : v_.values()) {
1944 if (bit_pos > 7) {
1945 bit_pos = 0;
1946 ++byte_pos;
1947 }
1948
1949 if (!v) {
1950 nullbits[byte_pos] |= 1 << bit_pos;
1951 }
1952
1953 ++bit_pos;
1954 }
1955 }
1956
1957 accu
1958 .step(bw::String<Borrowed>(typename bw::String<Borrowed>::value_type(
1959 reinterpret_cast<const char *>(nullbits.data()), nullbits.size())))
1960 .step(bw::FixedInt<1>(v_.new_params_bound()));
1961 if (v_.new_params_bound()) {
1962 for (const auto &param_def : v_.types()) {
1963 accu.step(bw::FixedInt<2>(param_def.type_and_flags));
1964 }
1965 }
1966
1967 for (auto [n, v] : stdx::views::enumerate(v_.values())) {
1968 // add all the values that aren't NULL
1969 if (!v.has_value()) continue;
1970 // write length of the type is a variable length
1971 switch (v_.types()[n].type_and_flags & 0xff) {
1972 case field_type::Bit:
1973 case field_type::Blob:
1976 case field_type::Set:
1977 case field_type::String:
1978 case field_type::Enum:
1985 accu.step(bw::VarInt(v->size()));
1986 break;
1987 case field_type::Date:
1990 case field_type::Time:
1991 accu.step(bw::FixedInt<1>(v->size()));
1992 break;
1994 case field_type::Double:
1995 case field_type::Long:
1996 case field_type::Int24:
1997 case field_type::Float:
1998 case field_type::Short:
1999 case field_type::Year:
2000 case field_type::Tiny:
2001 // fixed size
2002 break;
2003 default:
2004 assert(false || "Unknown Type");
2005 }
2006 accu.step(borrowed::wire::String(v.value()));
2007 }
2008
2009 return accu.result();
2010 }
2011
2012 public:
2015
2016 friend __base;
2017
2019 : __base(caps), v_{std::move(val)} {}
2020
2021 constexpr static uint8_t cmd_byte() noexcept {
2022 return static_cast<uint8_t>(CommandByte::StmtExecute);
2023 }
2024
2025 /**
2026 * decode a buffer into a message::client::StmtExecute.
2027 *
2028 * @param buffer a buffer
2029 * @param caps protocol capabilities
2030 * @param metadata_lookup callable that expects a 'uint32_t statement_id'
2031 * that returns a result that's convertible to
2032 * 'stdx::expected<std::vector<ParamDef>, std::error_code>' representing the
2033 * parameter-definitions of the prepared statement
2034 *
2035 * decoding a StmtExecute message requires the parameter-definitions of the
2036 * prepared statement. The metadata_lookup function may be called to get
2037 * the parameter-definitions for the statement-id.
2038 *
2039 * The function may return a parameter-definitions directly
2040 *
2041 * \code
2042 * StmtExecute::decode(
2043 * buffers,
2044 * capabilities::protocol_41,
2045 * [](uint32_t stmt_id) { return std::vector<ParamDef>{}; });
2046 * \endcode
2047 *
2048 * ... or a stdx::expected<std::vector<ParamDef>, std::error_code> if it wants
2049 * to signal that a statement-id wasn't found
2050 *
2051 * \code
2052 * StmtExecute::decode(
2053 * buffers,
2054 * capabilities::protocol_41,
2055 * [](uint32_t stmt_id) ->
2056 * stdx::expected<std::vector<ParamDef>, std::error_code> {
2057 * bool found{true};
2058 *
2059 * if (found) {
2060 * return {};
2061 * } else {
2062 * return stdx::make_unexpected(make_error_code(
2063 * codec_errc::statement_id_not_found));
2064 * }
2065 * });
2066 * \endcode
2067 */
2068 template <class Func>
2071 Func &&metadata_lookup) {
2073
2074 namespace bw = borrowable::wire;
2075
2076 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2077 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2078
2079 if (cmd_byte_res->value() != cmd_byte()) {
2081 }
2082
2083 auto statement_id_res = accu.template step<bw::FixedInt<4>>();
2084 auto flags_res = accu.template step<bw::FixedInt<1>>();
2085 auto iteration_count_res = accu.template step<bw::FixedInt<4>>();
2086
2087 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2088
2090 metadata_res = metadata_lookup(statement_id_res->value());
2091 if (!metadata_res) {
2092 return stdx::make_unexpected(
2094 }
2095
2096 const size_t param_count = metadata_res->size();
2097
2098 if (param_count == 0) {
2099 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2100
2101 return std::make_pair(
2102 accu.result().value(),
2103 value_type(statement_id_res->value(), flags_res->value(),
2104 iteration_count_res->value(), false, {}, {}));
2105 }
2106
2107 auto nullbits_res =
2108 accu.template step<bw::String<Borrowed>>(bytes_per_bits(param_count));
2109 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2110
2111 auto new_params_bound_res = accu.template step<bw::FixedInt<1>>();
2112 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2113
2114 std::vector<typename value_type::ParamDef> types;
2115 std::vector<std::optional<typename value_type::string_type>> values;
2116
2117 auto new_params_bound = new_params_bound_res->value();
2118 if (new_params_bound == 0) {
2119 types = *metadata_res;
2120 } else if (new_params_bound == 1) {
2121 types.reserve(param_count);
2122
2123 for (size_t n{}; n < param_count; ++n) {
2124 auto type_res = accu.template step<bw::FixedInt<2>>();
2125 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2126
2127 types.push_back(type_res->value());
2128 }
2129 } else {
2131 }
2132
2133 const auto nullbits = nullbits_res->value();
2134 values.reserve(param_count);
2135
2136 for (size_t n{}, bit_pos{}, byte_pos{}; n < param_count; ++n, ++bit_pos) {
2137 if (bit_pos > 7) {
2138 bit_pos = 0;
2139 ++byte_pos;
2140 }
2141
2142 if (!(nullbits[byte_pos] & (1 << bit_pos))) {
2145 make_error_code(std::errc::invalid_argument)));
2146 switch (types[n].type_and_flags & 0xff) {
2147 case field_type::Bit:
2148 case field_type::Blob:
2151 case field_type::Set:
2152 case field_type::String:
2153 case field_type::Enum:
2159 case field_type::Geometry: {
2160 auto string_field_size_res = accu.template step<bw::VarInt>();
2161 if (!accu.result())
2162 return stdx::make_unexpected(accu.result().error());
2163
2164 field_size_res = string_field_size_res->value();
2165 } break;
2166 case field_type::Date:
2169 case field_type::Time: {
2170 auto time_field_size_res = accu.template step<bw::FixedInt<1>>();
2171 if (!accu.result())
2172 return stdx::make_unexpected(accu.result().error());
2173
2174 field_size_res = time_field_size_res->value();
2175 } break;
2177 case field_type::Double:
2178 field_size_res = 8;
2179 break;
2180 case field_type::Long:
2181 case field_type::Int24:
2182 case field_type::Float:
2183 field_size_res = 4;
2184 break;
2185 case field_type::Short:
2186 case field_type::Year:
2187 field_size_res = 2;
2188 break;
2189 case field_type::Tiny:
2190 field_size_res = 1;
2191 break;
2192 }
2193
2194 if (!field_size_res) {
2195 return stdx::make_unexpected(
2197 }
2198
2199 auto value_res =
2200 accu.template step<bw::String<Borrowed>>(field_size_res.value());
2201 if (!accu.result()) {
2202 return stdx::make_unexpected(accu.result().error());
2203 }
2204
2205 values.push_back(value_res->value());
2206 } else {
2207 values.emplace_back(std::nullopt);
2208 }
2209 }
2210
2211 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2212
2213 return std::make_pair(
2214 accu.result().value(),
2215 value_type(statement_id_res->value(), flags_res->value(),
2216 iteration_count_res->value(), new_params_bound_res->value(),
2217 types, values));
2218 }
2219
2220 private:
2222};
2223
2224/**
2225 * codec for client's append data Statement command.
2226 */
2227template <bool Borrowed>
2229 : public impl::EncodeBase<
2230 Codec<borrowable::message::client::StmtParamAppendData<Borrowed>>> {
2231 template <class Accumulator>
2232 constexpr auto accumulate_fields(Accumulator &&accu) const {
2233 namespace bw = borrowable::wire;
2234
2235 return accu.step(bw::FixedInt<1>(cmd_byte()))
2236 .step(bw::FixedInt<4>(v_.statement_id()))
2237 .step(bw::FixedInt<2>(v_.param_id()))
2238 .step(bw::String<Borrowed>(v_.data()))
2239 .result();
2240 }
2241
2242 public:
2245
2246 friend __base;
2247
2249 : __base(caps), v_{std::move(v)} {}
2250
2251 constexpr static uint8_t cmd_byte() noexcept {
2252 return static_cast<uint8_t>(CommandByte::StmtSendLongData);
2253 }
2254
2258
2259 namespace bw = borrowable::wire;
2260
2261 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2262 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2263
2264 if (cmd_byte_res->value() != cmd_byte()) {
2266 }
2267
2268 auto statement_id_res = accu.template step<bw::FixedInt<4>>();
2269 auto param_id_res = accu.template step<bw::FixedInt<2>>();
2270 auto data_res = accu.template step<bw::String<Borrowed>>();
2271 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2272
2273 return std::make_pair(accu.result().value(),
2274 value_type(statement_id_res->value(),
2275 param_id_res->value(), data_res->value()));
2276 }
2277
2278 private:
2280};
2281
2282/**
2283 * codec for client's Close Statement command.
2284 */
2285template <>
2287 : public impl::EncodeBase<Codec<borrowable::message::client::StmtClose>> {
2288 template <class Accumulator>
2289 constexpr auto accumulate_fields(Accumulator &&accu) const {
2290 namespace bw = borrowable::wire;
2291
2292 return accu.step(bw::FixedInt<1>(cmd_byte()))
2293 .step(bw::FixedInt<4>(v_.statement_id()))
2294 .result();
2295 }
2296
2297 public:
2300
2301 friend __base;
2302
2304 : __base(caps), v_{std::move(v)} {}
2305
2306 constexpr static uint8_t cmd_byte() noexcept {
2307 return static_cast<uint8_t>(CommandByte::StmtClose);
2308 }
2309
2313
2314 namespace bw = borrowable::wire;
2315
2316 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2317 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2318
2319 if (cmd_byte_res->value() != cmd_byte()) {
2321 }
2322
2323 auto statement_id_res = accu.template step<bw::FixedInt<4>>();
2324 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2325
2326 return std::make_pair(accu.result().value(),
2327 value_type(statement_id_res->value()));
2328 }
2329
2330 private:
2332};
2333
2334/**
2335 * codec for client's Reset Statement command.
2336 */
2337template <>
2339 : public impl::EncodeBase<Codec<borrowable::message::client::StmtReset>> {
2340 template <class Accumulator>
2341 constexpr auto accumulate_fields(Accumulator &&accu) const {
2342 namespace bw = borrowable::wire;
2343
2344 return accu.step(bw::FixedInt<1>(cmd_byte()))
2345 .step(bw::FixedInt<4>(v_.statement_id()))
2346 .result();
2347 }
2348
2349 public:
2352
2353 friend __base;
2354
2356 : __base(caps), v_{std::move(v)} {}
2357
2358 constexpr static uint8_t cmd_byte() noexcept {
2359 return static_cast<uint8_t>(CommandByte::StmtReset);
2360 }
2361
2365
2366 namespace bw = borrowable::wire;
2367
2368 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2369 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2370
2371 if (cmd_byte_res->value() != cmd_byte()) {
2373 }
2374
2375 auto statement_id_res = accu.template step<bw::FixedInt<4>>();
2376 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2377
2378 return std::make_pair(accu.result().value(),
2379 value_type(statement_id_res->value()));
2380 }
2381
2382 private:
2384};
2385
2386/**
2387 * codec for client's SetOption command.
2388 */
2389template <>
2391 : public impl::EncodeBase<Codec<borrowable::message::client::SetOption>> {
2392 template <class Accumulator>
2393 constexpr auto accumulate_fields(Accumulator &&accu) const {
2394 namespace bw = borrowable::wire;
2395
2396 return accu.step(bw::FixedInt<1>(cmd_byte()))
2397 .step(bw::FixedInt<2>(v_.option()))
2398 .result();
2399 }
2400
2401 public:
2404
2405 friend __base;
2406
2408 : __base(caps), v_{std::move(v)} {}
2409
2410 constexpr static uint8_t cmd_byte() noexcept {
2411 return static_cast<uint8_t>(CommandByte::SetOption);
2412 }
2413
2417
2418 namespace bw = borrowable::wire;
2419
2420 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2421 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2422
2423 if (cmd_byte_res->value() != cmd_byte()) {
2425 }
2426
2427 auto option_res = accu.template step<bw::FixedInt<2>>();
2428 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2429
2430 return std::make_pair(accu.result().value(),
2431 value_type(option_res->value()));
2432 }
2433
2434 private:
2436};
2437
2438/**
2439 * codec for client's Fetch Cursor command.
2440 */
2441template <>
2443 : public impl::EncodeBase<Codec<borrowable::message::client::StmtFetch>> {
2444 template <class Accumulator>
2445 constexpr auto accumulate_fields(Accumulator &&accu) const {
2446 namespace bw = borrowable::wire;
2447
2448 return accu.step(bw::FixedInt<1>(cmd_byte()))
2449 .step(bw::FixedInt<4>(v_.statement_id()))
2450 .step(bw::FixedInt<4>(v_.row_count()))
2451 .result();
2452 }
2453
2454 public:
2457
2458 friend __base;
2459
2461 : __base(caps), v_{std::move(v)} {}
2462
2463 constexpr static uint8_t cmd_byte() noexcept {
2464 return static_cast<uint8_t>(CommandByte::StmtFetch);
2465 }
2466
2470
2471 namespace bw = borrowable::wire;
2472
2473 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2474 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2475
2476 if (cmd_byte_res->value() != cmd_byte()) {
2478 }
2479
2480 auto statement_id_res = accu.template step<bw::FixedInt<4>>();
2481 auto row_count_res = accu.template step<bw::FixedInt<4>>();
2482 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2483
2484 return std::make_pair(
2485 accu.result().value(),
2486 value_type(statement_id_res->value(), row_count_res->value()));
2487 }
2488
2489 private:
2491};
2492
2493/**
2494 * codec for client side greeting message.
2495 *
2496 *
2497 * in 3.21 ... 4.0:
2498 *
2499 * FixedInt<2> capabilities [protocol_41 not set]
2500 * FixedInt<3> max-allowed-packet
2501 * NulTermString username
2502 * NulTermString auth-method-data
2503 *
2504 * [if not connect_with_schema, there may be no trailing Nul-byte]
2505 *
2506 * if connect_with_schema {
2507 * String schema
2508 * }
2509 *
2510 * the auth-method is "old_password" if "protocol_version == 10 &&
2511 * (capabilities & long_password)", it is "older_password" otherwise
2512 *
2513 * FixedInt<2> capabilities_lo [protocol_41 set]
2514 * FixedInt<2> capabilities_hi
2515 * FixedInt<4> max_allowed-packet
2516 * ...
2517 *
2518 * The capabilities that are part of the message are the client's capabilities
2519 * (which may announce more than what the server supports). The codec
2520 * uses the capabilities that are shared between client and server to decide
2521 * which parts and how they are understood, though.
2522 *
2523 * checked capabilities:
2524 * - protocol_41
2525 * - ssl
2526 * - client_auth_method_data_varint
2527 * - secure_connection
2528 * - connect_with_schema
2529 * - plugin_auth
2530 * - connect_attributes
2531 */
2532template <bool Borrowed>
2533class Codec<borrowable::message::client::Greeting<Borrowed>>
2534 : public impl::EncodeBase<
2535 Codec<borrowable::message::client::Greeting<Borrowed>>> {
2536 template <class Accumulator>
2537 constexpr auto accumulate_fields(Accumulator &&accu) const {
2538 namespace bw = borrowable::wire;
2539
2540 const auto shared_caps = v_.capabilities() & this->caps();
2541
2543 accu.step(bw::FixedInt<4>(v_.capabilities().to_ulong()))
2544 .step(bw::FixedInt<4>(v_.max_packet_size()))
2545 .step(bw::FixedInt<1>(v_.collation()))
2546 .step(bw::String<Borrowed>(std::string(23, '\0')));
2547 if (!(shared_caps[classic_protocol::capabilities::pos::ssl] &&
2548 v_.username().empty())) {
2549 // the username is empty and SSL is set, this is a short SSL-greeting
2550 // packet
2551 accu.step(bw::NulTermString<Borrowed>(v_.username()));
2552
2553 if (shared_caps[classic_protocol::capabilities::pos::
2555 accu.step(bw::VarString<Borrowed>(v_.auth_method_data()));
2556 } else if (shared_caps[classic_protocol::capabilities::pos::
2558 accu.step(bw::FixedInt<1>(v_.auth_method_data().size()))
2559 .step(bw::String<Borrowed>(v_.auth_method_data()));
2560 } else {
2561 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_data()));
2562 }
2563
2564 if (shared_caps
2566 accu.step(bw::NulTermString<Borrowed>(v_.schema()));
2567 }
2568
2569 if (!shared_caps
2571 // special handling for off-spec client/server implementations.
2572 //
2573 // 1. older clients may set ::plugin_auth, but
2574 // ::connection_attributes which means nothing follows the
2575 // "auth-method-name" field
2576 // 2. auth-method-name is empty, it MAY be skipped.
2578 !v_.auth_method_name().empty()) {
2579 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_name()));
2580 }
2581 } else {
2583 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_name()));
2584 }
2585
2586 accu.step(bw::VarString<Borrowed>(v_.attributes()));
2587 }
2588 }
2589 } else {
2590 accu.step(bw::FixedInt<2>(v_.capabilities().to_ulong()))
2591 .step(bw::FixedInt<3>(v_.max_packet_size()))
2592 .step(bw::NulTermString<Borrowed>(v_.username()));
2593 if (shared_caps
2595 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_data()))
2596 .step(bw::String<Borrowed>(v_.schema()));
2597 } else {
2598 accu.step(bw::String<Borrowed>(v_.auth_method_data()));
2599 }
2600 }
2601
2602 return accu.result();
2603 }
2604
2605 public:
2608
2609 friend __base;
2610
2612 : __base(caps), v_{std::move(v)} {}
2613
2617
2618 namespace bw = borrowable::wire;
2619
2620 auto capabilities_lo_res = accu.template step<bw::FixedInt<2>>();
2621 if (!capabilities_lo_res)
2622 return stdx::make_unexpected(capabilities_lo_res.error());
2623
2624 auto client_capabilities = classic_protocol::capabilities::value_type(
2625 capabilities_lo_res->value());
2626
2627 // decoding depends on the capabilities that both client and server have in
2628 // common
2629 auto shared_capabilities = caps & client_capabilities;
2630
2631 if (shared_capabilities[classic_protocol::capabilities::pos::protocol_41]) {
2632 // if protocol_41 is set in the capabilities, we expected 2 more bytes
2633 // of capabilities
2634 auto capabilities_hi_res = accu.template step<bw::FixedInt<2>>();
2635 if (!capabilities_hi_res)
2636 return stdx::make_unexpected(capabilities_hi_res.error());
2637
2638 client_capabilities |= classic_protocol::capabilities::value_type(
2639 capabilities_hi_res->value() << 16);
2640
2641 shared_capabilities = caps & client_capabilities;
2642
2643 auto max_packet_size_res = accu.template step<bw::FixedInt<4>>();
2644 auto collation_res = accu.template step<bw::FixedInt<1>>();
2645
2646 accu.template step<bw::String<Borrowed>>(23); // skip 23 bytes
2647
2648 auto last_accu_res = accu.result();
2649
2650 auto username_res = accu.template step<bw::NulTermString<Borrowed>>();
2651 if (!accu.result()) {
2652 // if there isn't enough data for the nul-term-string, but we had the
2653 // 23-bytes ...
2654 if (last_accu_res &&
2655 shared_capabilities[classic_protocol::capabilities::pos::ssl]) {
2656 return std::make_pair(
2657 last_accu_res.value(),
2658 value_type(client_capabilities, max_packet_size_res->value(),
2659 collation_res->value(), {}, {}, {}, {}, {}));
2660 }
2661
2662 return stdx::make_unexpected(accu.result().error());
2663 }
2664
2665 // auth-method-data is either
2666 //
2667 // - varint length
2668 // - fixed-int-1 length
2669 // - null-term-string
2670 stdx::expected<bw::String<Borrowed>, std::error_code>
2671 auth_method_data_res;
2672 if (shared_capabilities[classic_protocol::capabilities::pos::
2674 auto res = accu.template step<bw::VarString<Borrowed>>();
2675 if (!res) return stdx::make_unexpected(res.error());
2676
2677 auth_method_data_res = bw::String<Borrowed>(res->value());
2678 } else if (shared_capabilities
2680 auto auth_method_data_len_res = accu.template step<bw::FixedInt<1>>();
2681 if (!auth_method_data_len_res)
2682 return stdx::make_unexpected(auth_method_data_len_res.error());
2683 auto auth_method_data_len = auth_method_data_len_res->value();
2684
2685 auto res =
2686 accu.template step<bw::String<Borrowed>>(auth_method_data_len);
2687 if (!res) return stdx::make_unexpected(res.error());
2688
2689 auth_method_data_res = bw::String<Borrowed>(res->value());
2690 } else {
2691 auto res = accu.template step<bw::NulTermString<Borrowed>>();
2692 if (!res) return stdx::make_unexpected(res.error());
2693
2694 auth_method_data_res = bw::String<Borrowed>(res->value());
2695 }
2696
2697 stdx::expected<bw::NulTermString<Borrowed>, std::error_code> schema_res;
2698 if (shared_capabilities
2700 schema_res = accu.template step<bw::NulTermString<Borrowed>>();
2701 }
2702 if (!schema_res) return stdx::make_unexpected(schema_res.error());
2703
2705 auth_method_res;
2706 if (shared_capabilities
2708 if (net::buffer_size(buffer) == accu.result().value()) {
2709 // even with plugin_auth set, the server is fine, if no
2710 // auth_method_name is sent.
2711 auth_method_res = bw::NulTermString<Borrowed>{};
2712 } else {
2713 auth_method_res = accu.template step<bw::NulTermString<Borrowed>>();
2714 }
2715 }
2716 if (!auth_method_res)
2717 return stdx::make_unexpected(auth_method_res.error());
2718
2719 stdx::expected<bw::VarString<Borrowed>, std::error_code> attributes_res;
2720 if (shared_capabilities
2722 attributes_res = accu.template step<bw::VarString<Borrowed>>();
2723 }
2724
2725 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2726
2727 return std::make_pair(
2728 accu.result().value(),
2729 value_type(client_capabilities, max_packet_size_res->value(),
2730 collation_res->value(), username_res->value(),
2731 auth_method_data_res->value(), schema_res->value(),
2732 auth_method_res->value(), attributes_res->value()));
2733
2734 } else {
2735 auto max_packet_size_res = accu.template step<bw::FixedInt<3>>();
2736
2737 auto username_res = accu.template step<bw::NulTermString<Borrowed>>();
2738
2739 stdx::expected<bw::String<Borrowed>, std::error_code>
2740 auth_method_data_res;
2741 stdx::expected<bw::String<Borrowed>, std::error_code> schema_res;
2742
2743 if (shared_capabilities
2745 auto res = accu.template step<bw::NulTermString<Borrowed>>();
2746 if (!res) return stdx::make_unexpected(res.error());
2747
2748 // auth_method_data is a wire::String, move it over
2749 auth_method_data_res = bw::String<Borrowed>(res->value());
2750
2751 schema_res = accu.template step<bw::String<Borrowed>>();
2752 } else {
2753 auth_method_data_res = accu.template step<bw::String<Borrowed>>();
2754 }
2755
2756 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2757
2758 // idea: benchmark in-place constructor where all parameters are passed
2759 // down to the lowest level.
2760 //
2761 // It should involve less copy-construction.
2762 //
2763 // - stdx::in_place is for in-place construction of stdx::expected's
2764 // value
2765 // - std::piecewise_construct for the parts of the std::pair that is
2766 // returned as value of stdx::expected
2767 //
2768 // return {stdx::in_place, std::piecewise_construct,
2769 // std::forward_as_tuple(accu.result().value()),
2770 // std::forward_as_tuple(capabilities,
2771 // max_packet_size_res->value(),
2772 // 0x00, username_res->value(),
2773 // auth_method_data_res->value(),
2774 // schema_res->value(), {},
2775 // {})};
2776 return std::make_pair(
2777 accu.result().value(),
2778 value_type(client_capabilities, max_packet_size_res->value(), 0x00,
2779 username_res->value(), auth_method_data_res->value(),
2780 schema_res->value(), {}, {}));
2781 }
2782 }
2783
2784 private:
2786};
2787
2788/**
2789 * codec for client::AuthMethodData message.
2790 *
2791 * format:
2792 *
2793 * - String auth_method_data
2794 *
2795 * sent after server::AuthMethodData or server::AuthMethodContinue
2796 */
2797template <bool Borrowed>
2798class Codec<borrowable::message::client::AuthMethodData<Borrowed>>
2799 : public impl::EncodeBase<
2800 Codec<borrowable::message::client::AuthMethodData<Borrowed>>> {
2801 template <class Accumulator>
2802 constexpr auto accumulate_fields(Accumulator &&accu) const {
2803 namespace bw = borrowable::wire;
2804
2805 return accu.step(bw::String<Borrowed>(v_.auth_method_data())).result();
2806 }
2807
2808 public:
2811
2812 friend __base;
2813
2815 : __base(caps), v_{std::move(v)} {}
2816
2820
2821 namespace bw = borrowable::wire;
2822
2823 auto auth_method_data_res = accu.template step<bw::String<Borrowed>>();
2824
2825 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2826
2827 return std::make_pair(accu.result().value(),
2828 value_type(auth_method_data_res->value()));
2829 }
2830
2831 private:
2833};
2834
2835/**
2836 * codec for client side change-user message.
2837 *
2838 * checked capabilities:
2839 * - protocol_41
2840 * - secure_connection
2841 * - plugin_auth
2842 * - connect_attributes
2843 */
2844template <bool Borrowed>
2845class Codec<borrowable::message::client::ChangeUser<Borrowed>>
2846 : public impl::EncodeBase<
2847 Codec<borrowable::message::client::ChangeUser<Borrowed>>> {
2848 template <class Accumulator>
2849 constexpr auto accumulate_fields(Accumulator &&accu) const {
2850 namespace bw = borrowable::wire;
2851
2852 accu.step(bw::FixedInt<1>(cmd_byte()))
2853 .step(bw::NulTermString<Borrowed>(v_.username()));
2854
2856 accu.step(bw::FixedInt<1>(v_.auth_method_data().size()))
2857 .step(bw::String<Borrowed>(v_.auth_method_data()));
2858 } else {
2859 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_data()));
2860 }
2861 accu.step(bw::NulTermString<Borrowed>(v_.schema()));
2862
2863 // 4.1 and later have a collation
2864 //
2865 // this could be checked via the protocol_41 capability, but that's not
2866 // what the server does
2867 if (v_.collation() != 0x00 ||
2870 accu.step(bw::FixedInt<2>(v_.collation()));
2872 accu.step(bw::NulTermString<Borrowed>(v_.auth_method_name()));
2873 }
2874
2875 if (this->caps()
2877 accu.step(bw::VarString<Borrowed>(v_.attributes()));
2878 }
2879 }
2880
2881 return accu.result();
2882 }
2883
2884 public:
2887
2888 friend __base;
2889
2891 : __base(caps), v_{std::move(v)} {}
2892
2893 constexpr static uint8_t cmd_byte() noexcept {
2894 return static_cast<uint8_t>(CommandByte::ChangeUser);
2895 }
2896
2900
2901 namespace bw = borrowable::wire;
2902
2903 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
2904 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2905
2906 if (cmd_byte_res->value() != cmd_byte()) {
2908 }
2909 auto username_res = accu.template step<bw::NulTermString<Borrowed>>();
2910
2911 // auth-method-data is either
2912 //
2913 // - fixed-int-1 length
2914 // - null-term-string
2915 stdx::expected<bw::String<Borrowed>, std::error_code> auth_method_data_res;
2917 auto auth_method_data_len_res = accu.template step<bw::FixedInt<1>>();
2918 if (!auth_method_data_len_res)
2919 return stdx::make_unexpected(auth_method_data_len_res.error());
2920 auto auth_method_data_len = auth_method_data_len_res->value();
2921
2922 auto res = accu.template step<bw::String<Borrowed>>(auth_method_data_len);
2923 if (!res) return stdx::make_unexpected(res.error());
2924
2925 auth_method_data_res = bw::String<Borrowed>(res->value());
2926 } else {
2927 auto res = accu.template step<bw::NulTermString<Borrowed>>();
2928 if (!res) return stdx::make_unexpected(res.error());
2929
2930 auth_method_data_res = bw::String<Borrowed>(res->value());
2931 }
2932
2933 auto schema_res = accu.template step<bw::NulTermString<Borrowed>>();
2934
2935 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2936
2937 // 3.23.x-4.0 don't send more.
2938 if (buffer_size(buffer) <= accu.result().value()) {
2939 return std::make_pair(
2940 accu.result().value(),
2941 value_type(username_res->value(), auth_method_data_res->value(),
2942 schema_res->value(), 0x00, {}, {}));
2943 }
2944
2945 // added in 4.1
2946 auto collation_res = accu.template step<bw::FixedInt<2>>();
2947
2949 auth_method_name_res;
2951 auth_method_name_res = accu.template step<bw::NulTermString<Borrowed>>();
2952 }
2953
2954 stdx::expected<bw::VarString<Borrowed>, std::error_code> attributes_res;
2956 attributes_res = accu.template step<bw::VarString<Borrowed>>();
2957 }
2958
2959 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
2960
2961 return std::make_pair(
2962 accu.result().value(),
2963 value_type(username_res->value(), auth_method_data_res->value(),
2964 schema_res->value(), collation_res->value(),
2965 auth_method_name_res->value(), attributes_res->value()));
2966 }
2967
2968 private:
2970};
2971
2972/**
2973 * codec for client's Clone command.
2974 *
2975 * response: server::Ok or server::Error
2976 */
2977template <>
2979 : public CodecSimpleCommand<Codec<borrowable::message::client::Clone>,
2980 borrowable::message::client::Clone> {
2981 public:
2984
2986
2987 constexpr static uint8_t cmd_byte() noexcept {
2988 return static_cast<uint8_t>(CommandByte::Clone);
2989 }
2990};
2991
2992/**
2993 * codec for client side dump-binlog message.
2994 */
2995template <bool Borrowed>
2996class Codec<borrowable::message::client::BinlogDump<Borrowed>>
2997 : public impl::EncodeBase<
2998 Codec<borrowable::message::client::BinlogDump<Borrowed>>> {
2999 public:
3001
3002 private:
3003 template <class Accumulator>
3004 constexpr auto accumulate_fields(Accumulator &&accu) const {
3005 namespace bw = borrowable::wire;
3006
3007 return accu.step(bw::FixedInt<1>(cmd_byte()))
3008 .step(bw::FixedInt<4>(v_.position()))
3009 .step(bw::FixedInt<2>(v_.flags().underlying_value()))
3010 .step(bw::FixedInt<4>(v_.server_id()))
3011 .step(bw::String<Borrowed>(v_.filename()))
3012 .result();
3013 }
3014
3015 public:
3017
3018 friend __base;
3019
3021 : __base(caps), v_{std::move(v)} {}
3022
3023 constexpr static uint8_t cmd_byte() noexcept {
3024 return static_cast<uint8_t>(CommandByte::BinlogDump);
3025 }
3026
3030
3031 namespace bw = borrowable::wire;
3032
3033 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
3034 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3035
3036 if (cmd_byte_res->value() != cmd_byte()) {
3038 }
3039 auto position_res = accu.template step<bw::FixedInt<4>>();
3040 auto flags_res = accu.template step<bw::FixedInt<2>>();
3041 auto server_id_res = accu.template step<bw::FixedInt<4>>();
3042
3043 auto filename_res = accu.template step<bw::String<Borrowed>>();
3044
3045 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3046
3048 flags.underlying_value(flags_res->value());
3049
3050 return std::make_pair(
3051 accu.result().value(),
3052 value_type(flags, server_id_res->value(), filename_res->value(),
3053 position_res->value()));
3054 }
3055
3056 private:
3058};
3059
3060/**
3061 * codec for client side register-replica message.
3062 */
3063template <bool Borrowed>
3064class Codec<borrowable::message::client::RegisterReplica<Borrowed>>
3065 : public impl::EncodeBase<
3066 Codec<borrowable::message::client::RegisterReplica<Borrowed>>> {
3067 public:
3069
3070 private:
3071 template <class Accumulator>
3072 constexpr auto accumulate_fields(Accumulator &&accu) const {
3073 namespace bw = borrowable::wire;
3074
3075 return accu.step(bw::FixedInt<1>(cmd_byte()))
3076 .step(bw::FixedInt<4>(v_.server_id()))
3077 .step(bw::FixedInt<1>(v_.hostname().size()))
3078 .step(bw::String<Borrowed>(v_.hostname()))
3079 .step(bw::FixedInt<1>(v_.username().size()))
3080 .step(bw::String<Borrowed>(v_.username()))
3081 .step(bw::FixedInt<1>(v_.password().size()))
3082 .step(bw::String<Borrowed>(v_.password()))
3083 .step(bw::FixedInt<2>(v_.port()))
3084 .step(bw::FixedInt<4>(v_.replication_rank()))
3085 .step(bw::FixedInt<4>(v_.master_id()))
3086 .result();
3087 }
3088
3089 public:
3091
3092 friend __base;
3093
3095 : __base(caps), v_{std::move(v)} {}
3096
3097 constexpr static uint8_t cmd_byte() noexcept {
3098 return static_cast<uint8_t>(CommandByte::RegisterReplica);
3099 }
3100
3104
3105 namespace bw = borrowable::wire;
3106
3107 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
3108 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3109
3110 if (cmd_byte_res->value() != cmd_byte()) {
3112 }
3113 auto server_id_res = accu.template step<bw::FixedInt<4>>();
3114 auto hostname_len_res = accu.template step<bw::FixedInt<1>>();
3115 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3116
3117 auto hostname_res =
3118 accu.template step<bw::String<Borrowed>>(hostname_len_res->value());
3119
3120 auto username_len_res = accu.template step<bw::FixedInt<1>>();
3121 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3122
3123 auto username_res =
3124 accu.template step<bw::String<Borrowed>>(username_len_res->value());
3125
3126 auto password_len_res = accu.template step<bw::FixedInt<1>>();
3127 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3128
3129 auto password_res =
3130 accu.template step<bw::String<Borrowed>>(password_len_res->value());
3131
3132 auto port_res = accu.template step<bw::FixedInt<2>>();
3133 auto replication_rank_res = accu.template step<bw::FixedInt<4>>();
3134 auto master_id_res = accu.template step<bw::FixedInt<4>>();
3135
3136 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3137
3138 return std::make_pair(
3139 accu.result().value(),
3140 value_type(server_id_res->value(), hostname_res->value(),
3141 username_res->value(), password_res->value(),
3142 port_res->value(), replication_rank_res->value(),
3143 master_id_res->value()));
3144 }
3145
3146 private:
3148};
3149
3150/**
3151 * codec for client side dump-binlog-with-gtid message.
3152 */
3153template <bool Borrowed>
3154class Codec<borrowable::message::client::BinlogDumpGtid<Borrowed>>
3155 : public impl::EncodeBase<
3156 Codec<borrowable::message::client::BinlogDumpGtid<Borrowed>>> {
3157 public:
3159
3160 private:
3161 template <class Accumulator>
3162 constexpr auto accumulate_fields(Accumulator &&accu) const {
3163 namespace bw = borrowable::wire;
3164
3165 accu.step(bw::FixedInt<1>(cmd_byte()))
3166 .step(bw::FixedInt<2>(v_.flags().underlying_value()))
3167 .step(bw::FixedInt<4>(v_.server_id()))
3168 .step(bw::FixedInt<4>(v_.filename().size()))
3169 .step(bw::String<Borrowed>(v_.filename()))
3170 .step(bw::FixedInt<8>(v_.position()));
3171
3172 if (v_.flags() & value_type::Flags::through_gtid) {
3173 accu.step(bw::FixedInt<4>(v_.sids().size()))
3174 .step(bw::String<Borrowed>(v_.sids()));
3175 }
3176
3177 return accu.result();
3178 }
3179
3180 public:
3182
3183 friend base_;
3184
3186 : base_(caps), v_{std::move(val)} {}
3187
3188 constexpr static uint8_t cmd_byte() noexcept {
3189 return static_cast<uint8_t>(CommandByte::BinlogDumpGtid);
3190 }
3191
3195
3196 namespace bw = borrowable::wire;
3197
3198 auto cmd_byte_res = accu.template step<bw::FixedInt<1>>();
3199 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3200
3201 if (cmd_byte_res->value() != cmd_byte()) {
3203 }
3204 auto flags_res = accu.template step<bw::FixedInt<2>>();
3205 auto server_id_res = accu.template step<bw::FixedInt<4>>();
3206 auto filename_len_res = accu.template step<bw::FixedInt<4>>();
3207 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3208
3209 auto filename_res =
3210 accu.template step<bw::String<Borrowed>>(filename_len_res->value());
3211 auto position_res = accu.template step<bw::FixedInt<8>>();
3212
3214 flags.underlying_value(flags_res->value());
3215
3216 if (!(flags & value_type::Flags::through_gtid)) {
3217 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3218
3219 return std::make_pair(
3220 accu.result().value(),
3221 value_type(flags, server_id_res->value(), filename_res->value(),
3222 position_res->value(), {}));
3223 }
3224
3225 auto sids_len_res = accu.template step<bw::FixedInt<4>>();
3226 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3227
3228 auto sids_res =
3229 accu.template step<bw::String<Borrowed>>(sids_len_res->value());
3230
3231 if (!accu.result()) return stdx::make_unexpected(accu.result().error());
3232
3233 return std::make_pair(
3234 accu.result().value(),
3235 value_type(flags, server_id_res->value(), filename_res->value(),
3236 position_res->value(), sids_res->value()));
3237 }
3238
3239 private:
3241};
3242
3243} // namespace classic_protocol
3244
3245#endif
CRTP base for client-side commands that are encoded as a single byte.
Definition: classic_protocol_codec_message.h:1405
constexpr CodecSimpleCommand(capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1418
friend __base
Definition: classic_protocol_codec_message.h:1416
static constexpr size_t max_size() noexcept
Definition: classic_protocol_codec_message.h:1420
static stdx::expected< std::pair< size_t, ValueType >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1422
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1407
const value_type v_
Definition: classic_protocol_codec_message.h:2832
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2817
friend __base
Definition: classic_protocol_codec_message.h:2812
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2802
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2814
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:3188
const value_type v_
Definition: classic_protocol_codec_message.h:3240
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:3192
constexpr Codec(value_type val, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:3185
friend base_
Definition: classic_protocol_codec_message.h:3183
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:3162
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:3020
friend __base
Definition: classic_protocol_codec_message.h:3018
const value_type v_
Definition: classic_protocol_codec_message.h:3057
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:3027
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:3004
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:3023
const value_type v_
Definition: classic_protocol_codec_message.h:2969
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2893
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2897
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2890
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2849
friend __base
Definition: classic_protocol_codec_message.h:2888
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2987
constexpr Codec(value_type, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2985
friend __base
Definition: classic_protocol_codec_message.h:2609
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2614
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2611
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2537
const value_type v_
Definition: classic_protocol_codec_message.h:2785
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1576
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1555
const value_type v_
Definition: classic_protocol_codec_message.h:1597
friend __base
Definition: classic_protocol_codec_message.h:1567
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1569
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1572
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1818
value_type v_
Definition: classic_protocol_codec_message.h:1860
friend __base
Definition: classic_protocol_codec_message.h:1830
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1839
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1835
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1832
const value_type v_
Definition: classic_protocol_codec_message.h:1752
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1722
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1725
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1707
friend __base
Definition: classic_protocol_codec_message.h:1720
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1729
constexpr Codec(value_type, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1522
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1524
const value_type v_
Definition: classic_protocol_codec_message.h:1650
friend __base
Definition: classic_protocol_codec_message.h:1620
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1629
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1608
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1625
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1622
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1487
constexpr Codec(value_type, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1485
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:3072
const value_type v_
Definition: classic_protocol_codec_message.h:3147
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:3097
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:3094
friend __base
Definition: classic_protocol_codec_message.h:3092
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:3101
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1762
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1779
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1776
friend __base
Definition: classic_protocol_codec_message.h:1774
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1783
const value_type v_
Definition: classic_protocol_codec_message.h:1803
constexpr Codec(value_type, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1504
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1506
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1682
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1667
friend __base
Definition: classic_protocol_codec_message.h:1677
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1679
const value_type v_
Definition: classic_protocol_codec_message.h:1696
const value_type v_
Definition: classic_protocol_codec_message.h:2435
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2414
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2407
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2393
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2410
friend __base
Definition: classic_protocol_codec_message.h:2405
constexpr Codec(value_type, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1540
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1542
friend __base
Definition: classic_protocol_codec_message.h:2301
const value_type v_
Definition: classic_protocol_codec_message.h:2331
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2306
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2289
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2310
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2303
friend __base
Definition: classic_protocol_codec_message.h:2016
const value_type v_
Definition: classic_protocol_codec_message.h:2221
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps, Func &&metadata_lookup)
decode a buffer into a message::client::StmtExecute.
Definition: classic_protocol_codec_message.h:2069
auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1924
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2021
constexpr Codec(value_type val, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2018
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2467
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2463
const value_type v_
Definition: classic_protocol_codec_message.h:2490
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2445
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2460
friend __base
Definition: classic_protocol_codec_message.h:2458
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2248
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2251
const value_type v_
Definition: classic_protocol_codec_message.h:2279
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2255
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2232
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1888
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1892
const value_type v_
Definition: classic_protocol_codec_message.h:1913
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1885
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1871
friend __base
Definition: classic_protocol_codec_message.h:1883
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:2358
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2362
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:2341
friend __base
Definition: classic_protocol_codec_message.h:2353
const value_type v_
Definition: classic_protocol_codec_message.h:2383
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:2355
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:323
const value_type v_
Definition: classic_protocol_codec_message.h:349
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:309
borrowable::message::server::AuthMethodData< Borrowed > value_type
Definition: classic_protocol_codec_message.h:318
static constexpr uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:326
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:328
friend __base
Definition: classic_protocol_codec_message.h:321
borrowable::message::server::AuthMethodSwitch< Borrowed > value_type
Definition: classic_protocol_codec_message.h:259
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:264
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:245
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:269
static constexpr uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:267
const value_type v_
Definition: classic_protocol_codec_message.h:298
borrowable::message::server::ColumnCount value_type
Definition: classic_protocol_codec_message.h:743
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:748
friend __base
Definition: classic_protocol_codec_message.h:746
const value_type v_
Definition: classic_protocol_codec_message.h:769
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:736
static constexpr size_t max_size() noexcept
Definition: classic_protocol_codec_message.h:751
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:755
auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:783
const value_type v_
Definition: classic_protocol_codec_message.h:941
friend __base
Definition: classic_protocol_codec_message.h:827
Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:829
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:836
static size_t max_size() noexcept
Definition: classic_protocol_codec_message.h:832
borrowable::message::server::ColumnMeta< Borrowed > value_type
Definition: classic_protocol_codec_message.h:824
borrowable::message::server::Eof< Borrowed > value_type
Definition: classic_protocol_codec_message.h:537
const value_type v_
Definition: classic_protocol_codec_message.h:635
friend __base
Definition: classic_protocol_codec_message.h:540
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:542
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:495
static constexpr uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:545
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
decode a server::Eof message from a buffer-sequence.
Definition: classic_protocol_codec_message.h:566
friend __base
Definition: classic_protocol_codec_message.h:684
static constexpr uint8_t cmd_byte()
Definition: classic_protocol_codec_message.h:689
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:686
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:695
borrowable::message::server::Error< Borrowed > value_type
Definition: classic_protocol_codec_message.h:681
const value_type v_
Definition: classic_protocol_codec_message.h:726
static constexpr size_t max_size() noexcept
Definition: classic_protocol_codec_message.h:691
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:667
const value_type v_
Definition: classic_protocol_codec_message.h:234
friend __base
Definition: classic_protocol_codec_message.h:129
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:131
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:134
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:83
borrowable::message::server::Greeting< Borrowed > value_type
Definition: classic_protocol_codec_message.h:126
const value_type v_
Definition: classic_protocol_codec_message.h:469
borrowable::message::server::Ok< Borrowed > value_type
Definition: classic_protocol_codec_message.h:388
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:360
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:393
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
decode a server::Ok message from a buffer-sequence.
Definition: classic_protocol_codec_message.h:413
friend __base
Definition: classic_protocol_codec_message.h:391
static constexpr uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:396
static size_t max_size() noexcept
Definition: classic_protocol_codec_message.h:1119
Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1116
const value_type v_
Definition: classic_protocol_codec_message.h:1152
auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1096
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1123
borrowable::message::server::Row< Borrowed > value_type
Definition: classic_protocol_codec_message.h:1111
friend __base
Definition: classic_protocol_codec_message.h:1114
const value_type v_
Definition: classic_protocol_codec_message.h:998
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:972
friend __base
Definition: classic_protocol_codec_message.h:970
borrowable::message::server::SendFileRequest< Borrowed > value_type
Definition: classic_protocol_codec_message.h:967
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:977
static constexpr uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:975
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:958
const value_type v_
Definition: classic_protocol_codec_message.h:1397
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1379
borrowable::message::server::Statistics< Borrowed > value_type
Definition: classic_protocol_codec_message.h:1374
friend __base
Definition: classic_protocol_codec_message.h:1377
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1382
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1367
constexpr static uint8_t cmd_byte() noexcept
Definition: classic_protocol_codec_message.h:1050
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1052
friend __base
Definition: classic_protocol_codec_message.h:1045
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1047
borrowable::message::server::StmtPrepareOk value_type
Definition: classic_protocol_codec_message.h:1042
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1024
const value_type v_
Definition: classic_protocol_codec_message.h:1085
const value_type v_
Definition: classic_protocol_codec_message.h:1356
Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_message.h:1247
borrowable::message::server::StmtRow< Borrowed > value_type
Definition: classic_protocol_codec_message.h:1242
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps, std::vector< field_type::value_type > types)
Definition: classic_protocol_codec_message.h:1254
static size_t max_size() noexcept
Definition: classic_protocol_codec_message.h:1250
auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_message.h:1174
friend __base
Definition: classic_protocol_codec_message.h:1245
Codec for a type.
Definition: classic_protocol_codec_base.h:71
Definition: classic_protocol_message.h:1219
Definition: classic_protocol_message.h:1281
Definition: classic_protocol_message.h:1253
Definition: classic_protocol_message.h:850
Definition: classic_protocol_message.h:1250
Definition: classic_protocol_message.h:662
Definition: classic_protocol_message.h:825
Definition: classic_protocol_message.h:938
Definition: classic_protocol_message.h:788
Definition: classic_protocol_message.h:1214
Definition: classic_protocol_message.h:764
Definition: classic_protocol_message.h:1209
Definition: classic_protocol_message.h:1313
Definition: classic_protocol_message.h:916
Definition: classic_protocol_message.h:903
Definition: classic_protocol_message.h:958
set options on the current connection.
Definition: classic_protocol_message.h:1189
Definition: classic_protocol_message.h:910
close a prepared statement.
Definition: classic_protocol_message.h:1119
execute a prepared statement.
Definition: classic_protocol_message.h:1052
fetch rows from an executed statement.
Definition: classic_protocol_message.h:1163
append data to a parameter of a prepared statement.
Definition: classic_protocol_message.h:1011
Definition: classic_protocol_message.h:983
reset a prepared statement.
Definition: classic_protocol_message.h:1141
Definition: classic_protocol_wire.h:37
Generator of decoded Types of a buffer.
Definition: classic_protocol_codec_base.h:152
result_type result() const
get result of the step().
Definition: classic_protocol_codec_base.h:218
CRTP base for the Codec's encode part.
Definition: classic_protocol_codec_base.h:374
constexpr capabilities::value_type caps() const noexcept
Definition: classic_protocol_codec_base.h:389
Definition: buffer.h:134
constexpr const value_type & value() const &
Definition: expected.h:687
constexpr unexpected_type get_unexpected() const
Definition: expected.h:753
constexpr const error_type & error() const &
Definition: expected.h:736
Definition: expected.h:943
a type-safe flags type.
Definition: flags.h:114
constexpr DWORD buf_size
Definition: create_def.cc:227
static int flags[50]
Definition: hp_test1.cc:39
uint16_t value_type
Definition: vt100.h:183
borrowable::wire::Null Null
Definition: classic_protocol_wire.h:144
borrowable::wire::VarInt VarInt
Definition: classic_protocol_wire.h:147
Definition: classic_protocol_constants.h:35
constexpr value_type text_result_with_session_tracking
Definition: classic_protocol_constants.h:61
constexpr value_type long_flag
Definition: classic_protocol_constants.h:39
constexpr value_type transactions
Definition: classic_protocol_constants.h:50
constexpr value_type plugin_auth
Definition: classic_protocol_constants.h:56
constexpr value_type session_track
Definition: classic_protocol_constants.h:60
constexpr value_type optional_resultset_metadata
Definition: classic_protocol_constants.h:62
constexpr value_type connect_attributes
Definition: classic_protocol_constants.h:57
constexpr value_type client_auth_method_data_varint
Definition: classic_protocol_constants.h:58
constexpr value_type ssl
Definition: classic_protocol_constants.h:48
constexpr value_type connect_with_schema
Definition: classic_protocol_constants.h:40
constexpr value_type secure_connection
Definition: classic_protocol_constants.h:52
constexpr value_type protocol_41
Definition: classic_protocol_constants.h:46
std::bitset< 32 > value_type
Definition: classic_protocol_constants.h:72
constexpr value_type Short
Definition: classic_protocol_constants.h:230
constexpr value_type DateTime
Definition: classic_protocol_constants.h:240
constexpr value_type LongLong
Definition: classic_protocol_constants.h:236
constexpr value_type Varchar
Definition: classic_protocol_constants.h:243
constexpr value_type NewDecimal
Definition: classic_protocol_constants.h:250
constexpr value_type Time
Definition: classic_protocol_constants.h:239
constexpr value_type Decimal
Definition: classic_protocol_constants.h:228
constexpr value_type VarString
Definition: classic_protocol_constants.h:257
constexpr value_type MediumBlob
Definition: classic_protocol_constants.h:254
constexpr value_type String
Definition: classic_protocol_constants.h:258
constexpr value_type Set
Definition: classic_protocol_constants.h:252
constexpr value_type Geometry
Definition: classic_protocol_constants.h:259
constexpr value_type Bit
Definition: classic_protocol_constants.h:244
constexpr value_type Tiny
Definition: classic_protocol_constants.h:229
constexpr value_type TinyBlob
Definition: classic_protocol_constants.h:253
constexpr value_type Int24
Definition: classic_protocol_constants.h:237
constexpr value_type Enum
Definition: classic_protocol_constants.h:251
constexpr value_type Long
Definition: classic_protocol_constants.h:231
constexpr value_type Double
Definition: classic_protocol_constants.h:233
constexpr value_type Year
Definition: classic_protocol_constants.h:241
constexpr value_type Timestamp
Definition: classic_protocol_constants.h:235
constexpr value_type LongBlob
Definition: classic_protocol_constants.h:255
constexpr value_type Blob
Definition: classic_protocol_constants.h:256
constexpr value_type Date
Definition: classic_protocol_constants.h:238
constexpr value_type Float
Definition: classic_protocol_constants.h:232
borrowable::message::client::StmtFetch StmtFetch
Definition: classic_protocol_message.h:1391
borrowable::message::client::StmtReset StmtReset
Definition: classic_protocol_message.h:1386
borrowable::message::client::Reload Reload
Definition: classic_protocol_message.h:1381
borrowable::message::client::SetOption SetOption
Definition: classic_protocol_message.h:1390
borrowable::message::client::Kill Kill
Definition: classic_protocol_message.h:1379
borrowable::message::client::StmtClose StmtClose
Definition: classic_protocol_message.h:1387
borrowable::message::server::AuthMethodSwitch< false > AuthMethodSwitch
Definition: classic_protocol_message.h:1362
borrowable::message::server::Error< false > Error
Definition: classic_protocol_message.h:1357
borrowable::message::server::StmtPrepareOk StmtPrepareOk
Definition: classic_protocol_message.h:1367
borrowable::message::server::Greeting< false > Greeting
Definition: classic_protocol_message.h:1359
borrowable::message::server::Row< false > Row
Definition: classic_protocol_message.h:1365
borrowable::message::server::Eof< false > Eof
Definition: classic_protocol_message.h:1358
borrowable::message::server::ColumnCount ColumnCount
Definition: classic_protocol_message.h:1360
borrowable::message::server::Ok< false > Ok
Definition: classic_protocol_message.h:1356
borrowable::message::server::AuthMethodData< false > AuthMethodData
Definition: classic_protocol_message.h:1363
borrowable::message::server::Statistics< false > Statistics
Definition: classic_protocol_message.h:1368
borrowable::message::server::StmtRow< false > StmtRow
Definition: classic_protocol_message.h:1366
borrowable::message::server::SendFileRequest< false > SendFileRequest
Definition: classic_protocol_message.h:1364
borrowable::message::server::ColumnMeta< false > ColumnMeta
Definition: classic_protocol_message.h:1361
constexpr value_type session_state_changed
Definition: classic_protocol_constants.h:163
constexpr value_type session_state_changed
Definition: classic_protocol_constants.h:205
Definition: classic_protocol_clone.h:31
std::error_code make_error_code(codec_errc e) noexcept
Definition: classic_protocol_codec_error.h:85
CommandByte
Definition: classic_protocol_codec_message.h:1439
constexpr size_t bytes_per_bits(size_t bits)
Definition: classic_protocol_codec_base.h:54
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:419
size_t buffer_size(const ConstBufferSequence &buffers) noexcept
Definition: buffer.h:314
Definition: varlen_sort.h:183
constexpr auto enumerate(T &&iterable)
Definition: ranges.h:141
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:124
int n
Definition: xcom_base.cc:508