diff options
author | jackpoz <giacomopoz@gmail.com> | 2016-08-10 16:02:22 +0200 |
---|---|---|
committer | jackpoz <giacomopoz@gmail.com> | 2016-08-10 16:02:22 +0200 |
commit | abe37e458c2b482d478ce98ba44bc8dcf76caeb1 (patch) | |
tree | 9cbbbbaa3ab019e549b3e310e6f3ebf9aae8d62b /src | |
parent | 375593761167ba1bf8ef16bbe345cb569ad1e00b (diff) |
Server/Database: Reduce differences between 3.3.5 and 6.x branches
Cherry-pick 1bea52fd4649b6a1761aa157f9e74f01e19872e7 and 543bea32 to add support to TYPE_BINARY MySQL field type
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Field.cpp | 10 | ||||
-rw-r--r-- | src/server/database/Database/Field.h | 14 | ||||
-rw-r--r-- | src/server/database/Database/PreparedStatement.cpp | 37 | ||||
-rw-r--r-- | src/server/database/Database/PreparedStatement.h | 6 | ||||
-rw-r--r-- | src/server/database/Database/QueryResult.cpp | 10 |
5 files changed, 59 insertions, 18 deletions
diff --git a/src/server/database/Database/Field.cpp b/src/server/database/Database/Field.cpp index 20a42871b91..efddd005c06 100644 --- a/src/server/database/Database/Field.cpp +++ b/src/server/database/Database/Field.cpp @@ -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; diff --git a/src/server/database/Database/Field.h b/src/server/database/Database/Field.h index 123e25dbbf3..6089c3001fb 100644 --- a/src/server/database/Database/Field.h +++ b/src/server/database/Database/Field.h @@ -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() { diff --git a/src/server/database/Database/PreparedStatement.cpp b/src/server/database/Database/PreparedStatement.cpp index 119f1d4c93b..d32b3306995 100644 --- a/src/server/database/Database/PreparedStatement.cpp +++ b/src/server/database/Database/PreparedStatement.cpp @@ -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"; diff --git a/src/server/database/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h index faaec27014f..d7508dbae1f 100644 --- a/src/server/database/Database/PreparedStatement.h +++ b/src/server/database/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 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: diff --git a/src/server/database/Database/QueryResult.cpp b/src/server/database/Database/QueryResult.cpp index db9e737830c..44f29ce41b8 100644 --- a/src/server/database/Database/QueryResult.cpp +++ b/src/server/database/Database/QueryResult.cpp @@ -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; } |