From 3c6dc320308880bde4ef9eddd695db28a74aa0d9 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Fri, 24 Sep 2010 22:16:21 +0200 Subject: Core/DBLayer: - Rewrite Field class to be able to store both binary prepared statement data and data from adhoc query resultsets - Buffer the data of prepared statements using ResultSet and Field classes and let go of mysql c api structures after PreparedResultSet constructor. Fixes a race condition and thus a possible crash/data corruption (issue pointed out to Derex, basic suggestion by raczman) - Conform PreparedResultSet and ResultSet to the same design standards, and using Field class as data buffer class for both * NOTE: This means the fetching methods are uniform again, using ¨Field* fields = result->Fetch();¨ and access to elements trough fields[x]. * NOTE: for access to the correct row in prepared statements, ¨Field* fields = result->Fetch();¨ must ALWAYS be called inside the do { }while(result->NextRow()) loop. * NOTE: This means that Field::GetString() returns std::string object and Field::GetCString() returns const char* pointer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Still experimental and all that jazz, not recommended for production servers until feedback is given. --HG-- branch : trunk --- src/server/shared/Database/Field.cpp | 66 +++++++++++++----------------------- 1 file changed, 24 insertions(+), 42 deletions(-) (limited to 'src/server/shared/Database/Field.cpp') diff --git a/src/server/shared/Database/Field.cpp b/src/server/shared/Database/Field.cpp index ac83bf055fb..9ef23f3ad17 100644 --- a/src/server/shared/Database/Field.cpp +++ b/src/server/shared/Database/Field.cpp @@ -1,6 +1,4 @@ /* - * Copyright (C) 2005-2009 MaNGOS - * * Copyright (C) 2008-2010 Trinity * * This program is free software; you can redistribute it and/or modify @@ -20,58 +18,42 @@ #include "Field.h" -Field::Field() : -mValue(NULL), mType(DB_TYPE_UNKNOWN) +Field::Field() { + data.value = NULL; + data.type = MYSQL_TYPE_NULL; + data.length = 0; } -Field::Field(Field &f) +Field::~Field() { - const char *value; - - value = f.GetString(); - - if (value) - { - mValue = new char[strlen(value) + 1]; - if (mValue) - strcpy(mValue, value); - } - else - mValue = NULL; - - mType = f.GetType(); + CleanUp(); } -Field::Field(const char *value, enum Field::DataTypes type) : -mType(type) +void Field::SetByteValue(void* newValue, const size_t newSize, enum_field_types newType, uint32 length) { - if (value) + // This value stores raw bytes that have to be explicitly casted later + if (newValue) { - mValue = new char[strlen(value) + 1]; - if (mValue) - strcpy(mValue, value); + data.value = new char [newSize]; + memcpy(data.value, newValue, newSize); + data.length = length; } - else - mValue = NULL; + data.type = newType; + data.raw = true; } -Field::~Field() -{ - if (mValue) - delete [] mValue; -} - -void Field::SetValue(const char *value) +void Field::SetStructuredValue(char* newValue, enum_field_types newType, const size_t newSize) { - if (mValue) - delete [] mValue; - - if (value) + // This value stores somewhat structured data that needs function style casting + if (newValue) { - mValue = new char[strlen(value) + 1]; - strcpy(mValue, value); + size_t size = strlen(newValue); + data.value = new char [size+1]; + strcpy(data.value, newValue); + data.length = size; } - else - mValue = NULL; + + data.type = newType; + data.raw = false; } -- cgit v1.2.3