mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 23:50:44 +01:00
Server/Database: Reduce differences between 3.3.5 and 6.x branches
Cherry-pick1bea52fd46and543bea32to add support to TYPE_BINARY MySQL field type
This commit is contained in:
@@ -39,7 +39,7 @@ void Field::SetByteValue(void* newValue, enum_field_types newType, uint32 length
|
||||
data.raw = true;
|
||||
}
|
||||
|
||||
void Field::SetStructuredValue(char* newValue, enum_field_types newType)
|
||||
void Field::SetStructuredValue(char* newValue, enum_field_types newType, uint32 length)
|
||||
{
|
||||
if (data.value)
|
||||
CleanUp();
|
||||
@@ -47,10 +47,10 @@ void Field::SetStructuredValue(char* newValue, enum_field_types newType)
|
||||
// This value stores somewhat structured data that needs function style casting
|
||||
if (newValue)
|
||||
{
|
||||
size_t size = strlen(newValue);
|
||||
data.value = new char [size+1];
|
||||
strcpy((char*)data.value, newValue);
|
||||
data.length = size;
|
||||
data.value = new char[length + 1];
|
||||
memcpy(data.value, newValue, length);
|
||||
*(reinterpret_cast<char*>(data.value) + length) = '\0';
|
||||
data.length = length;
|
||||
}
|
||||
|
||||
data.type = newType;
|
||||
|
||||
@@ -271,7 +271,6 @@ class TC_DATABASE_API Field
|
||||
}
|
||||
#endif
|
||||
return static_cast<char const*>(data.value);
|
||||
|
||||
}
|
||||
|
||||
std::string GetString() const
|
||||
@@ -286,6 +285,17 @@ class TC_DATABASE_API Field
|
||||
return std::string(string, data.length);
|
||||
}
|
||||
|
||||
std::vector<uint8> 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;
|
||||
}
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return data.value == NULL;
|
||||
@@ -313,7 +323,7 @@ class TC_DATABASE_API Field
|
||||
#pragma pack(pop)
|
||||
|
||||
void SetByteValue(void* newValue, enum_field_types newType, uint32 length);
|
||||
void SetStructuredValue(char* newValue, enum_field_types newType);
|
||||
void SetStructuredValue(char* newValue, enum_field_types newType, uint32 length);
|
||||
|
||||
void CleanUp()
|
||||
{
|
||||
|
||||
@@ -68,7 +68,10 @@ void PreparedStatement::BindParameters()
|
||||
m_stmt->setDouble(i, statement_data[i].data.d);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
m_stmt->setString(i, statement_data[i].str.c_str());
|
||||
m_stmt->setBinary(i, statement_data[i].binary, true);
|
||||
break;
|
||||
case TYPE_BINARY:
|
||||
m_stmt->setBinary(i, statement_data[i].binary, false);
|
||||
break;
|
||||
case TYPE_NULL:
|
||||
m_stmt->setNull(i);
|
||||
@@ -186,10 +189,20 @@ void PreparedStatement::setString(const uint8 index, const std::string& value)
|
||||
if (index >= statement_data.size())
|
||||
statement_data.resize(index+1);
|
||||
|
||||
statement_data[index].str = value;
|
||||
statement_data[index].binary.resize(value.length() + 1);
|
||||
memcpy(statement_data[index].binary.data(), value.c_str(), value.length() + 1);
|
||||
statement_data[index].type = TYPE_STRING;
|
||||
}
|
||||
|
||||
void PreparedStatement::setBinary(const uint8 index, const std::vector<uint8>& value)
|
||||
{
|
||||
if (index >= statement_data.size())
|
||||
statement_data.resize(index + 1);
|
||||
|
||||
statement_data[index].binary = value;
|
||||
statement_data[index].type = TYPE_BINARY;
|
||||
}
|
||||
|
||||
void PreparedStatement::setNull(const uint8 index)
|
||||
{
|
||||
if (index >= statement_data.size())
|
||||
@@ -339,21 +352,26 @@ void MySQLPreparedStatement::setDouble(const uint8 index, const double value)
|
||||
setValue(param, MYSQL_TYPE_DOUBLE, &value, sizeof(double), (value > 0.0f));
|
||||
}
|
||||
|
||||
void MySQLPreparedStatement::setString(const uint8 index, const char* value)
|
||||
void MySQLPreparedStatement::setBinary(const uint8 index, const std::vector<uint8>& value, bool isString)
|
||||
{
|
||||
CheckValidIndex(index);
|
||||
m_paramsSet[index] = true;
|
||||
MYSQL_BIND* param = &m_bind[index];
|
||||
uint32 len = uint32(strlen(value) + 1);
|
||||
param->buffer_type = MYSQL_TYPE_VAR_STRING;
|
||||
uint32 len = uint32(value.size());
|
||||
param->buffer_type = MYSQL_TYPE_BLOB;
|
||||
delete [] static_cast<char *>(param->buffer);
|
||||
param->buffer = new char[len];
|
||||
param->buffer_length = len;
|
||||
param->is_null_value = 0;
|
||||
delete param->length;
|
||||
param->length = new unsigned long(len-1);
|
||||
param->length = new unsigned long(len);
|
||||
if (isString)
|
||||
{
|
||||
*param->length -= 1;
|
||||
param->buffer_type = MYSQL_TYPE_VAR_STRING;
|
||||
}
|
||||
|
||||
memcpy(param->buffer, value, len);
|
||||
memcpy(param->buffer, value.data(), len);
|
||||
}
|
||||
|
||||
void MySQLPreparedStatement::setNull(const uint8 index)
|
||||
@@ -429,7 +447,10 @@ std::string MySQLPreparedStatement::getQueryString(std::string const& sqlPattern
|
||||
ss << m_stmt->statement_data[i].data.d;
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
ss << '\'' << m_stmt->statement_data[i].str << '\'';
|
||||
ss << '\'' << (char const*)m_stmt->statement_data[i].binary.data() << '\'';
|
||||
break;
|
||||
case TYPE_BINARY:
|
||||
ss << "BINARY";
|
||||
break;
|
||||
case TYPE_NULL:
|
||||
ss << "NULL";
|
||||
|
||||
@@ -56,6 +56,7 @@ enum PreparedStatementValueType
|
||||
TYPE_FLOAT,
|
||||
TYPE_DOUBLE,
|
||||
TYPE_STRING,
|
||||
TYPE_BINARY,
|
||||
TYPE_NULL
|
||||
};
|
||||
|
||||
@@ -63,7 +64,7 @@ struct PreparedStatementData
|
||||
{
|
||||
PreparedStatementDataUnion data;
|
||||
PreparedStatementValueType type;
|
||||
std::string str;
|
||||
std::vector<uint8> binary;
|
||||
};
|
||||
|
||||
//- Forward declare
|
||||
@@ -92,6 +93,7 @@ class TC_DATABASE_API PreparedStatement
|
||||
void setFloat(const uint8 index, const float value);
|
||||
void setDouble(const uint8 index, const double value);
|
||||
void setString(const uint8 index, const std::string& value);
|
||||
void setBinary(const uint8 index, const std::vector<uint8>& value);
|
||||
void setNull(const uint8 index);
|
||||
|
||||
protected:
|
||||
@@ -129,7 +131,7 @@ class TC_DATABASE_API MySQLPreparedStatement
|
||||
void setInt64(const uint8 index, const int64 value);
|
||||
void setFloat(const uint8 index, const float value);
|
||||
void setDouble(const uint8 index, const double value);
|
||||
void setString(const uint8 index, const char* value);
|
||||
void setBinary(const uint8 index, const std::vector<uint8>& value, bool isString);
|
||||
void setNull(const uint8 index);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -187,8 +187,16 @@ bool ResultSet::NextRow()
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long* lengths = mysql_fetch_lengths(_result);
|
||||
if (!lengths)
|
||||
{
|
||||
TC_LOG_WARN("sql.sql", "%s:mysql_fetch_lengths, cannot retrieve value lengths. Error %s.", __FUNCTION__, mysql_error(_result->handle));
|
||||
CleanUp();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < _fieldCount; i++)
|
||||
_currentRow[i].SetStructuredValue(row[i], _fields[i].type);
|
||||
_currentRow[i].SetStructuredValue(row[i], _fields[i].type, lengths[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user