Server/Database: Reduce differences between 3.3.5 and 6.x branches

Cherry-pick 1bea52fd46 and 543bea32 to add support to TYPE_BINARY MySQL field type
This commit is contained in:
jackpoz
2016-08-10 16:02:22 +02:00
parent 3755937611
commit abe37e458c
5 changed files with 59 additions and 18 deletions

View File

@@ -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;

View File

@@ -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()
{

View File

@@ -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";

View File

@@ -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:

View File

@@ -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;
}