2012-03-09 15:46:52 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2013-08-04 00:42:35 +00:00
|
|
|
|
#include <DB/Core/Types.h>
|
|
|
|
|
|
|
|
|
|
|
2012-03-09 15:46:52 +00:00
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/** Протокол взаимодействия с сервером.
|
2012-05-16 18:03:00 +00:00
|
|
|
|
*
|
|
|
|
|
* Клиент соединяется с сервером и передаёт ему пакет Hello.
|
|
|
|
|
* Если версия не устраивает, то сервер может разорвать соединение.
|
|
|
|
|
* Сервер отвечает пакетом Hello.
|
|
|
|
|
* Если версия не устраивает, то клиент может разорвать соединение.
|
|
|
|
|
*
|
|
|
|
|
* Далее в цикле.
|
2012-05-17 19:15:53 +00:00
|
|
|
|
*
|
|
|
|
|
* 1. Клиент отправляет на сервер пакет Query.
|
2012-05-16 18:03:00 +00:00
|
|
|
|
*
|
2014-03-28 11:50:54 +00:00
|
|
|
|
* Начиная с версии 50263, сразу после отправки пакета Query клиент начинает передачу
|
|
|
|
|
* внешних (временных) таблиц (external storages) - один или несколько пакетов Data.
|
|
|
|
|
* Конец передачи данных определается по отправленному пустому блоку.
|
|
|
|
|
* В данный момент, не пустое множество таблиц может быть передано только вместе с запросом SELECT.
|
|
|
|
|
*
|
2012-05-21 06:49:05 +00:00
|
|
|
|
* Если запрос типа INSERT (требует передачи данных от клиента), то сервер передаёт
|
|
|
|
|
* пакет Data, содержащий пустой блок, который описывает структуру таблицы.
|
|
|
|
|
* Затем клиент отправляет данные для вставки
|
|
|
|
|
* - один или несколько пакетов Data.
|
|
|
|
|
* Конец данных определается по отправленному пустому блоку.
|
|
|
|
|
* Затем сервер отправляет клиенту пакет EndOfStream.
|
|
|
|
|
*
|
|
|
|
|
* Если запрос типа SELECT или другой, то сервер передаёт набор пакетов одного из следующих видов:
|
2012-05-16 18:03:00 +00:00
|
|
|
|
* - Data - данные результата выполнения запроса (один блок);
|
|
|
|
|
* - Progress - прогресс выполнения запроса;
|
|
|
|
|
* - Exception - ошибка;
|
|
|
|
|
* - EndOfStream - конец передачи данных;
|
|
|
|
|
*
|
|
|
|
|
* Клиент должен читать пакеты до EndOfStream или Exception.
|
|
|
|
|
* Также, клиент может передать на сервер пакет Cancel - отмена выполнения запроса.
|
|
|
|
|
* В этом случае, сервер может прервать выполнение запроса и вернуть неполные данные;
|
|
|
|
|
* но клиент всё равно должен читать все пакеты до EndOfStream.
|
2013-05-22 14:57:43 +00:00
|
|
|
|
*
|
|
|
|
|
* Перед пакетом EndOfStream, если есть профайлинговая информация и ревизия клиента достаточно новая,
|
2013-09-05 20:22:43 +00:00
|
|
|
|
* может быть отправлен пакет Totals и/или ProfileInfo.
|
|
|
|
|
* Totals - блок с тотальными значениями.
|
|
|
|
|
* ProfileInfo - данные профайлинга - сериализованная структура BlockStreamProfileInfo.
|
2013-06-19 13:09:28 +00:00
|
|
|
|
*
|
|
|
|
|
* При запросах, которые возвращают данные, сервер, перед обработкой запроса,
|
|
|
|
|
* отправляет заголовочный блок, содержащий описание столбцов из запроса, но с нулем строк.
|
|
|
|
|
* Используя этот заголовочный блок, клиент может заранее проинициализировать формат вывода
|
|
|
|
|
* и вывести префикс таблицы результата.
|
2012-05-16 18:03:00 +00:00
|
|
|
|
*
|
2012-05-17 19:15:53 +00:00
|
|
|
|
* 2. Между запросами, клиент может отправить Ping, и сервер должен ответить Pong.
|
2012-03-09 15:46:52 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace Protocol
|
|
|
|
|
{
|
|
|
|
|
/// То, что передаёт сервер.
|
|
|
|
|
namespace Server
|
|
|
|
|
{
|
|
|
|
|
enum Enum
|
|
|
|
|
{
|
2012-05-16 18:03:00 +00:00
|
|
|
|
Hello = 0, /// Имя, версия, ревизия.
|
2012-05-21 06:49:05 +00:00
|
|
|
|
Data = 1, /// Блок данных со сжатием или без.
|
2012-05-16 18:03:00 +00:00
|
|
|
|
Exception = 2, /// Исключение во время обработки запроса.
|
|
|
|
|
Progress = 3, /// Прогресс выполнения запроса: строк считано, байт считано.
|
|
|
|
|
Pong = 4, /// Ответ на Ping.
|
|
|
|
|
EndOfStream = 5, /// Все пакеты были переданы.
|
2013-09-05 20:22:43 +00:00
|
|
|
|
ProfileInfo = 6, /// Пакет с профайлинговой информацией.
|
|
|
|
|
Totals = 7, /// Блок данных с тотальными значениями, со сжатием или без.
|
2013-09-07 02:03:13 +00:00
|
|
|
|
Extremes = 8, /// Блок данных с минимумами и максимумами, аналогично.
|
2012-03-09 15:46:52 +00:00
|
|
|
|
};
|
2012-05-23 19:51:30 +00:00
|
|
|
|
|
2013-08-04 00:42:35 +00:00
|
|
|
|
/** NOTE: Если бы в качестве типа агрумента функции был бы Enum, то сравнение packet >= 0 && packet < 7
|
|
|
|
|
* срабатывало бы всегда из-за оптимизации компилятором, даже если packet некорректный, и было бы чтение за границей массива.
|
2013-08-04 00:58:07 +00:00
|
|
|
|
* https://www.securecoding.cert.org/confluence/display/cplusplus/INT36-CPP.+Do+not+use+out-of-range+enumeration+values
|
2013-08-04 00:42:35 +00:00
|
|
|
|
*/
|
|
|
|
|
inline const char * toString(UInt64 packet)
|
2012-05-23 19:51:30 +00:00
|
|
|
|
{
|
2013-09-07 02:03:13 +00:00
|
|
|
|
static const char * data[] = { "Hello", "Data", "Exception", "Progress", "Pong", "EndOfStream", "ProfileInfo", "Totals", "Extremes" };
|
2014-03-10 04:17:17 +00:00
|
|
|
|
return packet < 9
|
2012-10-12 17:54:26 +00:00
|
|
|
|
? data[packet]
|
|
|
|
|
: "Unknown packet";
|
2012-05-23 19:51:30 +00:00
|
|
|
|
}
|
2012-03-09 15:46:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// То, что передаёт клиент.
|
|
|
|
|
namespace Client
|
|
|
|
|
{
|
|
|
|
|
enum Enum
|
|
|
|
|
{
|
2012-05-30 06:46:57 +00:00
|
|
|
|
Hello = 0, /// Имя, версия, ревизия, БД по-умолчанию.
|
2013-02-01 19:02:04 +00:00
|
|
|
|
Query = 1, /** Идентификатор запроса, настройки на отдельный запрос,
|
|
|
|
|
* информация, до какой стадии исполнять запрос,
|
2012-05-21 06:49:05 +00:00
|
|
|
|
* использовать ли сжатие, текст запроса (без данных для INSERT-а).
|
|
|
|
|
*/
|
|
|
|
|
Data = 2, /// Блок данных со сжатием или без.
|
2012-05-16 18:03:00 +00:00
|
|
|
|
Cancel = 3, /// Отменить выполнение запроса.
|
|
|
|
|
Ping = 4, /// Проверка живости соединения с сервером.
|
2012-03-09 15:46:52 +00:00
|
|
|
|
};
|
2012-05-23 19:51:30 +00:00
|
|
|
|
|
2013-08-04 00:42:35 +00:00
|
|
|
|
inline const char * toString(UInt64 packet)
|
2012-05-23 19:51:30 +00:00
|
|
|
|
{
|
|
|
|
|
static const char * data[] = { "Hello", "Query", "Data", "Cancel", "Ping" };
|
2014-03-10 04:17:17 +00:00
|
|
|
|
return packet < 5
|
2012-10-12 17:54:26 +00:00
|
|
|
|
? data[packet]
|
|
|
|
|
: "Unknown packet";
|
2012-05-23 19:51:30 +00:00
|
|
|
|
}
|
2012-03-09 15:46:52 +00:00
|
|
|
|
}
|
2012-03-11 08:52:56 +00:00
|
|
|
|
|
|
|
|
|
/// Использовать ли сжатие.
|
|
|
|
|
namespace Compression
|
|
|
|
|
{
|
|
|
|
|
enum Enum
|
|
|
|
|
{
|
2012-03-19 12:57:56 +00:00
|
|
|
|
Disable = 0,
|
|
|
|
|
Enable = 1,
|
2012-03-11 08:52:56 +00:00
|
|
|
|
};
|
|
|
|
|
}
|
2012-03-09 15:46:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|