#include "mysql_types.h" #include "helpers.h" #include "rawDataReader.h" #include #include #include #include namespace MyGrate::MySQL { typename Type::C Type::read(RawDataReader &, RawDataReader &) { return nullptr; } #define INTEGER_TYPE(ET) \ typename Type::C Type::read(RawDataReader &, RawDataReader & data) \ { \ return data.readValue::C>(); \ } \ typename Type::C Type::read(RawDataReader &, RawDataReader & data) \ { \ return data.readValue::C>(); \ } INTEGER_TYPE(MYSQL_TYPE_TINY); INTEGER_TYPE(MYSQL_TYPE_SHORT); INTEGER_TYPE(MYSQL_TYPE_LONG); INTEGER_TYPE(MYSQL_TYPE_LONGLONG); #undef INTEGER_TYPE #define FLOAT_TYPE(ET) \ typename Type::C Type::read(RawDataReader & md, RawDataReader & data) \ { \ verify(sizeof(typename Type::C) == md.readValue(), "Invalid " #ET " size"); \ return data.readValue::C>(); \ } FLOAT_TYPE(MYSQL_TYPE_FLOAT); FLOAT_TYPE(MYSQL_TYPE_DOUBLE); #undef FLOAT_TYPE typename Type::C Type::read(RawDataReader &, RawDataReader &) { throw std::logic_error("Not implemented"); } typename Type::C Type::read(RawDataReader &, RawDataReader &) { throw std::logic_error("Not implemented"); } #define INTEGER_TYPE(ET, s, l) \ typename Type::C Type::read(RawDataReader &, RawDataReader & data) \ { \ return data.readValue::C, l>(); \ } INTEGER_TYPE(MYSQL_TYPE_INT24, false, 3); INTEGER_TYPE(MYSQL_TYPE_INT24, true, 3); INTEGER_TYPE(MYSQL_TYPE_YEAR, false, 2); #undef INTEGER24_TYPE static Blob readBlob(RawDataReader & md, RawDataReader & data) { const auto lenlen {md.readValue()}; const auto len {data.readValue(lenlen)}; return data.viewValue(len); } #define BLOB_TYPE(ET) \ typename Type::C Type::read(RawDataReader & md, RawDataReader & data) \ { \ return readBlob(md, data); \ } BLOB_TYPE(MYSQL_TYPE_TINY_BLOB); BLOB_TYPE(MYSQL_TYPE_MEDIUM_BLOB); BLOB_TYPE(MYSQL_TYPE_LONG_BLOB); BLOB_TYPE(MYSQL_TYPE_GEOMETRY); // Ummm, pass this to the target to handle? #undef BLOB_TYPE typename Type::C Type::read(RawDataReader & md, RawDataReader & data) { const auto lenlen {md.readValue()}; const auto len {data.readValue(lenlen)}; return data.viewValue(len); } typename Type::C Type::read(RawDataReader &, RawDataReader &) { throw std::logic_error("Not implemented"); } #define STRING_TYPE(ET) \ typename Type::C Type::read(RawDataReader & md, RawDataReader & data) \ { \ const auto realtype {md.readValue()}; \ const auto lenlen {md.readValue()}; \ switch (realtype) { \ case MYSQL_TYPE_ENUM: \ case MYSQL_TYPE_VAR_STRING: \ return data.viewValue(lenlen); \ default: \ throw std::logic_error("Not implemented: sub-type: " + std::to_string(realtype)); \ } \ throw std::logic_error("Didn't return a value: " + std::to_string(realtype)); \ } STRING_TYPE(MYSQL_TYPE_STRING); STRING_TYPE(MYSQL_TYPE_JSON); STRING_TYPE(MYSQL_TYPE_SET); STRING_TYPE(MYSQL_TYPE_ENUM); #undef STRING_TYPE typename Type::C Type::read(RawDataReader & md, RawDataReader & data) { const auto fieldlen {md.readValue()}; const auto len {data.readValue(fieldlen > 255 ? 2 : 1)}; return data.viewValue(len); } typename Type::C Type::read(RawDataReader & md, RawDataReader & data) { const auto fieldlen {md.readValue()}; const auto len {md.readValue(fieldlen > 255 ? 2 : 1)}; return data.viewValue(len); } typename Type::C Type::read(RawDataReader &, RawDataReader & data) { auto dtint {data.readValue()}; DateTime dt {}; dt.second = mod100_extract(dtint); dt.minute = mod100_extract(dtint); dt.hour = mod100_extract(dtint); dt.day = mod100_extract(dtint); dt.month = mod100_extract(dtint); dt.year = boost::numeric_cast(dtint); return dt; } typename Type::C Type::read(RawDataReader &, RawDataReader & data) { auto tint {data.readValue()}; Time t {}; t.second = mod100_extract(tint); t.minute = mod100_extract(tint); t.hour = boost::numeric_cast(tint); return t; } typename Type::C Type::read(RawDataReader &, RawDataReader &) { throw std::logic_error("Not implemented"); } typename Type::C Type::read(RawDataReader &, RawDataReader & data) { auto dint {data.readValue()}; Date d {}; d.day = bitslice<6>(dint, 0); d.month = bitslice<4>(dint, 6); d.year = bitslice<14>(dint, 10); return d; } typename Type::C Type::read(RawDataReader &, RawDataReader &) { throw std::logic_error("Not implemented"); } typename Type::C Type::read(RawDataReader &, RawDataReader & data) { return {data.readValue(), 0}; } typename Type::C Type::read(RawDataReader & md, RawDataReader & data) { const auto decimals {md.readValue()}; return {data.readValue(), data.readValue(decimals)}; } typename Type::C Type::read(RawDataReader & md, RawDataReader & data) { md.discard(1); union { uint64_t i; std::array b; } r {}; r.b = data.readValue(); std::reverse(r.b.begin(), r.b.end()); DateTime dt; dt.year = boost::numeric_cast(bitslice<17>(r.i, 22) / 13); dt.month = boost::numeric_cast(bitslice<17>(r.i, 22) % 13); dt.day = bitslice<5>(r.i, 17); dt.hour = bitslice<5>(r.i, 12); dt.minute = bitslice<6>(r.i, 6); dt.second = bitslice<6>(r.i, 0); return dt; } }