File: xprotocol.h

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (929 lines) | stat: -rw-r--r-- 32,837 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
/*
 * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2.0,
 * as published by the Free Software Foundation.
 *
 * This program is designed to work with certain software (including
 * but not limited to OpenSSL) that is licensed under separate terms,
 * as designated in a particular file or component or in included license
 * documentation.  The authors of MySQL hereby grant you an additional
 * permission to link the program and your derivative works with the
 * separately licensed software that they have either included with
 * the program or referenced in the documentation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License, version 2.0, for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 */

// MySQL DB access module, for use by plugins and others
// For the module that implements interactive DB functionality see mod_db

#ifndef PLUGIN_X_CLIENT_MYSQLXCLIENT_XPROTOCOL_H_
#define PLUGIN_X_CLIENT_MYSQLXCLIENT_XPROTOCOL_H_

#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "mysqlxclient/xmessage.h"

#include "mysqlxclient/xargument.h"
#include "mysqlxclient/xcompression.h"
#include "mysqlxclient/xconnection.h"
#include "mysqlxclient/xerror.h"
#include "mysqlxclient/xquery_result.h"

#ifdef USE_MYSQLX_FULL_PROTO
#define HAVE_MYSQLX_FULL_PROTO(Y, N) Y
#else
#define HAVE_MYSQLX_FULL_PROTO(Y, N) N
#endif

#define XCL_CLIENT_ID_NOT_VALID 0
#define XCL_SESSION_ID_NOT_VALID 0
#define XCL_HANDLER_ID_NOT_VALID -1

namespace xcl {

/**
  Enum that defines result of dispatching a message or a notice
  to handler registred by user or XSession.
*/
enum class Handler_result {
  /**
    No action, dispatch the message/notice to next handler or
    return the message.
  */
  Continue,
  /**
    Message consumed. Stop dispatching the message. Requester
    is going to wait for next message/notice.
  */
  Consumed,
  /**
    Message consumed. Stop dispatching the message. Requester
    is going to receive an error.
  */
  Error
};

/**
  Enum that defines the position inside priority group
  where the handler is going to be appended.
*/
enum class Handler_position {
  Begin,
  End,
};

/**
  Enum that defines a execution priority of a handler.

  User handlers should be pushed on stack with "medium" priority. To overwrite
  behavior defined by XSession, XQuery_result, XProtocol objects, user can push
  their handler to other priorities.
*/
enum Handler_priority {
  /** Priority used by XSession object */
  Handler_priority_high = 100,
  /** Priority for handlers added by user */
  Handler_priority_medium = 200,
  /** Priority used by XSession object */
  Handler_priority_low = 300,
};

/**
  Interface defining X Protocol operations.

  It is responsible for building, serialization, deserialization of protobuf
  messages also it defines some basic X Protocol flows. The interface can be
  used for:

  * all X Protocol specific featured CRUD, pipelining, notices
  * sending messages that were recently added to proto files and 'send'
    method was not created for them
  * flows that were not implemented in XSession or XProtocol
*/
class XProtocol {
 public:
  /** Data type used on the wire for transferring Message_type_id */
  using Header_message_type_id = uint8_t;

  /** Aliases for types that represents different X Protocols message */
  using Server_message_type_id = Mysqlx::ServerMessages::Type;
  using Client_message_type_id = Mysqlx::ClientMessages::Type;

  /** Identification (representation) of notice handler placed in queue */
  using Handler_id = int;

  /** Alias for type that is able to hold X Plugins client identifier */
  using Client_id = uint64_t;

  /** Alias for protobuf message type used by the lite or
      full version of the library */
  using Message = HAVE_MYSQLX_FULL_PROTO(::google::protobuf::Message,
                                         ::google::protobuf::MessageLite);

  /** Function wrapper that can be used for X Protocol notice processing */
  using Notice_handler = std::function<Handler_result(
      XProtocol *protocol, const bool, const Mysqlx::Notice::Frame::Type,
      const char *, const uint32_t)>;

  /** Function wrapper that can be used for X Protocol message processing. */
  using Client_message_handler = std::function<Handler_result(
      XProtocol *protocol, const Client_message_type_id, const Message &)>;
  using Server_message_handler = std::function<Handler_result(
      XProtocol *protocol, const Server_message_type_id, const Message &)>;

  using Capabilities = ::Mysqlx::Connection::Capabilities;

 public:
  virtual ~XProtocol() = default;

  /**
    Add handler to the notice-handler list.

    Notice handlers are going to be held on a three different priority lists.
    Handler can be pushed at front or back of the list. Each notice/message
    received through this interface is going through all pushed handler
    in sequence defined by priorities and order of front/back pushes.
    Handlers are called in case when the message type is a notice and "message
    recv-handlers" didn't drop the message. When the handler returns:

    * "Handler_continue", the received notice is processed as usual.
    * "Handler_consumed", the dispatch to next handler is stopped. Received
       notice is dropped causing the receive function to wait for next notice.
    * "Handler_error", the dispatch to next handler is stopped. Received message
       is dropped and the receive functions gets and error
    CR_X_INTERNAL_ABORTED.

    @param handler     callback which is going to be called on each
                       notice received through current instance of XProtocol
    @param position    chooses where the handler is going to be inserted at
                       "begin" or "end" of selected priority list
    @param priority    chooses to which priority list the handler is going
                       to be added

    @return position ID of notice handler
  */
  virtual Handler_id add_notice_handler(
      Notice_handler handler,
      const Handler_position position = Handler_position::Begin,
      const Handler_priority priority = Handler_priority_medium) = 0;

  /**
    Removes a handler represented by 'id' from the notice hander container.

    @param id          id of header which should be removed
  */
  virtual void remove_notice_handler(const Handler_id id) = 0;

  /**
    Add handler to the recv-handler list.

    Received message handlers are going to be held on a three different
    priority lists. Handler can be pushed at front or back of the list.
    Each message received through this interface is going through all pushed
    handler in sequence defined by priorities and order of front/back pushes.
    Handlers are called after message deserialization. When the handler
    returns:

    * "Handler_continue", the received message is processed as usual.
    * "Handler_consumed", the dispatch to next handler is stopped, received
       message is dropped causing the receive function to wait for next message.
    * "Handler_error", the dispatch to next handler is stopped, received message
       is dropped and the receive functions gets and error
    CR_X_INTERNAL_ABORTED.

    @param handler     callback which is going to be called on each
                       message received through current instance of XProtocol
    @param position    chooses where the handler is going to be inserted at
                       "begin" or "end" of selected priority list
    @param priority    chooses to which priority list the handler is going
                       to be added

    @return position ID of notice handler
  */
  virtual Handler_id add_received_message_handler(
      Server_message_handler handler,
      const Handler_position position = Handler_position::Begin,
      const Handler_priority priority = Handler_priority_medium) = 0;

  /**
    Removes a handler represented by 'id' from the received
    handler container.

    @param id          id of header which should be removed
  */
  virtual void remove_received_message_handler(const Handler_id id) = 0;

  /**
    Add handler to the send-handler list.

    Send message handlers are going to be held on a three different
    priority lists. Handler can be pushed at front or back of the list.
    Each message send through this interface is going through all pushed
    handler in sequence defined by priorities and order of front/back pushes.
    Handlers are called before message serialization. Handlers return value
    is ignored.

    @param handler     callback which is going to be called on each
                       message sent through current instance of XProtocol
    @param position    chooses where the handler is going to be inserted:
                       "begin" or "end" of selected priority list
    @param priority    chooses to which priority list the handler is going
                       to be added

    @return position ID of notice handler
  */
  virtual Handler_id add_send_message_handler(
      Client_message_handler handler,
      const Handler_position position = Handler_position::Begin,
      const Handler_priority priority = Handler_priority_medium) = 0;

  /**
    Removes a handler represented by 'id' from the send
    handler container.

    @param id          id of header which should be removed
  */
  virtual void remove_send_message_handler(const Handler_id id) = 0;

  /**
    Get connection layer of XProtocol.

    The lower layer can by used do direct I/O operation on the
    socket.
  */
  virtual XConnection &get_connection() = 0;

  //
  // Methods that send or receive single message

  /**
    Read and deserialize single message.

    Message is read using XConnection, and deserialized in implementation
    of this interface. Received message before returning is going to be
    dispatched through "message handlers" and if it is a "notice" then it is
    going to be dispatched through "notice handlers". The handlers are going
    to decide what to do with the current message: ignore, allow, fail.
    When the message is ignored the  function is going to wait for next
    message.
    Following errors can occur while reading message/abort reading of the
    message:

    * I/O error from XConnection
    * timeout error from XConnection
    * error from dispatchers (notice, message)

    @param[out] out_mid    return received message identifier
    @param[out] out_error  if error occurred, this argument if going to be set
                           to its code and description

    @return Deserialized protobuf message
      @retval != nullptr   OK
      @retval == nullptr   I/O error, timeout error or dispatcher
                           error occurred
  */
  virtual std::unique_ptr<Message> recv_single_message(
      Server_message_type_id *out_mid, XError *out_error) = 0;

  /**
    Receive raw payload (of X Protocol message).

    This method receives a X Protocol message which consists of 'header' and
    'payload'. The header is received first, it holds message identifier and
    payload size(buffer size), payload(content of 'buffer') is received after
    the header. The method blocks until header and whole payload is stored
    inside user provided buffer. The length of the payload is limited by
    2^32 (length field uint32) - 5 (header size).
    When the value of expression '*buffer' is set to 'nullptr', then the method
    is going to allocate the buffer for the payload. User needs to release the
    buffer by calling 'delete[]' on it.
    Message payload received using this method isn't dispatched through
    "message handler" nor "notice handlers".

    @param[out]    out_mid     message identifier of received message
    @param[in,out] buffer      buffer for the message payload
    @param[in,out] buffer_size size of the buffer, after the call it is going
                               to hold payload length

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError recv(Header_message_type_id *out_mid, uint8_t **buffer,
                      std::size_t *buffer_size) = 0;

  /**
    Deserialize X Protocol message from raw payload.

    This method deserializes the raw payload acquired by
    `XProtocol::recv` method.

    @param mid          message identifier
    @param payload      message payload
    @param payload_size message payloads size
    @param out_error    deserialization error

    @return Error code with description
      @retval != true     OK
      @retval == true     deserialization error occurred
  */
  virtual std::unique_ptr<Message> deserialize_received_message(
      const Header_message_type_id mid, const uint8_t *payload,
      const std::size_t payload_size, XError *out_error) = 0;

  /**
    Serialize and send protobuf message.

    This method builds message payload when serializing 'msg' and prepends it
    with a 'header' holding the message identifier and payload size.
    Such construction is send using XConnection interface.

    @param mid      message identifier
    @param msg      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error or timeout error occurred
  */
  virtual XError send(const Client_message_type_id mid, const Message &msg) = 0;

  /**
    Send the raw payload as message.

    This method sends a X Protocol message which consist from 'header' and
    'payload'.  The header is send first, it holds message identifier and
    payload size(buffer size), payload(content of 'buffer') is send after
    the header. The method blocks until header and payload is fully queued
    inside TCP stack. The length of the payload is limited by
    2^32 (length field uint32) - 5 (header size).

    @param mid      message identifier
    @param buffer   already serialized message payload
    @param length   size of the custom payload

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Header_message_type_id mid, const uint8_t *buffer,
                      const std::size_t length) = 0;

  /**
    Serialize, compress and send protobuf message.

    This method compresses 'message', and places it into 'payload'
    field of `Compression` message. `Compression` message is serialized
    and send to the wire.
    Such construction is send using XConnection interface.

    @param message_id   message identifier
    @param message      to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error or timeout error occurred
  */
  virtual XError send_compressed_frame(const Client_message_type_id message_id,
                                       const Message &message) = 0;

  /**
    Serialize, compress and send multiple protobuf message of different type.

    This method builds "Compression" message that encodes and compresses all
    'messages' into "payload" field. Later on "Compression" message is
    serialized and send to the wire. size. Such construction is send using
    XConnection interface.

    @param messages     messages to be serialized, compressed and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error or timeout error occurred
  */
  virtual XError send_compressed_multiple_frames(
      const std::vector<std::pair<Client_message_type_id, const Message *>>
          &messages) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Session::AuthenticateStart &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Session::AuthenticateContinue &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Session::Reset &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Session::Close &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Sql::StmtExecute &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::Find &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::Insert &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::Update &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::Delete &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::CreateView &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::ModifyView &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Crud::DropView &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Expect::Open &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Expect::Close &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Connection::CapabilitiesGet &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Connection::CapabilitiesSet &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Connection::Close &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Cursor::Open &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Cursor::Close &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Cursor::Fetch &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Prepare::Prepare &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Prepare::Execute &m) = 0;

  /**
    Serialize and send protobuf message.

    @param m      message to be serialized and sent

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error occurred
  */
  virtual XError send(const Mysqlx::Prepare::Deallocate &m) = 0;

  /*
    Methods that execute different message flows
    with the server
  */

  /**
    Get an object that is capable of reading resultsets.

    Create and return an object without doing I/O operations.

    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  error occurred
  */
  virtual std::unique_ptr<XQuery_result> recv_resultset() = 0;

  /**
    Get an object that is capable of reading resultsets.

    Create and return an object which already fetched metadata.
    If server returns an error or an I/O error occurred then
    the function returns a valid object, the reason of doing so
    is that before the error some warnings could be received.
    User must have a possibility to investigate the warnings.

    @param[out] out_error  in case of error, the method is going to return error
                           code and description

    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  always valid object
  */
  virtual std::unique_ptr<XQuery_result> recv_resultset(XError *out_error) = 0;

  /**
    Read "Mysqlx.Ok" message.

    Expect to receive "Ok" message.
    * in case of any other message return out of sync error
    * in case "Mysqlx.Error" message translate it to "XError"
    "Ok" message is used in several different situations like: setting
    capabilities, creating views, expectations.

    @return Error code with description
      @retval != true     Received OK message
      @retval == true     I/O error, timeout error, dispatch error
                           or received "Mysqlx.Error" message
   */
  virtual XError recv_ok() = 0;

  /**
    Execute session closing flow.

    Send "Mysqlx::Session::Close" message and expect successful confirmation
    from the X Plugin by reception of "Mysqlx::Ok". Synchronization errors and
    "Mysqlx::Error" are returned through return values.

    @return Error code with description
      @retval != true     Received OK message
      @retval == true     I/O error, timeout error, dispatch error
                           or received "Mysqlx.Error" message
   */
  virtual XError execute_close() = 0;

  /**
    Send custom message and expect resultset as response.

    @param mid             id of the message to be serialized
    @param msg             message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description

    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_with_resultset(
      const Client_message_type_id mid, const Message &msg,
      XError *out_error) = 0;

  /**
    Send statement execute and expect resultset as response.

    @param msg             "StmtExecute" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description
    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_stmt(
      const Mysqlx::Sql::StmtExecute &msg, XError *out_error) = 0;

  /**
    Send crud find and expect resultset as response.

    @param msg             "Find" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description

    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_find(
      const Mysqlx::Crud::Find &msg, XError *out_error) = 0;

  /**
    Send crud update and expect resultset as response.

    @param msg             "Update" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description

    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_update(
      const Mysqlx::Crud::Update &msg, XError *out_error) = 0;

  /**
    Send crud insert and expect resultset as response.

    @param msg             "Insert" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description

    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_insert(
      const Mysqlx::Crud::Insert &msg, XError *out_error) = 0;

  /**
    Send crud delete and expect resultset as response.

    @param msg             "Delete" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description
    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_delete(
      const Mysqlx::Crud::Delete &msg, XError *out_error) = 0;

  /**
    Send prepared stmt execute and expect resultset as response.

    @param msg             "Execute" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description
    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_prep_stmt(
      const Mysqlx::Prepare::Execute &msg, XError *out_error) = 0;

  /**
    Send cursor open and expect resultset as response.

    @param msg             "Cursor::Open" message to be serialized and sent
    @param[out] out_error  in case of error, the method is going to return error
                           code and description
    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_cursor_open(
      const Mysqlx::Cursor::Open &msg, XError *out_error) = 0;

  /**
    Send cursor fetch and expect resultset as response.

    @param msg                 "Cursor::Fetch" message to be serialized and sent
    @param cursor_open_result  result of a Cursor.Open operation which should
                               contain metadata used by the fetch command
    @param[out] out_error      in case of error, the method is going to return
                               error code and description
    @return Object responsible for fetching "resultset/s" from the server
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<XQuery_result> execute_cursor_fetch(
      const Mysqlx::Cursor::Fetch &msg,
      std::unique_ptr<XQuery_result> cursor_open_result, XError *out_error) = 0;

  /**
    Send "CapabilitiesGet" and expect Capabilities as response.

    @param[out] out_error  in case of error, the method is going to return error
                           code and description

    @return X Protocol message containing capabilities available exposed
            by X Plugin
      @retval != nullptr  OK
      @retval == nullptr  I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual std::unique_ptr<Capabilities> execute_fetch_capabilities(
      XError *out_error) = 0;

  /**
    Execute "CapabilitiesSet" and expect "Ok" as response.

    @param capabilities   message containing cababilities to be set

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual XError execute_set_capability(
      const Mysqlx::Connection::CapabilitiesSet &capabilities) = 0;

  /**
    Execute authentication flow

    @param user    MySQL Server account name
    @param pass    MySQL Server accounts authentication string
    @param schema  schema which should be "used"
    @param method  X Protocol authentication method, for example:
                  "PLAIN", "MYSQL41"

    @return Error code with description
      @retval != true     OK
      @retval == true     I/O error, timeout error, dispatch error
                          or received "Mysqlx.Error" message
  */
  virtual XError execute_authenticate(const std::string &user,
                                      const std::string &pass,
                                      const std::string &schema,
                                      const std::string &method = "") = 0;

  virtual void use_compression(const Compression_algorithm algo) = 0;

  virtual void use_compression(const Compression_algorithm algo,
                               const int32_t level) = 0;

  virtual void reset_buffering() = 0;
};

}  // namespace xcl

#endif  // PLUGIN_X_CLIENT_MYSQLXCLIENT_XPROTOCOL_H_