2012-03-09 15:46:52 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2012-03-11 08:52:56 +00:00
|
|
|
|
#include <DB/Core/Protocol.h>
|
|
|
|
|
|
2012-03-25 03:47:13 +00:00
|
|
|
|
#include <DB/IO/ChunkedReadBuffer.h>
|
|
|
|
|
#include <DB/IO/ChunkedWriteBuffer.h>
|
2012-03-19 12:57:56 +00:00
|
|
|
|
#include <DB/IO/ReadHelpers.h>
|
|
|
|
|
#include <DB/IO/WriteHelpers.h>
|
|
|
|
|
|
2012-03-11 08:52:56 +00:00
|
|
|
|
#include <DB/DataStreams/BlockIO.h>
|
|
|
|
|
|
2012-03-09 15:46:52 +00:00
|
|
|
|
#include "Server.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2012-03-11 08:52:56 +00:00
|
|
|
|
|
|
|
|
|
/// Состояние обработки запроса.
|
|
|
|
|
struct QueryState
|
|
|
|
|
{
|
|
|
|
|
/// Идентификатор запроса.
|
|
|
|
|
UInt64 query_id;
|
|
|
|
|
|
|
|
|
|
Protocol::QueryProcessingStage::Enum stage;
|
|
|
|
|
Protocol::Compression::Enum compression;
|
|
|
|
|
String in_format;
|
|
|
|
|
String out_format;
|
|
|
|
|
|
2012-03-19 12:57:56 +00:00
|
|
|
|
/// Откуда читать данные для INSERT-а.
|
|
|
|
|
SharedPtr<ReadBuffer> chunked_in;
|
|
|
|
|
SharedPtr<ReadBuffer> maybe_compressed_in;
|
|
|
|
|
BlockInputStreamPtr block_in;
|
|
|
|
|
|
|
|
|
|
/// Куда писать возвращаемые данные.
|
|
|
|
|
SharedPtr<WriteBuffer> chunked_out;
|
|
|
|
|
SharedPtr<WriteBuffer> maybe_compressed_out;
|
|
|
|
|
BlockOutputStreamPtr block_out;
|
|
|
|
|
|
2012-03-11 08:52:56 +00:00
|
|
|
|
/// Текст запроса.
|
|
|
|
|
String query;
|
|
|
|
|
/// Потоки блоков, с помощью которых выполнять запрос.
|
|
|
|
|
BlockIO io;
|
|
|
|
|
|
|
|
|
|
Context context;
|
|
|
|
|
|
|
|
|
|
QueryState() : query_id(0), stage(Protocol::QueryProcessingStage::Complete), compression(Protocol::Compression::Disable) {}
|
|
|
|
|
|
|
|
|
|
void reset()
|
|
|
|
|
{
|
|
|
|
|
query_id = 0;
|
|
|
|
|
stage = Protocol::QueryProcessingStage::Complete;
|
|
|
|
|
compression = Protocol::Compression::Disable;
|
|
|
|
|
in_format.clear();
|
|
|
|
|
out_format.clear();
|
|
|
|
|
query.clear();
|
|
|
|
|
io = BlockIO();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool empty()
|
|
|
|
|
{
|
|
|
|
|
return query_id == 0;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2012-03-09 15:46:52 +00:00
|
|
|
|
class TCPHandler : public Poco::Net::TCPServerConnection
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TCPHandler(Server & server_, const Poco::Net::StreamSocket & socket_)
|
|
|
|
|
: Poco::Net::TCPServerConnection(socket_), server(server_)
|
|
|
|
|
, log(&Logger::get("TCPHandler"))
|
|
|
|
|
{
|
|
|
|
|
LOG_TRACE(log, "In constructor.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void run();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Server & server;
|
|
|
|
|
Logger * log;
|
|
|
|
|
|
2012-03-11 08:52:56 +00:00
|
|
|
|
/// На данный момент, поддерживается одновременное выполнение только одного запроса в соединении.
|
|
|
|
|
QueryState state;
|
|
|
|
|
|
2012-03-09 15:46:52 +00:00
|
|
|
|
void runImpl();
|
2012-03-11 08:52:56 +00:00
|
|
|
|
|
|
|
|
|
void sendHello(WriteBuffer & out);
|
2012-03-19 12:57:56 +00:00
|
|
|
|
bool sendData(WriteBuffer & out, WriteBuffer & out_for_chunks);
|
2012-03-11 08:52:56 +00:00
|
|
|
|
void sendException(WriteBuffer & out);
|
|
|
|
|
void sendProgress(WriteBuffer & out);
|
|
|
|
|
|
2012-03-19 12:57:56 +00:00
|
|
|
|
bool receivePacket(ReadBuffer & in);
|
2012-03-11 08:52:56 +00:00
|
|
|
|
void receiveQuery(ReadBuffer & in);
|
2012-03-19 12:57:56 +00:00
|
|
|
|
bool receiveData(ReadBuffer & in);
|
2012-03-09 15:46:52 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-03-11 08:52:56 +00:00
|
|
|
|
|
2012-03-09 15:46:52 +00:00
|
|
|
|
}
|