#ifndef DBMS_CORE_FIELD_H #define DBMS_CORE_FIELD_H #include #include #include #include #include #include #include #include namespace DB { /** Типы данных для представления единичного значения произвольного типа в оперативке. * Внимание! Предпочтительно вместо единичных значений хранить кусочки столбцов. См. Column.h */ typedef boost::make_recursive_variant< Null, UInt64, Int64, Float64, String, std::vector /// Array, Tuple >::type Field; typedef std::vector Array; /// Значение типа "массив" /** Числовое значение конкретного типа Field */ namespace FieldType { enum Enum { Null = 0, UInt64, Int64, Float64, String, Array }; } /** Возвращает true, если вариант - Null */ class FieldVisitorIsNull : public boost::static_visitor { public: template bool operator() (const T & x) const { return false; } bool operator() (const Null & x) const { return true; } }; /** Возвращает числовое значение типа */ class FieldVisitorGetType : public boost::static_visitor { public: FieldType::Enum operator() (const Null & x) const { return FieldType::Null; } FieldType::Enum operator() (const UInt64 & x) const { return FieldType::UInt64; } FieldType::Enum operator() (const Int64 & x) const { return FieldType::Int64; } FieldType::Enum operator() (const Float64 & x) const { return FieldType::Float64; } FieldType::Enum operator() (const String & x) const { return FieldType::String; } FieldType::Enum operator() (const Array & x) const { return FieldType::Array; } }; /** Возвращает строковый дамп типа */ class FieldVisitorDump : public boost::static_visitor { public: std::string operator() (const Null & x) const { return "NULL"; } std::string operator() (const UInt64 & x) const { return "UInt64_" + Poco::NumberFormatter::format(x); } std::string operator() (const Int64 & x) const { return "Int64_" + Poco::NumberFormatter::format(x); } std::string operator() (const Float64 & x) const { return "Float64_" + Poco::NumberFormatter::format(x); } std::string operator() (const String & x) const { std::stringstream s; s << mysqlxx::quote << x; return s.str(); } std::string operator() (const Array & x) const { std::stringstream s; s << "Array_["; for (Array::const_iterator it = x.begin(); it != x.end(); ++it) { if (it != x.begin()) s << ", "; s << boost::apply_visitor(FieldVisitorDump(), *it); } s << "]"; return s.str(); } }; /** Выводит текстовое представление типа, как литерала в SQL запросе */ class FieldVisitorToString : public boost::static_visitor { public: String operator() (const Null & x) const { return "NULL"; } String operator() (const UInt64 & x) const { return Poco::NumberFormatter::format(x); } String operator() (const Int64 & x) const { return Poco::NumberFormatter::format(x); } String operator() (const Float64 & x) const { return Poco::NumberFormatter::format(x); } String operator() (const String & x) const { std::stringstream s; s << mysqlxx::quote << x; return s.str(); } String operator() (const Array & x) const { std::stringstream s; FieldVisitorToString visitor; s << "["; for (Array::const_iterator it = x.begin(); it != x.end(); ++it) { if (it != x.begin()) s << ", "; s << boost::apply_visitor(FieldVisitorToString(), *it); } s << "]"; return s.str(); } }; template struct NearestFieldType; template <> struct NearestFieldType { typedef UInt64 Type; }; template <> struct NearestFieldType { typedef UInt64 Type; }; template <> struct NearestFieldType { typedef UInt64 Type; }; template <> struct NearestFieldType { typedef UInt64 Type; }; template <> struct NearestFieldType { typedef Int64 Type; }; template <> struct NearestFieldType { typedef Int64 Type; }; template <> struct NearestFieldType { typedef Int64 Type; }; template <> struct NearestFieldType { typedef Int64 Type; }; template <> struct NearestFieldType { typedef Float64 Type; }; template <> struct NearestFieldType { typedef Float64 Type; }; template <> struct NearestFieldType { typedef String Type; }; } #endif