aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/shared/Database/Field.cpp16
-rw-r--r--src/server/shared/Database/Field.h16
-rw-r--r--src/server/shared/Database/PreparedStatement.cpp31
-rw-r--r--src/server/shared/Database/PreparedStatement.h6
-rw-r--r--src/server/shared/Database/QueryResult.cpp10
5 files changed, 61 insertions, 18 deletions
diff --git a/src/server/shared/Database/Field.cpp b/src/server/shared/Database/Field.cpp
index 866a96b58b6..f1741f98cc3 100644
--- a/src/server/shared/Database/Field.cpp
+++ b/src/server/shared/Database/Field.cpp
@@ -46,7 +46,7 @@ void Field::SetByteValue(const void* newValue, const size_t newSize, enum_field_
data.raw = true;
}
-void Field::SetStructuredValue(char* newValue, enum_field_types newType)
+void Field::SetStructuredValue(char* newValue, enum_field_types newType, uint32 length, bool isBinary)
{
if (data.value)
CleanUp();
@@ -54,10 +54,16 @@ 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;
+ if (!isBinary)
+ {
+ data.value = new char[length + 1];
+ *(reinterpret_cast<char*>(data.value) + length) = '\0';
+ }
+ else
+ data.value = new char[length];
+
+ memcpy(data.value, newValue, length);
+ data.length = length;
}
data.type = newType;
diff --git a/src/server/shared/Database/Field.h b/src/server/shared/Database/Field.h
index 2e888be5ed3..99f98572a56 100644
--- a/src/server/shared/Database/Field.h
+++ b/src/server/shared/Database/Field.h
@@ -228,7 +228,6 @@ class Field
}
#endif
return static_cast<char const*>(data.value);
-
}
std::string GetString() const
@@ -243,7 +242,18 @@ class Field
string = "";
return std::string(string, data.length);
}
- return std::string((char*)data.value);
+ return std::string((char*)data.value, 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
@@ -274,7 +284,7 @@ class Field
#endif
void SetByteValue(void const* newValue, size_t const newSize, enum_field_types newType, uint32 length);
- void SetStructuredValue(char* newValue, enum_field_types newType);
+ void SetStructuredValue(char* newValue, enum_field_types newType, uint32 length, bool isBinary);
void CleanUp()
{
diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp
index 23c50ac2ef8..1f036b5bf0a 100644
--- a/src/server/shared/Database/PreparedStatement.cpp
+++ b/src/server/shared/Database/PreparedStatement.cpp
@@ -68,8 +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);
case TYPE_NULL:
m_stmt->setNull(i);
break;
@@ -186,10 +188,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 +351,23 @@ 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];
- size_t len = strlen(value) + 1;
+ size_t len = value.size();
param->buffer_type = MYSQL_TYPE_VAR_STRING;
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;
- memcpy(param->buffer, value, len);
+ memcpy(param->buffer, value.data(), len);
}
void MySQLPreparedStatement::setNull(const uint8 index)
@@ -429,7 +443,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";
diff --git a/src/server/shared/Database/PreparedStatement.h b/src/server/shared/Database/PreparedStatement.h
index 5af52cde016..3ab27902246 100644
--- a/src/server/shared/Database/PreparedStatement.h
+++ b/src/server/shared/Database/PreparedStatement.h
@@ -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 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 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:
diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/shared/Database/QueryResult.cpp
index a7b8ec2b107..a6d9c64622a 100644
--- a/src/server/shared/Database/QueryResult.cpp
+++ b/src/server/shared/Database/QueryResult.cpp
@@ -163,8 +163,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], (_fields[i].flags & BINARY_FLAG) != 0);
return true;
}