mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-14 09:39:11 +00:00
feat(Core/DBLayer): replace char const* to std::string_view (#10211)
* feat(Core/DBLayer): replace `char const*` to `std::string_view` * CString * 1 * chore(Core/Misc): code cleanup * cl * db fix * fmt style sql * to fmt * py * del old * 1 * 2 * 3 * 1 * 1
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
#include "Errors.h"
|
||||
#include "Log.h"
|
||||
#include "MySQLHacks.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Types.h"
|
||||
|
||||
Field::Field()
|
||||
{
|
||||
@@ -28,236 +30,118 @@ Field::Field()
|
||||
meta = nullptr;
|
||||
}
|
||||
|
||||
Field::~Field() = default;
|
||||
|
||||
uint8 Field::GetUInt8() const
|
||||
namespace
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int8))
|
||||
template<typename T>
|
||||
constexpr T GetDefaultValue()
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
return false;
|
||||
else if constexpr (std::is_integral_v<T>)
|
||||
return 0;
|
||||
else if constexpr (std::is_floating_point_v<T>)
|
||||
return 1.0f;
|
||||
else if constexpr (std::is_same_v<T, std::vector<uint8>> || std::is_same_v<std::string_view, T>)
|
||||
return {};
|
||||
else
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<uint8 const*>(data.value);
|
||||
return static_cast<uint8>(strtoul(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
int8 Field::GetInt8() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int8))
|
||||
template<typename T>
|
||||
inline bool IsCorrectFieldType(DatabaseFieldTypes type)
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
// Int8
|
||||
if constexpr (std::is_same_v<T, bool> || std::is_same_v<T, int8> || std::is_same_v<T, uint8>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Int8)
|
||||
return true;
|
||||
}
|
||||
|
||||
// In16
|
||||
if constexpr (std::is_same_v<T, uint16> || std::is_same_v<T, int16>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Int16)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Int32
|
||||
if constexpr (std::is_same_v<T, uint32> || std::is_same_v<T, int32>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Int32)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Int64
|
||||
if constexpr (std::is_same_v<T, uint64> || std::is_same_v<T, int64>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Int64)
|
||||
return true;
|
||||
}
|
||||
|
||||
// float
|
||||
if constexpr (std::is_same_v<T, float>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Float)
|
||||
return true;
|
||||
}
|
||||
|
||||
// dobule
|
||||
if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Double || type == DatabaseFieldTypes::Decimal)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Binary
|
||||
if constexpr (std::is_same_v<T, Binary>)
|
||||
{
|
||||
if (type == DatabaseFieldTypes::Binary)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<int8 const*>(data.value);
|
||||
return static_cast<int8>(strtol(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
uint16 Field::GetUInt16() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int16))
|
||||
inline Optional<std::string_view> GetCleanAliasName(std::string_view alias)
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
if (alias.empty())
|
||||
return {};
|
||||
|
||||
auto pos = alias.find_first_of('(');
|
||||
if (pos == std::string_view::npos)
|
||||
return {};
|
||||
|
||||
alias.remove_suffix(alias.length() - pos);
|
||||
|
||||
return { alias };
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<uint16 const*>(data.value);
|
||||
return static_cast<uint16>(strtoul(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
int16 Field::GetInt16() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int16))
|
||||
template<typename T>
|
||||
inline bool IsCorrectAlias(DatabaseFieldTypes type, std::string_view alias)
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
if ((StringEqualI(alias, "sum") || StringEqualI(alias, "avg")) && type == DatabaseFieldTypes::Decimal)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<T, uint64>)
|
||||
{
|
||||
if (StringEqualI(alias, "count") && type == DatabaseFieldTypes::Int64)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((StringEqualI(alias, "min") || StringEqualI(alias, "max")) && IsCorrectFieldType<T>(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<int16 const*>(data.value);
|
||||
return static_cast<int16>(strtol(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
uint32 Field::GetUInt32() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int32))
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<uint32 const*>(data.value);
|
||||
return static_cast<uint32>(strtoul(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
int32 Field::GetInt32() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int32))
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<int32 const*>(data.value);
|
||||
return static_cast<int32>(strtol(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
uint64 Field::GetUInt64() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int64))
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<uint64 const*>(data.value);
|
||||
return static_cast<uint64>(strtoull(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
int64 Field::GetInt64() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Int64))
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<int64 const*>(data.value);
|
||||
return static_cast<int64>(strtoll(data.value, nullptr, 10));
|
||||
}
|
||||
|
||||
float Field::GetFloat() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0.0f;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Float))
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<float const*>(data.value);
|
||||
return static_cast<float>(atof(data.value));
|
||||
}
|
||||
|
||||
double Field::GetDouble() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0.0f;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsType(DatabaseFieldTypes::Double) && !IsType(DatabaseFieldTypes::Decimal))
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.raw && !IsType(DatabaseFieldTypes::Decimal))
|
||||
return *reinterpret_cast<double const*>(data.value);
|
||||
return static_cast<double>(atof(data.value));
|
||||
}
|
||||
|
||||
char const* Field::GetCString() const
|
||||
{
|
||||
if (!data.value)
|
||||
return nullptr;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (IsNumeric() && data.raw)
|
||||
{
|
||||
LogWrongType(__FUNCTION__);
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
return static_cast<char const*>(data.value);
|
||||
}
|
||||
|
||||
std::string Field::GetString() const
|
||||
{
|
||||
if (!data.value)
|
||||
return "";
|
||||
|
||||
char const* string = GetCString();
|
||||
if (!string)
|
||||
return "";
|
||||
|
||||
return std::string(string, data.length);
|
||||
}
|
||||
|
||||
std::string_view Field::GetStringView() const
|
||||
{
|
||||
if (!data.value)
|
||||
return {};
|
||||
|
||||
char const* const string = GetCString();
|
||||
if (!string)
|
||||
return {};
|
||||
|
||||
return { string, data.length };
|
||||
}
|
||||
|
||||
std::vector<uint8> Field::GetBinary() const
|
||||
{
|
||||
std::vector<uint8> result;
|
||||
if (!data.value || !data.length)
|
||||
return result;
|
||||
|
||||
result.resize(data.length);
|
||||
memcpy(result.data(), data.value, data.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Field::GetBinarySizeChecked(uint8* buf, size_t length) const
|
||||
@@ -297,13 +181,159 @@ bool Field::IsNumeric() const
|
||||
meta->Type == DatabaseFieldTypes::Double);
|
||||
}
|
||||
|
||||
void Field::LogWrongType(char const* getter) const
|
||||
void Field::LogWrongType(std::string_view getter, std::string_view typeName) const
|
||||
{
|
||||
LOG_WARN("sql.sql", "Warning: {} on {} field {}.{} ({}.{}) at index {}.",
|
||||
getter, meta->TypeName, meta->TableAlias, meta->Alias, meta->TableName, meta->Name, meta->Index);
|
||||
LOG_WARN("sql.sql", "Warning: {}<{}> on {} field {}.{} ({}.{}) at index {}.",
|
||||
getter, typeName, meta->TypeName, meta->TableAlias, meta->Alias, meta->TableName, meta->Name, meta->Index);
|
||||
}
|
||||
|
||||
void Field::SetMetadata(QueryResultFieldMetadata const* fieldMeta)
|
||||
{
|
||||
meta = fieldMeta;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Field::GetData() const
|
||||
{
|
||||
static_assert(std::is_arithmetic_v<T>, "Unsurropt type for Field::GetData()");
|
||||
|
||||
if (!data.value)
|
||||
return GetDefaultValue<T>();
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsCorrectFieldType<T>(meta->Type))
|
||||
{
|
||||
LogWrongType(__FUNCTION__, typeid(T).name());
|
||||
//return GetDefaultValue<T>();
|
||||
}
|
||||
#endif
|
||||
|
||||
Optional<T> result = {};
|
||||
|
||||
if (data.raw)
|
||||
result = *reinterpret_cast<T const*>(data.value);
|
||||
else
|
||||
result = Acore::StringTo<T>(data.value);
|
||||
|
||||
// Correct double fields... this undefined behavior :/
|
||||
if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
if (data.raw && !IsType(DatabaseFieldTypes::Decimal))
|
||||
result = *reinterpret_cast<double const*>(data.value);
|
||||
else
|
||||
result = Acore::StringTo<float>(data.value);
|
||||
}
|
||||
|
||||
// Check -1 for *_dbc db tables
|
||||
if constexpr (std::is_same_v<T, uint32>)
|
||||
{
|
||||
std::string_view tableName{ meta->TableName };
|
||||
|
||||
if (!tableName.empty() && tableName.size() > 4)
|
||||
{
|
||||
auto signedResult = Acore::StringTo<int32>(data.value);
|
||||
|
||||
if (signedResult && !result && tableName.substr(tableName.length() - 4) == "_dbc")
|
||||
{
|
||||
LOG_DEBUG("sql.sql", "> Found incorrect value '{}' for type '{}' in _dbc table.", data.value, typeid(T).name());
|
||||
LOG_DEBUG("sql.sql", "> Table name '{}'. Field name '{}'. Try return int32 value", meta->TableName, meta->Name);
|
||||
return GetData<int32>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto alias = GetCleanAliasName(meta->Alias))
|
||||
{
|
||||
if ((StringEqualI(*alias, "min") || StringEqualI(*alias, "max")) && !IsCorrectAlias<T>(meta->Type, *alias))
|
||||
{
|
||||
LogWrongType(__FUNCTION__, typeid(T).name());
|
||||
}
|
||||
|
||||
if ((StringEqualI(*alias, "sum") || StringEqualI(*alias, "avg")) && !IsCorrectAlias<T>(meta->Type, *alias))
|
||||
{
|
||||
LogWrongType(__FUNCTION__, typeid(T).name());
|
||||
LOG_WARN("sql.sql", "> Please use GetData<double>()");
|
||||
return GetData<double>();
|
||||
}
|
||||
|
||||
if (StringEqualI(*alias, "count") && !IsCorrectAlias<T>(meta->Type, *alias))
|
||||
{
|
||||
LogWrongType(__FUNCTION__, typeid(T).name());
|
||||
LOG_WARN("sql.sql", "> Please use GetData<uint64>()");
|
||||
return GetData<uint64>();
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_FATAL("sql.sql", "> Incorrect value '{}' for type '{}'. Value is raw ? '{}'", data.value, typeid(T).name(), data.raw);
|
||||
LOG_FATAL("sql.sql", "> Table name '{}'. Field name '{}'", meta->TableName, meta->Name);
|
||||
//ABORT();
|
||||
return GetDefaultValue<T>();
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
template bool Field::GetData() const;
|
||||
template uint8 Field::GetData() const;
|
||||
template uint16 Field::GetData() const;
|
||||
template uint32 Field::GetData() const;
|
||||
template uint64 Field::GetData() const;
|
||||
template int8 Field::GetData() const;
|
||||
template int16 Field::GetData() const;
|
||||
template int32 Field::GetData() const;
|
||||
template int64 Field::GetData() const;
|
||||
template float Field::GetData() const;
|
||||
template double Field::GetData() const;
|
||||
|
||||
std::string Field::GetDataString() const
|
||||
{
|
||||
if (!data.value)
|
||||
return "";
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (IsNumeric() && data.raw)
|
||||
{
|
||||
LogWrongType(__FUNCTION__, "std::string");
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
return { data.value, data.length };
|
||||
}
|
||||
|
||||
std::string_view Field::GetDataStringView() const
|
||||
{
|
||||
if (!data.value)
|
||||
return {};
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (IsNumeric() && data.raw)
|
||||
{
|
||||
LogWrongType(__FUNCTION__, "std::string_view");
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
return { data.value, data.length };
|
||||
}
|
||||
|
||||
Binary Field::GetDataBinary() const
|
||||
{
|
||||
Binary result = {};
|
||||
if (!data.value || !data.length)
|
||||
return result;
|
||||
|
||||
#ifdef ACORE_STRICT_DATABASE_TYPE_CHECKS
|
||||
if (!IsCorrectFieldType<Binary>(meta->Type))
|
||||
{
|
||||
LogWrongType(__FUNCTION__, "Binary");
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
result.resize(data.length);
|
||||
memcpy(result.data(), data.value, data.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user