From f71d00d6f5a4966a3c9e99a42484567e204b0e31 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 29 Jul 2009 17:34:49 +0000 Subject: [PATCH] dbms: development. --- dbms/include/DB/ColumnType.h | 39 +++++++++++++++++++++++++++++++-- dbms/include/DB/ErrorCodes.h | 3 ++- dbms/src/tests/istream_test.cpp | 24 ++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 dbms/src/tests/istream_test.cpp diff --git a/dbms/include/DB/ColumnType.h b/dbms/include/DB/ColumnType.h index d9a12969dee..3a6b2646686 100644 --- a/dbms/include/DB/ColumnType.h +++ b/dbms/include/DB/ColumnType.h @@ -511,6 +511,39 @@ public: }; +/** IP адрес. Отличается от UInt32 текстовой сериализацией. */ +class ColumnTypeIPAddress : public ColumnTypeUInt32 +{ +public: + std::string getName() const { return "IPAddress"; } + + void serializeText(const DB::Field & field, std::ostream & ostr) const + { + UInt x = boost::get(field); + ostr << static_cast((x >> 24) & 0xFF) + << "." << static_cast((x >> 16) & 0xFF) + << "." << static_cast((x >> 8) & 0xFF) + << "." << static_cast(x & 0xFF); + } + + void deserializeText(DB::Field & field, std::istream & istr) const + { + Poco::UInt32 n1, n2, n3, n4; + istr >> n1; + istr.ignore(); + istr >> n2; + istr.ignore(); + istr >> n3; + istr.ignore(); + istr >> n4; + istr.ignore(); + if (n1 > 255 || n2 > 255 || n3 > 255 || n4 > 255) + throw Exception("Invalid IP address", ErrorCodes::INVALID_IP_ADDRESS); + boost::get(field) = (n1 << 24) | (n2 << 16) | (n3 << 8) | n4; + } +}; + + class ColumnTypeFactory { public: @@ -530,6 +563,8 @@ public: return new ColumnTypeUInt64; if (name == "Text") return new ColumnTypeText; + if (name == "IPAddress") + return new ColumnTypeIPAddress; /// параметризованные типы static Poco::RegularExpression one_parameter_regexp("^([^\\(]+)\\((.+)\\)$"); @@ -537,7 +572,7 @@ public: Poco::RegularExpression::MatchVec matches; - if (two_parameters_regexp.match(name, 0, matches)) + if (two_parameters_regexp.match(name, 0, matches) && matches.size() == 3) { /// FixedArray(T, N), где T - любой тип, а N - размер if (name.substr(matches[0].offset, matches[0].length) == "FixedArray") @@ -554,7 +589,7 @@ public: } } - if (one_parameter_regexp.match(name, 0, matches)) + if (one_parameter_regexp.match(name, 0, matches) && matches.size() == 2) { /// FixedText(N), где N - размер if (name.substr(matches[0].offset, matches[0].length) == "FixedText") diff --git a/dbms/include/DB/ErrorCodes.h b/dbms/include/DB/ErrorCodes.h index ec6ba312922..e4279b5da2e 100644 --- a/dbms/include/DB/ErrorCodes.h +++ b/dbms/include/DB/ErrorCodes.h @@ -18,7 +18,8 @@ namespace ErrorCodes TOO_FEW_COLUMNS_FOR_KEY, STORAGE_WAS_NOT_ATTACHED, CANT_READ_DATA_FILE, - TOO_MANY_COLUMNS_FOR_KEY + TOO_MANY_COLUMNS_FOR_KEY, + INVALID_IP_ADDRESS, }; } diff --git a/dbms/src/tests/istream_test.cpp b/dbms/src/tests/istream_test.cpp new file mode 100644 index 00000000000..23b6866a78a --- /dev/null +++ b/dbms/src/tests/istream_test.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(int argc, char ** argv) +{ + std::stringstream s; + s << "192.168.1.1fls"; + + unsigned x; + s >> x; + s.get(); + std::cout << x << std::endl; + s >> x; + s.get(); + std::cout << x << std::endl; + s >> x; + s.get(); + std::cout << x << std::endl; + s >> x; + std::cout << x << std::endl; + + return 0; +}