2019-01-23 19:39:19 +00:00
|
|
|
#pragma once
|
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
#include <common/DayNum.h>
|
|
|
|
#include <Common/UInt128.h>
|
2019-01-23 19:39:19 +00:00
|
|
|
#include <Core/UUID.h>
|
2019-02-22 14:22:12 +00:00
|
|
|
|
|
|
|
#include <Common/config.h>
|
|
|
|
#if USE_PROTOBUF
|
|
|
|
|
2019-01-23 19:39:19 +00:00
|
|
|
#include <boost/noncopyable.hpp>
|
2019-02-22 14:19:07 +00:00
|
|
|
#include <IO/WriteBufferFromString.h>
|
2019-01-23 19:39:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace google
|
|
|
|
{
|
|
|
|
namespace protobuf
|
|
|
|
{
|
|
|
|
class Descriptor;
|
|
|
|
class FieldDescriptor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
class IAggregateFunction;
|
|
|
|
using AggregateFunctionPtr = std::shared_ptr<IAggregateFunction>;
|
|
|
|
using ConstAggregateDataPtr = const char *;
|
|
|
|
|
|
|
|
|
|
|
|
/** Serializes a protobuf, tries to cast types if necessarily.
|
|
|
|
*/
|
|
|
|
class ProtobufWriter : private boost::noncopyable
|
|
|
|
{
|
|
|
|
public:
|
2019-02-22 14:22:12 +00:00
|
|
|
ProtobufWriter(WriteBuffer & out, const google::protobuf::Descriptor * message_type);
|
|
|
|
~ProtobufWriter();
|
2019-01-23 19:39:19 +00:00
|
|
|
|
|
|
|
/// Returns fields of the protobuf schema sorted by their numbers.
|
|
|
|
const std::vector<const google::protobuf::FieldDescriptor *> & fieldsInWriteOrder() const;
|
|
|
|
|
|
|
|
/// Should be called when we start writing a new message.
|
2019-02-22 14:22:12 +00:00
|
|
|
void newMessage();
|
2019-01-23 19:39:19 +00:00
|
|
|
|
|
|
|
/// Should be called when we start writing a new field.
|
|
|
|
/// Returns false if there is no more fields in the message type.
|
2019-02-22 14:22:12 +00:00
|
|
|
bool nextField();
|
2019-01-23 19:39:19 +00:00
|
|
|
|
|
|
|
/// Returns the current field of the message type.
|
|
|
|
/// The value returned by this function changes after calling nextField() or newMessage().
|
|
|
|
const google::protobuf::FieldDescriptor * currentField() const { return current_field; }
|
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
void writeNumber(Int8 value);
|
|
|
|
void writeNumber(UInt8 value);
|
|
|
|
void writeNumber(Int16 value);
|
|
|
|
void writeNumber(UInt16 value);
|
|
|
|
void writeNumber(Int32 value);
|
|
|
|
void writeNumber(UInt32 value);
|
|
|
|
void writeNumber(Int64 value);
|
|
|
|
void writeNumber(UInt64 value);
|
|
|
|
void writeNumber(UInt128 value);
|
|
|
|
void writeNumber(Float32 value);
|
|
|
|
void writeNumber(Float64 value);
|
2019-01-23 19:39:19 +00:00
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
void writeString(const StringRef & value);
|
2019-01-23 19:39:19 +00:00
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
void prepareEnumMapping(const std::vector<std::pair<std::string, Int8>> & name_value_pairs);
|
|
|
|
void prepareEnumMapping(const std::vector<std::pair<std::string, Int16>> & name_value_pairs);
|
|
|
|
void writeEnum(Int8 value);
|
|
|
|
void writeEnum(Int16 value);
|
2019-01-23 19:39:19 +00:00
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
void writeUUID(const UUID & value);
|
|
|
|
void writeDate(DayNum date);
|
|
|
|
void writeDateTime(time_t tm);
|
2019-01-23 19:39:19 +00:00
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
void writeDecimal(Decimal32 decimal, UInt32 scale);
|
|
|
|
void writeDecimal(Decimal64 decimal, UInt32 scale);
|
|
|
|
void writeDecimal(const Decimal128 & decimal, UInt32 scale);
|
2019-01-23 19:39:19 +00:00
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
void writeAggregateFunction(const AggregateFunctionPtr & function, ConstAggregateDataPtr place);
|
2019-01-23 19:39:19 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void enumerateFieldsInWriteOrder(const google::protobuf::Descriptor * message_type);
|
|
|
|
void createConverters();
|
|
|
|
|
|
|
|
void finishCurrentMessage();
|
|
|
|
void finishCurrentField();
|
|
|
|
|
2019-02-22 14:19:07 +00:00
|
|
|
class SimpleWriter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleWriter(WriteBuffer & out_);
|
|
|
|
~SimpleWriter();
|
|
|
|
|
|
|
|
void newMessage();
|
|
|
|
void setCurrentField(UInt32 field_number);
|
|
|
|
UInt32 currentFieldNumber() const { return current_field_number; }
|
|
|
|
size_t numValues() const { return num_normal_values + num_packed_values; }
|
|
|
|
|
|
|
|
void writeInt32(Int32 value);
|
|
|
|
void writeUInt32(UInt32 value);
|
|
|
|
void writeSInt32(Int32 value);
|
|
|
|
void writeInt64(Int64 value);
|
|
|
|
void writeUInt64(UInt64 value);
|
|
|
|
void writeSInt64(Int64 value);
|
|
|
|
void writeFixed32(UInt32 value);
|
|
|
|
void writeSFixed32(Int32 value);
|
|
|
|
void writeFloat(float value);
|
|
|
|
void writeFixed64(UInt64 value);
|
|
|
|
void writeSFixed64(Int64 value);
|
|
|
|
void writeDouble(double value);
|
|
|
|
void writeString(const StringRef & str);
|
|
|
|
|
|
|
|
void writeInt32IfNonZero(Int32 value);
|
|
|
|
void writeUInt32IfNonZero(UInt32 value);
|
|
|
|
void writeSInt32IfNonZero(Int32 value);
|
|
|
|
void writeInt64IfNonZero(Int64 value);
|
|
|
|
void writeUInt64IfNonZero(UInt64 value);
|
|
|
|
void writeSInt64IfNonZero(Int64 value);
|
|
|
|
void writeFixed32IfNonZero(UInt32 value);
|
|
|
|
void writeSFixed32IfNonZero(Int32 value);
|
|
|
|
void writeFloatIfNonZero(float value);
|
|
|
|
void writeFixed64IfNonZero(UInt64 value);
|
|
|
|
void writeSFixed64IfNonZero(Int64 value);
|
|
|
|
void writeDoubleIfNonZero(double value);
|
|
|
|
void writeStringIfNotEmpty(const StringRef & str);
|
|
|
|
|
|
|
|
void packRepeatedInt32(Int32 value);
|
|
|
|
void packRepeatedUInt32(UInt32 value);
|
|
|
|
void packRepeatedSInt32(Int32 value);
|
|
|
|
void packRepeatedInt64(Int64 value);
|
|
|
|
void packRepeatedUInt64(UInt64 value);
|
|
|
|
void packRepeatedSInt64(Int64 value);
|
|
|
|
void packRepeatedFixed32(UInt32 value);
|
|
|
|
void packRepeatedSFixed32(Int32 value);
|
|
|
|
void packRepeatedFloat(float value);
|
|
|
|
void packRepeatedFixed64(UInt64 value);
|
|
|
|
void packRepeatedSFixed64(Int64 value);
|
|
|
|
void packRepeatedDouble(double value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
void finishCurrentMessage();
|
|
|
|
void finishCurrentField();
|
|
|
|
|
|
|
|
enum WireType : UInt32;
|
|
|
|
void writeKey(WireType wire_type, WriteBuffer & buf);
|
|
|
|
|
|
|
|
WriteBuffer & out;
|
|
|
|
bool were_messages = false;
|
|
|
|
WriteBufferFromOwnString message_buffer;
|
|
|
|
UInt32 current_field_number = 0;
|
|
|
|
size_t num_normal_values = 0;
|
|
|
|
size_t num_packed_values = 0;
|
|
|
|
WriteBufferFromOwnString repeated_packing_buffer;
|
|
|
|
};
|
|
|
|
|
|
|
|
SimpleWriter simple_writer;
|
2019-01-23 19:39:19 +00:00
|
|
|
std::vector<const google::protobuf::FieldDescriptor *> fields_in_write_order;
|
|
|
|
size_t current_field_index = -1;
|
|
|
|
const google::protobuf::FieldDescriptor * current_field = nullptr;
|
|
|
|
|
|
|
|
class Converter;
|
|
|
|
class ToStringConverter;
|
|
|
|
template <typename T>
|
|
|
|
class ToNumberConverter;
|
|
|
|
class ToBoolConverter;
|
|
|
|
class ToEnumConverter;
|
|
|
|
|
|
|
|
std::vector<std::unique_ptr<Converter>> converters;
|
|
|
|
Converter * current_converter = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
2019-02-15 11:46:07 +00:00
|
|
|
|
2019-02-22 14:22:12 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
class IAggregateFunction;
|
|
|
|
using AggregateFunctionPtr = std::shared_ptr<IAggregateFunction>;
|
|
|
|
using ConstAggregateDataPtr = const char *;
|
|
|
|
|
|
|
|
class ProtobufWriter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void writeNumber(Int8 value) {}
|
|
|
|
void writeNumber(UInt8 value) {}
|
|
|
|
void writeNumber(Int16 value) {}
|
|
|
|
void writeNumber(UInt16 value) {}
|
|
|
|
void writeNumber(Int32 value) {}
|
|
|
|
void writeNumber(UInt32 value) {}
|
|
|
|
void writeNumber(Int64 value) {}
|
|
|
|
void writeNumber(UInt64 value) {}
|
|
|
|
void writeNumber(UInt128 value) {}
|
|
|
|
void writeNumber(Float32 value) {}
|
|
|
|
void writeNumber(Float64 value) {}
|
|
|
|
void writeString(const StringRef & value) {}
|
|
|
|
void prepareEnumMapping(const std::vector<std::pair<std::string, Int8>> & name_value_pairs) {}
|
|
|
|
void prepareEnumMapping(const std::vector<std::pair<std::string, Int16>> & name_value_pairs) {}
|
|
|
|
void writeEnum(Int8 value) {}
|
|
|
|
void writeEnum(Int16 value) {}
|
|
|
|
void writeUUID(const UUID & value) {}
|
|
|
|
void writeDate(DayNum date) {}
|
|
|
|
void writeDateTime(time_t tm) {}
|
|
|
|
void writeDecimal(Decimal32 decimal, UInt32 scale) {}
|
|
|
|
void writeDecimal(Decimal64 decimal, UInt32 scale) {}
|
|
|
|
void writeDecimal(const Decimal128 & decimal, UInt32 scale) {}
|
|
|
|
void writeAggregateFunction(const AggregateFunctionPtr & function, ConstAggregateDataPtr place) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
2019-02-15 11:46:07 +00:00
|
|
|
#endif
|