aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Core/MySQL/PacketEndpoint.h
blob: 5e1a6a31048fe50b70aa2374943b63bd58411162 (plain) (blame)
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
#pragma once

#include <boost/noncopyable.hpp>
#include <IO/ReadBuffer.h>
#include <IO/WriteBuffer.h>
#include "IMySQLReadPacket.h"
#include "IMySQLWritePacket.h"
#include "IO/MySQLPacketPayloadReadBuffer.h"

namespace DB
{

namespace MySQLProtocol
{

/* Writes and reads packets, keeping sequence-id.
 * Throws ProtocolError, if packet with incorrect sequence-id was received.
 */
class PacketEndpoint : boost::noncopyable
{
public:
    uint8_t & sequence_id;
    ReadBuffer * in;
    WriteBuffer * out;

    /// For writing.
    PacketEndpoint(WriteBuffer & out_, uint8_t & sequence_id_);

    /// For reading and writing.
    PacketEndpoint(ReadBuffer & in_, WriteBuffer & out_, uint8_t & sequence_id_);

    MySQLPacketPayloadReadBuffer getPayload();

    void receivePacket(IMySQLReadPacket & packet);

    bool tryReceivePacket(IMySQLReadPacket & packet, UInt64 millisecond = 0);

    /// Sets sequence-id to 0. Must be called before each command phase.
    void resetSequenceId();

    template<class T>
    void sendPacket(const T & packet, bool flush = false)
    {
        static_assert(std::is_base_of<IMySQLWritePacket, T>());
        packet.writePayload(*out, sequence_id);
        if (flush)
            out->next();
    }

    /// Converts packet to text. Is used for debug output.
    static String packetToText(const String & payload);
};

using PacketEndpointPtr = std::shared_ptr<PacketEndpoint>;

}

}