mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
SSQLS: added methods to read/write in tab-separated format with ReadBuffer/WriteBuffer [#CONV-3632].
This commit is contained in:
parent
eff4e7a65f
commit
b595e61c03
@ -8,6 +8,9 @@
|
||||
|
||||
#include <Yandex/DateLUT.h>
|
||||
|
||||
#include <mysqlxx/Date.h>
|
||||
#include <mysqlxx/DateTime.h>
|
||||
|
||||
#include <DB/Core/Types.h>
|
||||
#include <DB/Core/Exception.h>
|
||||
#include <DB/Core/ErrorCodes.h>
|
||||
@ -96,7 +99,15 @@ inline void readChar(char & x, ReadBuffer & buf)
|
||||
|
||||
void assertString(const char * s, ReadBuffer & buf);
|
||||
|
||||
/// грубо
|
||||
|
||||
inline void readBoolText(bool & x, ReadBuffer & buf)
|
||||
{
|
||||
char tmp = '0';
|
||||
readChar(tmp, buf);
|
||||
x = tmp != '0';
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void readIntText(T & x, ReadBuffer & buf)
|
||||
{
|
||||
@ -250,20 +261,6 @@ void readFloatText(T & x, ReadBuffer & buf)
|
||||
x = -x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void readText(T & x, ReadBuffer & buf);
|
||||
|
||||
template <> inline void readText<UInt8> (UInt8 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<UInt16> (UInt16 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<UInt32> (UInt32 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<UInt64> (UInt64 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int8> (Int8 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int16> (Int16 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int32> (Int32 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int64> (Int64 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Float32> (Float32 & x, ReadBuffer & buf) { readFloatText(x, buf); }
|
||||
template <> inline void readText<Float64> (Float64 & x, ReadBuffer & buf) { readFloatText(x, buf); }
|
||||
|
||||
|
||||
/// грубо; всё до '\n' или '\t'
|
||||
void readString(String & s, ReadBuffer & buf);
|
||||
@ -295,6 +292,21 @@ inline void readDateText(Yandex::DayNum_t & date, ReadBuffer & buf)
|
||||
date = Yandex::DateLUTSingleton::instance().makeDayNum(year, month, day);
|
||||
}
|
||||
|
||||
inline void readDateText(mysqlxx::Date & date, ReadBuffer & buf)
|
||||
{
|
||||
char s[10];
|
||||
size_t size = buf.read(s, 10);
|
||||
if (10 != size)
|
||||
{
|
||||
s[size] = 0;
|
||||
throw Exception(std::string("Cannot parse date ") + s, ErrorCodes::CANNOT_PARSE_DATE);
|
||||
}
|
||||
|
||||
date.year((s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0'));
|
||||
date.month((s[5] - '0') * 10 + (s[6] - '0'));
|
||||
date.day((s[8] - '0') * 10 + (s[9] - '0'));
|
||||
}
|
||||
|
||||
|
||||
/// в формате YYYY-MM-DD HH:MM:SS, согласно текущему часовому поясу
|
||||
inline void readDateTimeText(time_t & datetime, ReadBuffer & buf)
|
||||
@ -318,6 +330,49 @@ inline void readDateTimeText(time_t & datetime, ReadBuffer & buf)
|
||||
datetime = Yandex::DateLUTSingleton::instance().makeDateTime(year, month, day, hour, minute, second);
|
||||
}
|
||||
|
||||
inline void readDateTimeText(mysqlxx::DateTime & datetime, ReadBuffer & buf)
|
||||
{
|
||||
char s[19];
|
||||
size_t size = buf.read(s, 19);
|
||||
if (19 != size)
|
||||
{
|
||||
s[size] = 0;
|
||||
throw Exception(std::string("Cannot parse datetime ") + s, ErrorCodes::CANNOT_PARSE_DATETIME);
|
||||
}
|
||||
|
||||
datetime.year((s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0'));
|
||||
datetime.month((s[5] - '0') * 10 + (s[6] - '0'));
|
||||
datetime.day((s[8] - '0') * 10 + (s[9] - '0'));
|
||||
|
||||
datetime.hour((s[11] - '0') * 10 + (s[12] - '0'));
|
||||
datetime.minute((s[14] - '0') * 10 + (s[15] - '0'));
|
||||
datetime.second((s[17] - '0') * 10 + (s[18] - '0'));
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void readText(T & x, ReadBuffer & buf)
|
||||
{
|
||||
/// Переношу ошибку в рантайм, так как метод требуется для компиляции DBObject-ов
|
||||
throw Exception("Method readText is not implemented for this type.", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
template <> inline void readText<UInt8> (UInt8 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<UInt16> (UInt16 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<UInt32> (UInt32 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<UInt64> (UInt64 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int8> (Int8 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int16> (Int16 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int32> (Int32 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Int64> (Int64 & x, ReadBuffer & buf) { readIntText(x, buf); }
|
||||
template <> inline void readText<Float32> (Float32 & x, ReadBuffer & buf) { readFloatText(x, buf); }
|
||||
template <> inline void readText<Float64> (Float64 & x, ReadBuffer & buf) { readFloatText(x, buf); }
|
||||
template <> inline void readText<String> (String & x, ReadBuffer & buf) { readEscapedString(x, buf); }
|
||||
template <> inline void readText<bool> (bool & x, ReadBuffer & buf) { readBoolText(x, buf); }
|
||||
|
||||
template <> inline void readText<mysqlxx::Date> (mysqlxx::Date & x, ReadBuffer & buf) { readDateText(x, buf); }
|
||||
template <> inline void readText<mysqlxx::DateTime> (mysqlxx::DateTime & x, ReadBuffer & buf) { readDateTimeText(x, buf); }
|
||||
|
||||
|
||||
/// Пропустить пробельные символы.
|
||||
inline void skipWhitespaceIfAny(ReadBuffer & buf)
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include <Yandex/DateLUT.h>
|
||||
|
||||
#include <mysqlxx/Row.h>
|
||||
|
||||
#include <DB/Core/Types.h>
|
||||
#include <DB/Core/Exception.h>
|
||||
#include <DB/Core/ErrorCodes.h>
|
||||
@ -59,6 +61,12 @@ inline void writeStringBinary(const std::string & s, DB::WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
inline void writeBoolText(bool x, WriteBuffer & buf)
|
||||
{
|
||||
writeChar(x ? '1' : '0', buf);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void writeIntText(T x, WriteBuffer & buf)
|
||||
{
|
||||
@ -105,19 +113,6 @@ void writeFloatText(T x, WriteBuffer & buf, unsigned precision = WRITE_HELPERS_D
|
||||
buf.write(tmp, res);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writeText(T x, WriteBuffer & buf);
|
||||
|
||||
template <> inline void writeText<UInt8> (UInt8 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<UInt16> (UInt16 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<UInt32> (UInt32 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<UInt64> (UInt64 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int8> (Int8 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int16> (Int16 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int32> (Int32 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int64> (Int64 x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Float32> (Float32 x, WriteBuffer & buf) { writeFloatText(x, buf); }
|
||||
template <> inline void writeText<Float64> (Float64 x, WriteBuffer & buf) { writeFloatText(x, buf); }
|
||||
|
||||
inline void writeString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
@ -126,9 +121,9 @@ inline void writeString(const String & s, WriteBuffer & buf)
|
||||
|
||||
|
||||
template <char c>
|
||||
void writeAnyEscapedString(const String & s, WriteBuffer & buf)
|
||||
void writeAnyEscapedString(const char * begin, const char * end, WriteBuffer & buf)
|
||||
{
|
||||
for (String::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
for (const char * it = begin; it != end; ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
@ -171,6 +166,13 @@ void writeAnyEscapedString(const String & s, WriteBuffer & buf)
|
||||
}
|
||||
|
||||
|
||||
template <char c>
|
||||
void writeAnyEscapedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
writeAnyEscapedString<c>(s.data(), s.data() + s.size(), buf);
|
||||
}
|
||||
|
||||
|
||||
inline void writeEscapedString(const String & s, WriteBuffer & buf)
|
||||
{
|
||||
writeAnyEscapedString<'\''>(s, buf);
|
||||
@ -248,6 +250,22 @@ inline void writeDateText(Yandex::DayNum_t date, WriteBuffer & buf)
|
||||
buf.write(s, 10);
|
||||
}
|
||||
|
||||
inline void writeDateText(mysqlxx::Date date, WriteBuffer & buf)
|
||||
{
|
||||
char s[10] = {'0', '0', '0', '0', '-', '0', '0', '-', '0', '0'};
|
||||
|
||||
s[0] += date.year() / 1000;
|
||||
s[1] += (date.year() / 100) % 10;
|
||||
s[2] += (date.year() / 10) % 10;
|
||||
s[3] += date.year() % 10;
|
||||
s[5] += date.month() / 10;
|
||||
s[6] += date.month() % 10;
|
||||
s[8] += date.day() / 10;
|
||||
s[9] += date.day() % 10;
|
||||
|
||||
buf.write(s, 10);
|
||||
}
|
||||
|
||||
|
||||
/// в формате YYYY-MM-DD HH:MM:SS, согласно текущему часовому поясу
|
||||
inline void writeDateTimeText(time_t datetime, WriteBuffer & buf)
|
||||
@ -286,5 +304,71 @@ inline void writeDateTimeText(time_t datetime, WriteBuffer & buf)
|
||||
buf.write(s, 19);
|
||||
}
|
||||
|
||||
inline void writeDateTimeText(mysqlxx::DateTime datetime, WriteBuffer & buf)
|
||||
{
|
||||
char s[19] = {'0', '0', '0', '0', '-', '0', '0', '-', '0', '0', ' ', '0', '0', ':', '0', '0', ':', '0', '0'};
|
||||
|
||||
s[0] += datetime.year() / 1000;
|
||||
s[1] += (datetime.year() / 100) % 10;
|
||||
s[2] += (datetime.year() / 10) % 10;
|
||||
s[3] += datetime.year() % 10;
|
||||
s[5] += datetime.month() / 10;
|
||||
s[6] += datetime.month() % 10;
|
||||
s[8] += datetime.day() / 10;
|
||||
s[9] += datetime.day() % 10;
|
||||
|
||||
s[11] += datetime.hour() / 10;
|
||||
s[12] += datetime.hour() % 10;
|
||||
s[14] += datetime.minute() / 10;
|
||||
s[15] += datetime.minute() % 10;
|
||||
s[17] += datetime.second() / 10;
|
||||
s[18] += datetime.second() % 10;
|
||||
|
||||
buf.write(s, 19);
|
||||
}
|
||||
|
||||
|
||||
/// Вывести mysqlxx::Row в tab-separated виде
|
||||
inline void writeEscapedRow(const mysqlxx::Row & row, WriteBuffer & buf)
|
||||
{
|
||||
for (size_t i = 0; i < row.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
buf.write('\t');
|
||||
|
||||
if (unlikely(row[i].isNull()))
|
||||
{
|
||||
buf.write("\\N", 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
writeAnyEscapedString<'\''>(row[i].data(), row[i].data() + row[i].length(), buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void writeText(const T & x, WriteBuffer & buf)
|
||||
{
|
||||
/// Переношу ошибку в рантайм, так как метод требуется для компиляции DBObject-ов
|
||||
throw Exception("Method writeText is not implemented for this type.", ErrorCodes::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
template <> inline void writeText<UInt8> (const UInt8 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<UInt16> (const UInt16 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<UInt32> (const UInt32 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<UInt64> (const UInt64 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int8> (const Int8 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int16> (const Int16 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int32> (const Int32 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Int64> (const Int64 & x, WriteBuffer & buf) { writeIntText(x, buf); }
|
||||
template <> inline void writeText<Float32> (const Float32 & x, WriteBuffer & buf) { writeFloatText(x, buf); }
|
||||
template <> inline void writeText<Float64> (const Float64 & x, WriteBuffer & buf) { writeFloatText(x, buf); }
|
||||
template <> inline void writeText<String> (const String & x, WriteBuffer & buf) { writeEscapedString(x, buf); }
|
||||
template <> inline void writeText<bool> (const bool & x, WriteBuffer & buf) { writeBoolText(x, buf); }
|
||||
|
||||
template <> inline void writeText<mysqlxx::Date> (const mysqlxx::Date & x, WriteBuffer & buf) { writeDateText(x, buf); }
|
||||
template <> inline void writeText<mysqlxx::DateTime> (const mysqlxx::DateTime & x, WriteBuffer & buf) { writeDateTimeText(x, buf); }
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user