From 24fc0dcb1ee627cdec5ff5670a85050afc62d281 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 14 May 2023 16:30:05 +0200 Subject: Core/DBLayer: Relaxed restrictions on which Field class member function can be used to access column value from "strict match" to "must not truncate" (cherry picked from commit eadafb0347d606e5e3e660d21227aa15378bdb21) --- .../database/Database/FieldValueConverters.h | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/server/database/Database/FieldValueConverters.h (limited to 'src/server/database/Database/FieldValueConverters.h') diff --git a/src/server/database/Database/FieldValueConverters.h b/src/server/database/Database/FieldValueConverters.h new file mode 100644 index 00000000000..e050d8052ca --- /dev/null +++ b/src/server/database/Database/FieldValueConverters.h @@ -0,0 +1,112 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef TRINITY_FIELD_VALUE_CONVERTERS_H +#define TRINITY_FIELD_VALUE_CONVERTERS_H + +#include "FieldValueConverter.h" +#include "StringConvert.h" + +// converts string value returned from query to type specified in column metadata +template +class FromStringToDatabaseTypeConverter : public BaseDatabaseResultValueConverter +{ +public: + static DatabaseType GetDatabaseValue(char const* data, uint32 size) + { + return Trinity::StringTo({ data, size }).template value_or(0); + } + + static char const* GetStringValue(char const* data) + { + return data; + } +}; + +// converts binary value returned from query to type specified in column metadata +template +class FromBinaryToDatabaseTypeConverter : public BaseDatabaseResultValueConverter +{ +public: + static DatabaseType GetDatabaseValue(char const* data, uint32 /*size*/) + { + return *reinterpret_cast(data); + } + + static char const* GetStringValue(char const* /*data*/) + { + return nullptr; + } +}; + +// converts column value from type specified in column metadata to type requested by Field::Get* function +template typename ToDatabaseTypeConverter> +class PrimitiveResultValueConverter : public BaseDatabaseResultValueConverter +{ +public: + template + static T GetNumericValue(char const* data, uint32 size, QueryResultFieldMetadata const* meta, char const* func) + { + DatabaseType source = ToDatabaseTypeConverter::GetDatabaseValue(data, size); + T result = static_cast(source); + if (static_cast(result) != source) + { + LogTruncation(func, meta); + return T(); + } + return result; + } + + uint8 GetUInt8(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetUInt8"); } + int8 GetInt8(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetInt8"); } + uint16 GetUInt16(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetUInt16"); } + int16 GetInt16(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetInt16"); } + uint32 GetUInt32(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetUInt32"); } + int32 GetInt32(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetInt32"); } + uint64 GetUInt64(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetUInt64"); } + int64 GetInt64(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetInt64"); } + float GetFloat(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetFloat"); } + double GetDouble(char const* data, uint32 size, QueryResultFieldMetadata const* meta) const override { return GetNumericValue(data, size, meta, "Field::GetDouble"); } + char const* GetCString(char const* data, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override + { + char const* result = ToDatabaseTypeConverter::GetStringValue(data); + if (data && !result) + LogTruncation("Field::GetCString", meta); + return result; + } +}; + +template<> +class PrimitiveResultValueConverter : public BaseDatabaseResultValueConverter +{ +public: + uint8 GetUInt8(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetUInt8", meta); return 0; } + int8 GetInt8(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetInt8", meta); return 0; } + uint16 GetUInt16(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetUInt16", meta); return 0; } + int16 GetInt16(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetInt16", meta); return 0; } + uint32 GetUInt32(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetUInt32", meta); return 0; } + int32 GetInt32(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetInt32", meta); return 0; } + uint64 GetUInt64(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetUInt64", meta); return 0; } + int64 GetInt64(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetInt64", meta); return 0; } + float GetFloat(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetFloat", meta); return 0.0f; } + double GetDouble(char const* /*data*/, uint32 /*size*/, QueryResultFieldMetadata const* meta) const override { LogTruncation("Field::GetDouble", meta); return 0.0; } + char const* GetCString(char const* data, uint32 /*size*/, QueryResultFieldMetadata const* /*meta*/) const override { return data; } +}; + +using StringResultValueConverter = PrimitiveResultValueConverter; + +#endif // TRINITY_FIELD_VALUE_CONVERTERS_H -- cgit v1.2.3