diff options
Diffstat (limited to 'src/shared/Database')
22 files changed, 0 insertions, 422 deletions
diff --git a/src/shared/Database/DBCFileLoader.cpp b/src/shared/Database/DBCFileLoader.cpp index e7ebeedecfb..adf796fbce6 100644 --- a/src/shared/Database/DBCFileLoader.cpp +++ b/src/shared/Database/DBCFileLoader.cpp @@ -17,59 +17,42 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include <stdio.h> #include <stdlib.h> #include <string.h> - #include "DBCFileLoader.h" - DBCFileLoader::DBCFileLoader() { data = NULL; fieldsOffset = NULL; } - bool DBCFileLoader::Load(const char *filename, const char *fmt) { - uint32 header; if(data) { delete [] data; data=NULL; } - FILE * f=fopen(filename,"rb"); if(!f)return false; - if(fread(&header,4,1,f)!=1) // Number of records return false; - EndianConvert(header); if(header!=0x43424457) return false; //'WDBC' - if(fread(&recordCount,4,1,f)!=1) // Number of records return false; - EndianConvert(recordCount); - if(fread(&fieldCount,4,1,f)!=1) // Number of fields return false; - EndianConvert(fieldCount); - if(fread(&recordSize,4,1,f)!=1) // Size of a record return false; - EndianConvert(recordSize); - if(fread(&stringSize,4,1,f)!=1) // String size return false; - EndianConvert(stringSize); - fieldsOffset = new uint32[fieldCount]; fieldsOffset[0] = 0; for(uint32 i = 1; i < fieldCount; i++) @@ -80,17 +63,13 @@ bool DBCFileLoader::Load(const char *filename, const char *fmt) else // 4 byte fields (int32/float/strings) fieldsOffset[i] += 4; } - data = new unsigned char[recordSize*recordCount+stringSize]; stringTable = data + recordSize*recordCount; - if(fread(data,recordSize*recordCount+stringSize,1,f)!=1) return false; - fclose(f); return true; } - DBCFileLoader::~DBCFileLoader() { if(data) @@ -98,13 +77,11 @@ DBCFileLoader::~DBCFileLoader() if(fieldsOffset) delete [] fieldsOffset; } - DBCFileLoader::Record DBCFileLoader::getRecord(size_t id) { assert(data); return Record(*this, data + id*recordSize); } - uint32 DBCFileLoader::GetFormatRecordSize(const char * format,int32* index_pos) { uint32 recordsize = 0; @@ -130,13 +107,10 @@ uint32 DBCFileLoader::GetFormatRecordSize(const char * format,int32* index_pos) recordsize += 1; break; } - if(index_pos) *index_pos = i; - return recordsize; } - char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable) { /* @@ -146,18 +120,14 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** float field1, int field2 }entry; - this func will generate entry[rows] data; */ - typedef char * ptr; if(strlen(format)!=fieldCount) return NULL; - //get struct size and index pos int32 i; uint32 recordsize=GetFormatRecordSize(format,&i); - if(i>=0) { uint32 maxi=0; @@ -167,11 +137,9 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** uint32 ind=getRecord(y).getUInt (i); if(ind>maxi)maxi=ind; } - // If higher index avalible from sql - use it instead of dbcs if (sqlHighestIndex > maxi) maxi = sqlHighestIndex; - ++maxi; records=maxi; indexTable=new ptr[maxi]; @@ -182,11 +150,8 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** records = recordCount + sqlRecordCount; indexTable = new ptr[recordCount+ sqlRecordCount]; } - char* dataTable= new char[(recordCount + sqlRecordCount)*recordsize]; - uint32 offset=0; - for(uint32 y =0;y<recordCount;++y) { if(i>=0) @@ -195,7 +160,6 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** } else indexTable[y]=&dataTable[offset]; - for(uint32 x=0;x<fieldCount;x++) { switch(format[x]) @@ -221,20 +185,15 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** } } sqlDataTable = dataTable + offset; - return dataTable; } - char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable) { if(strlen(format)!=fieldCount) return NULL; - char* stringPool= new char[stringSize]; memcpy(stringPool,stringTable,stringSize); - uint32 offset=0; - for(uint32 y =0;y<recordCount;y++) { for(uint32 x=0;x<fieldCount;x++) @@ -260,7 +219,6 @@ char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable) break; } } - return stringPool; } diff --git a/src/shared/Database/DBCFileLoader.h b/src/shared/Database/DBCFileLoader.h index ef29af84bc1..fd1f5539ee3 100644 --- a/src/shared/Database/DBCFileLoader.h +++ b/src/shared/Database/DBCFileLoader.h @@ -15,13 +15,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DBC_FILE_LOADER_H #define DBC_FILE_LOADER_H #include "Platform/Define.h" #include "Utilities/ByteConverter.h" #include <cassert> - enum { FT_NA='x', //not used or unknown, 4 byte size @@ -36,15 +34,12 @@ enum FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc }; - class DBCFileLoader { public: DBCFileLoader(); ~DBCFileLoader(); - bool Load(const char *filename, const char *fmt); - class Record { public: @@ -67,7 +62,6 @@ class DBCFileLoader assert(field < file.fieldCount); return *reinterpret_cast<uint8*>(offset+file.GetOffset(field)); } - const char *getString(size_t field) const { assert(field < file.fieldCount); @@ -75,20 +69,15 @@ class DBCFileLoader assert(stringOffset < file.stringSize); return reinterpret_cast<char*>(file.stringTable + stringOffset); } - private: Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) {} unsigned char *offset; DBCFileLoader &file; - friend class DBCFileLoader; - }; - // Get record by id Record getRecord(size_t id); /// Get begin iterator over records - uint32 GetNumRows() const { return recordCount;} uint32 GetRowSize() const { return recordSize;} uint32 GetCols() const { return fieldCount; } @@ -98,7 +87,6 @@ class DBCFileLoader char* AutoProduceStrings(const char* fmt, char* dataTable); static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL); private: - uint32 recordSize; uint32 recordCount; uint32 fieldCount; diff --git a/src/shared/Database/DBCStore.h b/src/shared/Database/DBCStore.h index e02265ec523..60e533a88e1 100644 --- a/src/shared/Database/DBCStore.h +++ b/src/shared/Database/DBCStore.h @@ -15,13 +15,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DBCSTORE_H #define DBCSTORE_H - #include "DBCFileLoader.h" #include "Log.h" - struct SqlDbc { const std::string * formatString; @@ -41,7 +38,6 @@ struct SqlDbc else if (sqlTableName[i] == '.') sqlTableName[i] = '_'; } - // Get sql index position DBCFileLoader::GetFormatRecordSize(fmt, &indexPos); if (indexPos>=0) @@ -59,7 +55,6 @@ struct SqlDbc } } }; - template<class T> class DBCStorage { @@ -67,19 +62,16 @@ class DBCStorage public: explicit DBCStorage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { } ~DBCStorage() { Clear(); } - T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; } uint32 GetNumRows() const { return nCount; } char const* GetFormat() const { return fmt; } uint32 GetFieldCount() const { return fieldCount; } - bool Load(char const* fn, SqlDbc * sql) { DBCFileLoader dbc; // Check if load was sucessful, only then continue if(!dbc.Load(fn, fmt)) return false; - uint32 sqlRecordCount = 0; uint32 sqlHighestIndex = 0; Field *fields = NULL; @@ -91,7 +83,6 @@ class DBCStorage if (sql->indexPos >= 0) query +=" ORDER BY + " + *sql->indexName + " DESC"; query += ";"; - result = WorldDatabase.Query(query.c_str()); if (result) { @@ -112,9 +103,7 @@ class DBCStorage char * sqlDataTable; fieldCount = dbc.GetCols(); m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable, sqlRecordCount, sqlHighestIndex, sqlDataTable); - m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable)); - // Insert sql data into arrays if (result) { @@ -126,7 +115,6 @@ class DBCStorage { if (!fields) fields = result->Fetch(); - if(sql->indexPos >= 0) { uint32 id = fields[sql->sqlIndexPos].GetUInt32(); @@ -141,7 +129,6 @@ class DBCStorage indexTable[rowIndex]=(T*)&sqlDataTable[offset]; uint32 columnNumber = 0; uint32 sqlColumnNumber = 0; - for(;columnNumber < sql->formatString->size();++columnNumber) { if ((*sql->formatString)[columnNumber] == FT_SQL_ABSENT) @@ -211,44 +198,35 @@ class DBCStorage delete result; return false; } - fields = NULL; ++rowIndex; }while (result->NextRow()); } delete result; } - // error in dbc file at loading if NULL return indexTable!=NULL; } - bool LoadStringsFrom(char const* fn) { // DBC must be already loaded using Load if(!indexTable) return false; - DBCFileLoader dbc; // Check if load was successful, only then continue if(!dbc.Load(fn, fmt)) return false; - m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable)); - return true; } - void Clear() { if (!indexTable) return; - delete[] ((char*)indexTable); indexTable = NULL; delete[] ((char*)m_dataTable); m_dataTable = NULL; - while(!m_stringPoolList.empty()) { delete[] m_stringPoolList.front(); @@ -256,7 +234,6 @@ class DBCStorage } nCount = 0; } - private: char const* fmt; uint32 nCount; @@ -265,5 +242,4 @@ class DBCStorage T* m_dataTable; StringPoolList m_stringPoolList; }; - #endif diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index 572d3db6f1d..9bfae3479bf 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -17,22 +17,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "DatabaseEnv.h" #include "Config/ConfigEnv.h" - #include "Common.h" #include "../../game/UpdateFields.h" - #include <ctime> #include <iostream> #include <fstream> - Database::~Database() { /*Delete objects*/ } - bool Database::Initialize(const char *) { // Enable logging of SQL commands (usally only GM commands) @@ -44,46 +39,37 @@ bool Database::Initialize(const char *) if((m_logsDir.at(m_logsDir.length()-1)!='/') && (m_logsDir.at(m_logsDir.length()-1)!='\\')) m_logsDir.append("/"); } - return true; } - void Database::ThreadStart() { } - void Database::ThreadEnd() { } - void Database::escape_string(std::string& str) { if(str.empty()) return; - char* buf = new char[str.size()*2+1]; escape_string(buf,str.c_str(),str.size()); str = buf; delete[] buf; } - bool Database::PExecuteLog(const char * format,...) { if (!format) return false; - va_list ap; char szQuery [MAX_QUERY_LEN]; va_start(ap, format); int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); va_end(ap); - if(res==-1) { sLog.outError("SQL Query truncated (and not execute) for format: %s",format); return false; } - if( m_logSQL ) { time_t curr; @@ -92,7 +78,6 @@ bool Database::PExecuteLog(const char * format,...) local=*(localtime(&curr)); // dereference and assign char fName[128]; sprintf( fName, "%04d-%02d-%02d_logSQL.sql", local.tm_year+1900, local.tm_mon+1, local.tm_mday ); - FILE* log_file; std::string logsDir_fname = m_logsDir+fName; log_file = fopen(logsDir_fname.c_str(), "a"); @@ -107,74 +92,58 @@ bool Database::PExecuteLog(const char * format,...) sLog.outError("SQL-Logging is disabled - Log file for the SQL commands could not be openend: %s",fName); } } - return Execute(szQuery); } - void Database::SetResultQueue(SqlResultQueue * queue) { m_queryQueues[ACE_Based::Thread::current()] = queue; - } - QueryResult* Database::PQuery(const char *format,...) { if(!format) return NULL; - va_list ap; char szQuery [MAX_QUERY_LEN]; va_start(ap, format); int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); va_end(ap); - if(res==-1) { sLog.outError("SQL Query truncated (and not execute) for format: %s",format); return false; } - return Query(szQuery); } - QueryNamedResult* Database::PQueryNamed(const char *format,...) { if(!format) return NULL; - va_list ap; char szQuery [MAX_QUERY_LEN]; va_start(ap, format); int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); va_end(ap); - if(res==-1) { sLog.outError("SQL Query truncated (and not execute) for format: %s",format); return false; } - return QueryNamed(szQuery); } - bool Database::PExecute(const char * format,...) { if (!format) return false; - va_list ap; char szQuery [MAX_QUERY_LEN]; va_start(ap, format); int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); va_end(ap); - if(res==-1) { sLog.outError("SQL Query truncated (and not execute) for format: %s",format); return false; } - return Execute(szQuery); } - bool Database::_UpdateDataBlobValue(const uint32 guid, const uint32 field, const int32 value) { return PExecute( @@ -184,7 +153,6 @@ bool Database::_UpdateDataBlobValue(const uint32 guid, const uint32 field, const "' ',SUBSTRING_INDEX(`data`,' ',%i)) WHERE guid=%u", field, field+1, value, -int32(PLAYER_END-field), guid); } - bool Database::_SetDataBlobValue(const uint32 guid, const uint32 field, const uint32 value) { return PExecute( @@ -193,27 +161,22 @@ bool Database::_SetDataBlobValue(const uint32 guid, const uint32 field, const ui "%u,' ',SUBSTRING_INDEX(`data`,' ',%i)) WHERE guid=%u", field, value, -int32(PLAYER_END-field), guid); } - bool Database::DirectPExecute(const char * format,...) { if (!format) return false; - va_list ap; char szQuery [MAX_QUERY_LEN]; va_start(ap, format); int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); va_end(ap); - if(res==-1) { sLog.outError("SQL Query truncated (and not execute) for format: %s",format); return false; } - return DirectExecute(szQuery); } - bool Database::CheckRequiredField( char const* table_name, char const* required_name ) { // check required field @@ -223,9 +186,7 @@ bool Database::CheckRequiredField( char const* table_name, char const* required_ delete result; return true; } - // check fail, prepare readabale error message - // search current required_* field in DB QueryNamedResult* result2 = PQueryNamed("SELECT * FROM %s LIMIT 1",table_name); if(result2) @@ -240,9 +201,7 @@ bool Database::CheckRequiredField( char const* table_name, char const* required_ break; } } - delete result2; - if(!reqName.empty()) sLog.outErrorDb("Table `%s` have field `%s` but expected `%s`! Not all sql updates applied?",table_name,reqName.c_str(),required_name); else @@ -250,6 +209,5 @@ bool Database::CheckRequiredField( char const* table_name, char const* required_ } else sLog.outErrorDb("Table `%s` fields list query fail but expected have `%s`! No records in `%s`?",table_name,required_name,table_name); - return false; } diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h index 6172a61c5f9..34438d994dc 100644 --- a/src/shared/Database/Database.h +++ b/src/shared/Database/Database.h @@ -17,48 +17,35 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DATABASE_H #define DATABASE_H - #include "Threading.h" #include "Utilities/UnorderedMap.h" #include "Database/SqlDelayThread.h" - class SqlTransaction; class SqlResultQueue; class SqlQueryHolder; - typedef UNORDERED_MAP<ACE_Based::Thread* , SqlTransaction*> TransactionQueues; typedef UNORDERED_MAP<ACE_Based::Thread* , SqlResultQueue*> QueryQueues; - #define MAX_QUERY_LEN 32*1024 - class TRINITY_DLL_SPEC Database { protected: Database() : m_threadBody(NULL), m_delayThread(NULL) {}; - TransactionQueues m_tranQueues; ///< Transaction queues from diff. threads QueryQueues m_queryQueues; ///< Query queues from diff threads SqlDelayThread* m_threadBody; ///< Pointer to delay sql executer (owned by m_delayThread) ACE_Based::Thread* m_delayThread; ///< Pointer to executer thread - public: - virtual ~Database(); - virtual bool Initialize(const char *infoString); virtual void InitDelayThread() = 0; virtual void HaltDelayThread() = 0; - virtual QueryResult* Query(const char *sql) = 0; QueryResult* PQuery(const char *format,...) ATTR_PRINTF(2,3); virtual QueryNamedResult* QueryNamed(const char *sql) = 0; QueryNamedResult* PQueryNamed(const char *format,...) ATTR_PRINTF(2,3); - /// Async queries and query holders, implemented in DatabaseImpl.h - // Query / member template<class Class> bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql); @@ -96,18 +83,14 @@ class TRINITY_DLL_SPEC Database bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder); template<class Class, typename ParamType1> bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1); - virtual bool Execute(const char *sql) = 0; bool PExecute(const char *format,...) ATTR_PRINTF(2,3); virtual bool DirectExecute(const char* sql) = 0; bool DirectPExecute(const char *format,...) ATTR_PRINTF(2,3); - bool _UpdateDataBlobValue(const uint32 guid, const uint32 field, const int32 value); bool _SetDataBlobValue(const uint32 guid, const uint32 field, const uint32 value); - // Writes SQL commands to a LOG file (see Trinityd.conf "LogSQL") bool PExecuteLog(const char *format,...) ATTR_PRINTF(2,3); - virtual bool BeginTransaction() // nothing do if DB not support transactions { return true; @@ -120,20 +103,15 @@ class TRINITY_DLL_SPEC Database { return false; } - virtual operator bool () const = 0; - virtual unsigned long escape_string(char *to, const char *from, unsigned long length) { strncpy(to,from,length); return length; } void escape_string(std::string& str); - // must be called before first query in thread (one time for thread using one from existed Database objects) virtual void ThreadStart(); // must be called before finish thread run (one time for thread using one from existed Database objects) virtual void ThreadEnd(); - // sets the result queue of the current thread, be careful what thread you call this from void SetResultQueue(SqlResultQueue * queue); - bool CheckRequiredField(char const* table_name, char const* required_name); private: bool m_logSQL; diff --git a/src/shared/Database/DatabaseEnv.h b/src/shared/Database/DatabaseEnv.h index d5d6867e82f..2e89d74e97c 100644 --- a/src/shared/Database/DatabaseEnv.h +++ b/src/shared/Database/DatabaseEnv.h @@ -17,17 +17,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #if !defined(DATABASEENV_H) #define DATABASEENV_H - #include "Common.h" #include "Log.h" #include "Errors.h" - #include "Database/Field.h" #include "Database/QueryResult.h" - #ifdef DO_POSTGRESQL #include "Database/QueryResultPostgre.h" #include "Database/Database.h" @@ -47,10 +43,8 @@ typedef DatabaseMysql DatabaseType; #define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )" #define _OFFSET_ "LIMIT %d,1" #endif - extern DatabaseType WorldDatabase; extern DatabaseType CharacterDatabase; extern DatabaseType loginDatabase; - #endif diff --git a/src/shared/Database/DatabaseImpl.h b/src/shared/Database/DatabaseImpl.h index 7cbd0ed8ba5..ac856664290 100644 --- a/src/shared/Database/DatabaseImpl.h +++ b/src/shared/Database/DatabaseImpl.h @@ -17,12 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Database/Database.h" #include "Database/SqlOperations.h" - /// Function body definitions for the template function members of the Database class - #define ASYNC_QUERY_BODY(sql, queue_itr) \ if (!sql) return false; \ \ @@ -33,7 +30,6 @@ queue_itr = m_queryQueues.find(queryThread); \ if (queue_itr == m_queryQueues.end()) return false; \ } - #define ASYNC_PQUERY_BODY(format, szQuery) \ if(!format) return false; \ \ @@ -52,7 +48,6 @@ return false; \ } \ } - #define ASYNC_DELAYHOLDER_BODY(holder, queue_itr) \ if (!holder) return false; \ \ @@ -63,9 +58,7 @@ queue_itr = m_queryQueues.find(queryThread); \ if (queue_itr == m_queryQueues.end()) return false; \ } - // -- Query / member -- - template<class Class> bool Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const char *sql) @@ -73,7 +66,6 @@ Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*), const c ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class>(object, method), itr->second)); } - template<class Class, typename ParamType1> bool Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql) @@ -81,7 +73,6 @@ Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamTyp ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1>(object, method, (QueryResult*)NULL, param1), itr->second)); } - template<class Class, typename ParamType1, typename ParamType2> bool Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql) @@ -89,7 +80,6 @@ Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamTyp ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second)); } - template<class Class, typename ParamType1, typename ParamType2, typename ParamType3> bool Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql) @@ -97,9 +87,7 @@ Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamTyp ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult*)NULL, param1, param2, param3), itr->second)); } - // -- Query / static -- - template<typename ParamType1> bool Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql) @@ -107,7 +95,6 @@ Database::AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1 ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1>(method, (QueryResult*)NULL, param1), itr->second)); } - template<typename ParamType1, typename ParamType2> bool Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql) @@ -115,7 +102,6 @@ Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), Param ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second)); } - template<typename ParamType1, typename ParamType2, typename ParamType3> bool Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql) @@ -123,9 +109,7 @@ Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamT ASYNC_QUERY_BODY(sql, itr) return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult*)NULL, param1, param2, param3), itr->second)); } - // -- PQuery / member -- - template<class Class> bool Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) @@ -133,7 +117,6 @@ Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(object, method, szQuery); } - template<class Class, typename ParamType1> bool Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) @@ -141,7 +124,6 @@ Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamTy ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(object, method, param1, szQuery); } - template<class Class, typename ParamType1, typename ParamType2> bool Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) @@ -149,7 +131,6 @@ Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamTy ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(object, method, param1, param2, szQuery); } - template<class Class, typename ParamType1, typename ParamType2, typename ParamType3> bool Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) @@ -157,9 +138,7 @@ Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamTy ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(object, method, param1, param2, param3, szQuery); } - // -- PQuery / static -- - template<typename ParamType1> bool Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) @@ -167,7 +146,6 @@ Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(method, param1, szQuery); } - template<typename ParamType1, typename ParamType2> bool Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) @@ -175,7 +153,6 @@ Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), Para ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(method, param1, param2, szQuery); } - template<typename ParamType1, typename ParamType2, typename ParamType3> bool Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) @@ -183,9 +160,7 @@ Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2, Param ASYNC_PQUERY_BODY(format, szQuery) return AsyncQuery(method, param1, param2, param3, szQuery); } - // -- QueryHolder -- - template<class Class> bool Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder) @@ -193,7 +168,6 @@ Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, Sq ASYNC_DELAYHOLDER_BODY(holder, itr) return holder->Execute(new Trinity::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult*)NULL, holder), m_threadBody, itr->second); } - template<class Class, typename ParamType1> bool Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1) @@ -201,7 +175,6 @@ Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, Sq ASYNC_DELAYHOLDER_BODY(holder, itr) return holder->Execute(new Trinity::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult*)NULL, holder, param1), m_threadBody, itr->second); } - #undef ASYNC_QUERY_BODY #undef ASYNC_PQUERY_BODY #undef ASYNC_DELAYHOLDER_BODY diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp index f08ea67cbbe..235fb96f127 100644 --- a/src/shared/Database/DatabaseMysql.cpp +++ b/src/shared/Database/DatabaseMysql.cpp @@ -17,9 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DO_POSTGRESQL - #include "Util.h" #include "Policies/SingletonImp.h" #include "Platform/Define.h" @@ -28,19 +26,15 @@ #include "Database/MySQLDelayThread.h" #include "Database/SqlOperations.h" #include "Timer.h" - void DatabaseMysql::ThreadStart() { mysql_thread_init(); } - void DatabaseMysql::ThreadEnd() { mysql_thread_end(); } - size_t DatabaseMysql::db_count = 0; - DatabaseMysql::DatabaseMysql() : Database(), mMysql(0) { // before first connection @@ -48,7 +42,6 @@ DatabaseMysql::DatabaseMysql() : Database(), mMysql(0) { // Mysql Library Init mysql_library_init(-1, NULL, NULL); - if (!mysql_thread_safe()) { sLog.outError("FATAL ERROR: Used MySQL library isn't thread-safe."); @@ -56,26 +49,20 @@ DatabaseMysql::DatabaseMysql() : Database(), mMysql(0) } } } - DatabaseMysql::~DatabaseMysql() { if (m_delayThread) HaltDelayThread(); - if (mMysql) mysql_close(mMysql); - //Free Mysql library pointers for last ~DB if(--db_count == 0) mysql_library_end(); } - bool DatabaseMysql::Initialize(const char *infoString) { - if(!Database::Initialize(infoString)) return false; - tranThread = NULL; MYSQL *mysqlInit; mysqlInit = mysql_init(NULL); @@ -84,19 +71,13 @@ bool DatabaseMysql::Initialize(const char *infoString) sLog.outError( "Could not initialize Mysql connection" ); return false; } - InitDelayThread(); - Tokens tokens = StrSplit(infoString, ";"); - Tokens::iterator iter; - std::string host, port_or_socket, user, password, database; int port; char const* unix_socket; - iter = tokens.begin(); - if(iter != tokens.end()) host = *iter++; if(iter != tokens.end()) @@ -107,7 +88,6 @@ bool DatabaseMysql::Initialize(const char *infoString) password = *iter++; if(iter != tokens.end()) database = *iter++; - mysql_options(mysqlInit,MYSQL_SET_CHARSET_NAME,"utf8"); #ifdef WIN32 if(host==".") // named pipe use option (Windows) @@ -137,17 +117,14 @@ bool DatabaseMysql::Initialize(const char *infoString) unix_socket = 0; } #endif - mMysql = mysql_real_connect(mysqlInit, host.c_str(), user.c_str(), password.c_str(), database.c_str(), port, unix_socket, 0); - if (mMysql) { sLog.outDetail( "Connected to MySQL database at %s", host.c_str()); sLog.outString( "MySQL client library: %s", mysql_get_client_info()); sLog.outString( "MySQL server ver: %s ", mysql_get_server_info( mMysql)); - /*----------SET AUTOCOMMIT ON---------*/ // It seems mysql 5.0.x have enabled this feature // by default. In crash case you can lose data!!! @@ -161,12 +138,10 @@ bool DatabaseMysql::Initialize(const char *infoString) else sLog.outDetail("AUTOCOMMIT NOT SET TO 1"); /*-------------------------------------*/ - // set connection properties to UTF8 to properly handle locales for different // server configs - core sends data in UTF8, so MySQL must expect UTF8 too PExecute("SET NAMES `utf8`"); PExecute("SET CHARACTER SET `utf8`"); - #if MYSQL_VERSION_ID >= 50003 my_bool my_true = (my_bool)1; if (mysql_options(mMysql, MYSQL_OPT_RECONNECT, &my_true)) @@ -180,7 +155,6 @@ bool DatabaseMysql::Initialize(const char *infoString) #else #warning "Your mySQL client lib version does not support reconnecting after a timeout.\nIf this causes you any trouble we advice you to upgrade your mySQL client libs to at least mySQL 5.0.13 to resolve this problem." #endif - return true; } else @@ -191,12 +165,10 @@ bool DatabaseMysql::Initialize(const char *infoString) return false; } } - bool DatabaseMysql::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount) { if (!mMysql) return 0; - { // guarded block for thread-safe mySQL request ACE_Guard<ACE_Thread_Mutex> query_connection_guard(mMutex); @@ -215,72 +187,54 @@ bool DatabaseMysql::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **p sLog.outDebug("[%u ms] SQL: %s", getMSTimeDiff(_s,getMSTime()), sql ); #endif } - *pResult = mysql_store_result(mMysql); *pRowCount = mysql_affected_rows(mMysql); *pFieldCount = mysql_field_count(mMysql); // end guarded block } - if (!*pResult ) return false; - if (!*pRowCount) { mysql_free_result(*pResult); return false; } - *pFields = mysql_fetch_fields(*pResult); return true; } - QueryResult* DatabaseMysql::Query(const char *sql) { MYSQL_RES *result = NULL; MYSQL_FIELD *fields = NULL; uint64 rowCount = 0; uint32 fieldCount = 0; - if(!_Query(sql,&result,&fields,&rowCount,&fieldCount)) return NULL; - QueryResultMysql *queryResult = new QueryResultMysql(result, fields, rowCount, fieldCount); - queryResult->NextRow(); - return queryResult; } - QueryNamedResult* DatabaseMysql::QueryNamed(const char *sql) { MYSQL_RES *result = NULL; MYSQL_FIELD *fields = NULL; uint64 rowCount = 0; uint32 fieldCount = 0; - if(!_Query(sql,&result,&fields,&rowCount,&fieldCount)) return NULL; - QueryFieldNames names(fieldCount); for (uint32 i = 0; i < fieldCount; i++) names[i] = fields[i].name; - QueryResultMysql *queryResult = new QueryResultMysql(result, fields, rowCount, fieldCount); - queryResult->NextRow(); - return new QueryNamedResult(queryResult,names); } - bool DatabaseMysql::Execute(const char *sql) { if (!mMysql) return false; - // don't use queued execution if it has not been initialized if (!m_threadBody) return DirectExecute(sql); - tranThread = ACE_Based::Thread::current(); // owner of this transaction TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) @@ -292,19 +246,15 @@ bool DatabaseMysql::Execute(const char *sql) // Simple sql statement m_threadBody->Delay(new SqlStatement(sql)); } - return true; } - bool DatabaseMysql::DirectExecute(const char* sql) { if (!mMysql) return false; - { // guarded block for thread-safe mySQL request ACE_Guard<ACE_Thread_Mutex> query_connection_guard(mMutex); - #ifdef MANGOS_DEBUG uint32 _s = getMSTime(); #endif @@ -322,10 +272,8 @@ bool DatabaseMysql::DirectExecute(const char* sql) } // end guarded block } - return true; } - bool DatabaseMysql::_TransactionCmd(const char *sql) { if (mysql_query(mMysql, sql)) @@ -340,18 +288,15 @@ bool DatabaseMysql::_TransactionCmd(const char *sql) } return true; } - bool DatabaseMysql::BeginTransaction() { if (!mMysql) return false; - // don't use queued execution if it has not been initialized if (!m_threadBody) { if (tranThread == ACE_Based::Thread::current()) return false; // huh? this thread already started transaction - mMutex.acquire(); if (!_TransactionCmd("START TRANSACTION")) { @@ -360,24 +305,19 @@ bool DatabaseMysql::BeginTransaction() } return true; // transaction started } - tranThread = ACE_Based::Thread::current(); // owner of this transaction TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) // If for thread exists queue and also contains transaction // delete that transaction (not allow trans in trans) delete i->second; - m_tranQueues[tranThread] = new SqlTransaction(); - return true; } - bool DatabaseMysql::CommitTransaction() { if (!mMysql) return false; - // don't use queued execution if it has not been initialized if (!m_threadBody) { @@ -388,7 +328,6 @@ bool DatabaseMysql::CommitTransaction() mMutex.release(); return _res; } - tranThread = ACE_Based::Thread::current(); TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) @@ -400,12 +339,10 @@ bool DatabaseMysql::CommitTransaction() else return false; } - bool DatabaseMysql::RollbackTransaction() { if (!mMysql) return false; - // don't use queued execution if it has not been initialized if (!m_threadBody) { @@ -416,7 +353,6 @@ bool DatabaseMysql::RollbackTransaction() mMutex.release(); return _res; } - tranThread = ACE_Based::Thread::current(); TransactionQueues::iterator i = m_tranQueues.find(tranThread); if (i != m_tranQueues.end() && i->second != NULL) @@ -426,28 +362,22 @@ bool DatabaseMysql::RollbackTransaction() } return true; } - unsigned long DatabaseMysql::escape_string(char *to, const char *from, unsigned long length) { if (!mMysql || !to || !from || !length) return 0; - return(mysql_real_escape_string(mMysql, to, from, length)); } - void DatabaseMysql::InitDelayThread() { assert(!m_delayThread); - //New delay thread for delay execute m_threadBody = new MySQLDelayThread(this); // will deleted at m_delayThread delete m_delayThread = new ACE_Based::Thread(m_threadBody); } - void DatabaseMysql::HaltDelayThread() { if (!m_threadBody || !m_delayThread) return; - m_threadBody->Stop(); //Stop event m_delayThread->wait(); //Wait for flush to DB delete m_delayThread; //This also deletes m_threadBody diff --git a/src/shared/Database/DatabaseMysql.h b/src/shared/Database/DatabaseMysql.h index 4612ebfc462..3a7fa4f5def 100644 --- a/src/shared/Database/DatabaseMysql.h +++ b/src/shared/Database/DatabaseMysql.h @@ -17,17 +17,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DO_POSTGRESQL - #ifndef _DATABASEMYSQL_H #define _DATABASEMYSQL_H - #include "Database.h" #include "Policies/Singleton.h" #include "ace/Thread_Mutex.h" #include "ace/Guard_T.h" - #ifdef WIN32 #define FD_SETSIZE 1024 #include <winsock2.h> @@ -35,15 +31,12 @@ #else #include <mysql.h> #endif - class TRINITY_DLL_SPEC DatabaseMysql : public Database { friend class Trinity::OperatorNew<DatabaseMysql>; - public: DatabaseMysql(); ~DatabaseMysql(); - //! Initializes Mysql and connects to a server. /*! infoString should be formated like hostname;username;password;database. */ bool Initialize(const char *infoString); @@ -56,25 +49,18 @@ class TRINITY_DLL_SPEC DatabaseMysql : public Database bool BeginTransaction(); bool CommitTransaction(); bool RollbackTransaction(); - operator bool () const { return mMysql != NULL; } - unsigned long escape_string(char *to, const char *from, unsigned long length); using Database::escape_string; - // must be call before first query in thread void ThreadStart(); // must be call before finish thread run void ThreadEnd(); private: ACE_Thread_Mutex mMutex; - ACE_Based::Thread * tranThread; - MYSQL *mMysql; - static size_t db_count; - bool _TransactionCmd(const char *sql); bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount); }; diff --git a/src/shared/Database/Field.cpp b/src/shared/Database/Field.cpp index 9a1fbfa5178..2467eabd448 100644 --- a/src/shared/Database/Field.cpp +++ b/src/shared/Database/Field.cpp @@ -17,28 +17,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "DatabaseEnv.h" - Field::Field() : mValue(NULL), mType(DB_TYPE_UNKNOWN) { } - Field::Field(Field &f) { const char *value; - value = f.GetString(); - if (value && (mValue = new char[strlen(value) + 1])) strcpy(mValue, value); else mValue = NULL; - mType = f.GetType(); } - Field::Field(const char *value, enum Field::DataTypes type) : mType(type) { @@ -47,16 +40,13 @@ mType(type) else mValue = NULL; } - Field::~Field() { if(mValue) delete [] mValue; } - void Field::SetValue(const char *value) { if(mValue) delete [] mValue; - if (value) { mValue = new char[strlen(value) + 1]; diff --git a/src/shared/Database/Field.h b/src/shared/Database/Field.h index d1238f838a5..fd259423aef 100644 --- a/src/shared/Database/Field.h +++ b/src/shared/Database/Field.h @@ -17,14 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #if !defined(FIELD_H) #define FIELD_H - class Field { public: - enum DataTypes { DB_TYPE_UNKNOWN = 0x00, @@ -33,15 +30,11 @@ class Field DB_TYPE_FLOAT = 0x03, DB_TYPE_BOOL = 0x04 }; - Field(); Field(Field &f); Field(const char *value, enum DataTypes type); - ~Field(); - enum DataTypes GetType() const { return mType; } - const char *GetString() const { return mValue; } std::string GetCppString() const { @@ -76,11 +69,8 @@ class Field else return 0; } - void SetType(enum DataTypes type) { mType = type; } - void SetValue(const char *value); - private: char *mValue; enum DataTypes mType; diff --git a/src/shared/Database/MySQLDelayThread.h b/src/shared/Database/MySQLDelayThread.h index fcebe3fbd35..f8dba08bddc 100644 --- a/src/shared/Database/MySQLDelayThread.h +++ b/src/shared/Database/MySQLDelayThread.h @@ -17,12 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __MYSQLDELAYTHREAD_H #define __MYSQLDELAYTHREAD_H - #include "Database/SqlDelayThread.h" - class MySQLDelayThread : public SqlDelayThread { public: diff --git a/src/shared/Database/QueryResult.h b/src/shared/Database/QueryResult.h index f9f1a009833..9d5bb57e4e9 100644 --- a/src/shared/Database/QueryResult.h +++ b/src/shared/Database/QueryResult.h @@ -17,52 +17,39 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #if !defined(QUERYRESULT_H) #define QUERYRESULT_H - class TRINITY_DLL_SPEC QueryResult { public: QueryResult(uint64 rowCount, uint32 fieldCount) : mFieldCount(fieldCount), mRowCount(rowCount) {} - virtual ~QueryResult() {} - virtual bool NextRow() = 0; - Field *Fetch() const { return mCurrentRow; } - const Field & operator [] (int index) const { return mCurrentRow[index]; } - uint32 GetFieldCount() const { return mFieldCount; } uint64 GetRowCount() const { return mRowCount; } - protected: Field *mCurrentRow; uint32 mFieldCount; uint64 mRowCount; }; - typedef std::vector<std::string> QueryFieldNames; - class MANGOS_DLL_SPEC QueryNamedResult { public: explicit QueryNamedResult(QueryResult* query, QueryFieldNames const& names) : mQuery(query), mFieldNames(names) {} ~QueryNamedResult() { delete mQuery; } - // compatible interface with QueryResult bool NextRow() { return mQuery->NextRow(); } Field *Fetch() const { return mQuery->Fetch(); } uint32 GetFieldCount() const { return mQuery->GetFieldCount(); } uint64 GetRowCount() const { return mQuery->GetRowCount(); } Field const& operator[] (int index) const { return (*mQuery)[index]; } - // named access Field const& operator[] (const std::string &name) const { return mQuery->Fetch()[GetField_idx(name)]; } QueryFieldNames const& GetFieldNames() const { return mFieldNames; } - uint32 GetField_idx(const std::string &name) const { for(size_t idx = 0; idx < mFieldNames.size(); ++idx) @@ -73,11 +60,9 @@ class MANGOS_DLL_SPEC QueryNamedResult ASSERT(false && "unknown field name"); return uint32(-1); } - protected: QueryResult *mQuery; QueryFieldNames mFieldNames; }; - #endif diff --git a/src/shared/Database/QueryResultMysql.cpp b/src/shared/Database/QueryResultMysql.cpp index 2e4738469c9..ef8a77ec002 100644 --- a/src/shared/Database/QueryResultMysql.cpp +++ b/src/shared/Database/QueryResultMysql.cpp @@ -17,47 +17,35 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DO_POSTGRESQL - #include "DatabaseEnv.h" - QueryResultMysql::QueryResultMysql(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount) : QueryResult(rowCount, fieldCount), mResult(result) { - mCurrentRow = new Field[mFieldCount]; ASSERT(mCurrentRow); - for (uint32 i = 0; i < mFieldCount; i++) mCurrentRow[i].SetType(ConvertNativeType(fields[i].type)); } - QueryResultMysql::~QueryResultMysql() { EndQuery(); } - bool QueryResultMysql::NextRow() { MYSQL_ROW row; - if (!mResult) return false; - row = mysql_fetch_row(mResult); if (!row) { EndQuery(); return false; } - for (uint32 i = 0; i < mFieldCount; i++) mCurrentRow[i].SetValue(row[i]); - return true; } - void QueryResultMysql::EndQuery() { if (mCurrentRow) @@ -65,14 +53,12 @@ void QueryResultMysql::EndQuery() delete [] mCurrentRow; mCurrentRow = 0; } - if (mResult) { mysql_free_result(mResult); mResult = 0; } } - enum Field::DataTypes QueryResultMysql::ConvertNativeType(enum_field_types mysqlType) const { switch (mysqlType) @@ -89,7 +75,6 @@ enum Field::DataTypes QueryResultMysql::ConvertNativeType(enum_field_types mysql case FIELD_TYPE_NULL: return Field::DB_TYPE_STRING; case FIELD_TYPE_TINY: - case FIELD_TYPE_SHORT: case FIELD_TYPE_LONG: case FIELD_TYPE_INT24: diff --git a/src/shared/Database/QueryResultMysql.h b/src/shared/Database/QueryResultMysql.h index 89aceb12b13..fb9d422ebf2 100644 --- a/src/shared/Database/QueryResultMysql.h +++ b/src/shared/Database/QueryResultMysql.h @@ -17,12 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DO_POSTGRESQL - #if !defined(QUERYRESULTMYSQL_H) #define QUERYRESULTMYSQL_H - #ifdef WIN32 #define FD_SETSIZE 1024 #include <winsock2.h> @@ -30,20 +27,15 @@ #else #include <mysql.h> #endif - class QueryResultMysql : public QueryResult { public: QueryResultMysql(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount); - ~QueryResultMysql(); - bool NextRow(); - private: enum Field::DataTypes ConvertNativeType(enum_field_types mysqlType) const; void EndQuery(); - MYSQL_RES *mResult; }; #endif diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index 372baafe278..e4de05c7c77 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -17,16 +17,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "SQLStorage.h" #include "SQLStorageImpl.h" - #ifdef DO_POSTGRESQL extern DatabasePostgre WorldDatabase; #else extern DatabaseMysql WorldDatabase; #endif - const char CreatureInfosrcfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiiffliiiiiliiis"; const char CreatureInfodstfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiiffliiiiiliiii"; const char CreatureDataAddonInfofmt[]="iiiiiiis"; @@ -40,7 +37,6 @@ const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii const char PageTextfmt[]="isi"; const char InstanceTemplatesrcfmt[]="iiiiiiffffs"; const char InstanceTemplatedstfmt[]="iiiiiiffffi"; - SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template"); SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon"); SQLStorage sCreatureModelStorage(CreatureModelfmt,"modelid","creature_model_info"); @@ -50,7 +46,6 @@ SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameo SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template"); SQLStorage sPageTextStore(PageTextfmt,"entry","page_text"); SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template"); - void SQLStorage::Free () { uint32 offset=0; @@ -60,7 +55,6 @@ void SQLStorage::Free () for(uint32 y=0;y<MaxEntry;y++) if(pIndex[y]) delete [] *(char**)((char*)(pIndex[y])+offset); - offset += sizeof(char*); } else if (dst_format[x]==FT_LOGIC) @@ -69,11 +63,9 @@ void SQLStorage::Free () offset += sizeof(char); else offset += 4; - delete [] pIndex; delete [] data; } - void SQLStorage::Load() { SQLStorageLoader loader; diff --git a/src/shared/Database/SQLStorage.h b/src/shared/Database/SQLStorage.h index cc165af532e..96f817c64e7 100644 --- a/src/shared/Database/SQLStorage.h +++ b/src/shared/Database/SQLStorage.h @@ -17,27 +17,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef SQLSTORAGE_H #define SQLSTORAGE_H - #include "Common.h" #include "Database/DatabaseEnv.h" - class SQLStorage { template<class T> friend struct SQLStorageLoaderBase; - public: - SQLStorage(const char* fmt, const char * _entry_field, const char * sqlname) { src_format = fmt; dst_format = fmt; init(_entry_field, sqlname); } - SQLStorage(const char* src_fmt, const char* dst_fmt, const char * _entry_field, const char * sqlname) { src_format = src_fmt; @@ -45,12 +39,10 @@ class SQLStorage init(_entry_field, sqlname); } - ~SQLStorage() { Free(); } - template<class T> T const* LookupEntry(uint32 id) const { @@ -60,16 +52,12 @@ class SQLStorage return NULL; return reinterpret_cast<T const*>(pIndex[id]); } - uint32 RecordCount; uint32 MaxEntry; uint32 iNumFields; - char const* GetTableName() const { return table; } - void Load(); void Free(); - private: void init(const char * _entry_field, const char * sqlname) { @@ -80,9 +68,7 @@ class SQLStorage iNumFields = strlen(src_format); MaxEntry = 0; } - char** pIndex; - char *data; const char *src_format; const char *dst_format; @@ -90,13 +76,11 @@ class SQLStorage const char *entry_field; //bool HasString; }; - template <class T> struct SQLStorageLoaderBase { public: void Load(SQLStorage &storage); - template<class S, class D> void convert(uint32 field_pos, S src, D &dst); template<class S> @@ -104,16 +88,13 @@ struct SQLStorageLoaderBase template<class D> void convert_from_str(uint32 field_pos, char * src, D& dst); void convert_str_to_str(uint32 field_pos, char *src, char *&dst); - private: template<class V> void storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset); void storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset); }; - struct SQLStorageLoader : public SQLStorageLoaderBase<SQLStorageLoader> { }; - #endif diff --git a/src/shared/Database/SQLStorageImpl.h b/src/shared/Database/SQLStorageImpl.h index b511bdad68c..c229327a0ec 100644 --- a/src/shared/Database/SQLStorageImpl.h +++ b/src/shared/Database/SQLStorageImpl.h @@ -15,18 +15,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "ProgressBar.h" #include "Log.h" #include "DBCFileLoader.h" - template<class T> template<class S, class D> void SQLStorageLoaderBase<T>::convert(uint32 /*field_pos*/, S src, D &dst) { dst = D(src); } - template<class T> void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 /*field_pos*/, char *src, char *&dst) { @@ -42,7 +39,6 @@ void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 /*field_pos*/, char *src memcpy(dst, src, l); } } - template<class T> template<class S> void SQLStorageLoaderBase<T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, char * & dst) @@ -50,14 +46,12 @@ void SQLStorageLoaderBase<T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, ch dst = new char[1]; *dst = 0; } - template<class T> template<class D> void SQLStorageLoaderBase<T>::convert_from_str(uint32 /*field_pos*/, char * /*src*/, D& dst) { dst = 0; } - template<class T> template<class V> void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset) @@ -87,7 +81,6 @@ void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage &store, char *p, in break; } } - template<class T> void SQLStorageLoaderBase<T>::storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset) { @@ -116,7 +109,6 @@ void SQLStorageLoaderBase<T>::storeValue(char * value, SQLStorage &store, char * break; } } - template<class T> void SQLStorageLoaderBase<T>::Load(SQLStorage &store) { @@ -128,10 +120,8 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage &store) sLog.outError("Error loading %s table (not exist?)\n", store.table); exit(1); // Stop server at loading non exited table or not accessable table } - maxi = (*result)[0].GetUInt32()+1; delete result; - result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table); if(result) { @@ -141,19 +131,15 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage &store) } else store.RecordCount = 0; - result = WorldDatabase.PQuery("SELECT * FROM %s", store.table); - if(!result) { sLog.outError("%s table is empty!\n", store.table); store.RecordCount = 0; return; } - uint32 recordsize = 0; uint32 offset = 0; - if(store.iNumFields != result->GetFieldCount()) { store.RecordCount = 0; @@ -161,7 +147,6 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage &store) delete result; exit(1); // Stop server at loading broken or non-compatible table. } - //get struct size uint32 sc=0; uint32 bo=0; @@ -174,10 +159,8 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage &store) else if (store.dst_format[x]==FT_BYTE) ++bb; recordsize=(store.iNumFields-sc-bo-bb)*4+sc*sizeof(char*)+bo*sizeof(bool)+bb*sizeof(char); - char** newIndex=new char*[maxi]; memset(newIndex,0,maxi*sizeof(char*)); - char * _data= new char[store.RecordCount *recordsize]; uint32 count=0; barGoLink bar( store.RecordCount ); @@ -187,7 +170,6 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage &store) bar.step(); char *p=(char*)&_data[recordsize*count]; newIndex[fields[0].GetUInt32()]=p; - offset=0; for(uint32 x = 0; x < store.iNumFields; x++) switch(store.src_format[x]) @@ -205,9 +187,7 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage &store) } ++count; }while( result->NextRow() ); - delete result; - store.pIndex = newIndex; store.MaxEntry = maxi; store.data = _data; diff --git a/src/shared/Database/SqlDelayThread.cpp b/src/shared/Database/SqlDelayThread.cpp index 88b6b85df70..bca8dcd8cd6 100644 --- a/src/shared/Database/SqlDelayThread.cpp +++ b/src/shared/Database/SqlDelayThread.cpp @@ -17,21 +17,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Database/SqlDelayThread.h" #include "Database/SqlOperations.h" #include "DatabaseEnv.h" - SqlDelayThread::SqlDelayThread(Database* db) : m_dbEngine(db), m_running(true) { } - void SqlDelayThread::run() { #ifndef DO_POSTGRESQL mysql_thread_init(); #endif - while (m_running) { // if the running state gets turned off while sleeping @@ -44,12 +40,10 @@ void SqlDelayThread::run() delete s; } } - #ifndef DO_POSTGRESQL mysql_thread_end(); #endif } - void SqlDelayThread::Stop() { m_running = false; diff --git a/src/shared/Database/SqlDelayThread.h b/src/shared/Database/SqlDelayThread.h index 3c24d3525b7..422b01ac650 100644 --- a/src/shared/Database/SqlDelayThread.h +++ b/src/shared/Database/SqlDelayThread.h @@ -17,34 +17,26 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __SQLDELAYTHREAD_H #define __SQLDELAYTHREAD_H - #include "ace/Thread_Mutex.h" #include "LockedQueue.h" #include "Threading.h" - class Database; class SqlOperation; - class SqlDelayThread : public ACE_Based::Runnable { typedef ACE_Based::LockedQueue<SqlOperation*, ACE_Thread_Mutex> SqlQueue; - private: SqlQueue m_sqlQueue; ///< Queue of SQL statements Database* m_dbEngine; ///< Pointer to used Database engine volatile bool m_running; - SqlDelayThread(); public: SqlDelayThread(Database* db); - ///< Put sql statement to delay queue bool Delay(SqlOperation* sql) { m_sqlQueue.add(sql); return true; } - virtual void Stop(); ///< Stop event virtual void run(); ///< Main Thread loop }; diff --git a/src/shared/Database/SqlOperations.cpp b/src/shared/Database/SqlOperations.cpp index 396f2e36bc2..9ca698d733e 100644 --- a/src/shared/Database/SqlOperations.cpp +++ b/src/shared/Database/SqlOperations.cpp @@ -17,20 +17,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "SqlOperations.h" #include "SqlDelayThread.h" #include "DatabaseEnv.h" #include "DatabaseImpl.h" - /// ---- ASYNC STATEMENTS / TRANSACTIONS ---- - void SqlStatement::Execute(Database *db) { /// just do it db->DirectExecute(m_sql); } - void SqlTransaction::Execute(Database *db) { if(m_queue.empty()) @@ -40,7 +36,6 @@ void SqlTransaction::Execute(Database *db) { char const *sql = m_queue.front(); m_queue.pop(); - if(!db->DirectExecute(sql)) { free((void*)const_cast<char*>(sql)); @@ -52,14 +47,11 @@ void SqlTransaction::Execute(Database *db) } return; } - free((void*)const_cast<char*>(sql)); } db->DirectExecute("COMMIT"); } - /// ---- ASYNC QUERIES ---- - void SqlQuery::Execute(Database *db) { if(!m_callback || !m_queue) @@ -69,7 +61,6 @@ void SqlQuery::Execute(Database *db) /// add the callback to the sql result queue of the thread it originated from m_queue->add(m_callback); } - void SqlResultQueue::Update() { /// execute the callbacks waiting in the synchronization queue @@ -80,19 +71,16 @@ void SqlResultQueue::Update() delete callback; } } - bool SqlQueryHolder::Execute(Trinity::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue) { if(!callback || !thread || !queue) return false; - /// delay the execution of the queries, sync them with the delay thread /// which will in turn resync on execution (via the queue) and call back SqlQueryHolderEx *holderEx = new SqlQueryHolderEx(this, callback, queue); thread->Delay(holderEx); return true; } - bool SqlQueryHolder::SetQuery(size_t index, const char *sql) { if(m_queries.size() <= index) @@ -100,19 +88,16 @@ bool SqlQueryHolder::SetQuery(size_t index, const char *sql) sLog.outError("Query index (%u) out of range (size: %u) for query: %s",index,(uint32)m_queries.size(),sql); return false; } - if(m_queries[index].first != NULL) { sLog.outError("Attempt assign query to holder index (%u) where other query stored (Old: [%s] New: [%s])", index,m_queries[index].first,sql); return false; } - /// not executed yet, just stored (it's not called a holder for nothing) m_queries[index] = SqlResultPair(strdup(sql), NULL); return true; } - bool SqlQueryHolder::SetPQuery(size_t index, const char *format, ...) { if(!format) @@ -120,22 +105,18 @@ bool SqlQueryHolder::SetPQuery(size_t index, const char *format, ...) sLog.outError("Query (index: %u) is empty.",index); return false; } - va_list ap; char szQuery [MAX_QUERY_LEN]; va_start(ap, format); int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); va_end(ap); - if(res==-1) { sLog.outError("SQL Query truncated (and not execute) for format: %s",format); return false; } - return SetQuery(index,szQuery); } - QueryResult* SqlQueryHolder::GetResult(size_t index) { if(index < m_queries.size()) @@ -152,14 +133,12 @@ QueryResult* SqlQueryHolder::GetResult(size_t index) else return NULL; } - void SqlQueryHolder::SetResult(size_t index, QueryResult *result) { /// store the result in the holder if(index < m_queries.size()) m_queries[index].second = result; } - SqlQueryHolder::~SqlQueryHolder() { for(size_t i = 0; i < m_queries.size(); i++) @@ -174,28 +153,23 @@ SqlQueryHolder::~SqlQueryHolder() } } } - void SqlQueryHolder::SetSize(size_t size) { /// to optimize push_back, reserve the number of queries about to be executed m_queries.resize(size); } - void SqlQueryHolderEx::Execute(Database *db) { if(!m_holder || !m_callback || !m_queue) return; - /// we can do this, we are friends std::vector<SqlQueryHolder::SqlResultPair> &queries = m_holder->m_queries; - for(size_t i = 0; i < queries.size(); i++) { /// execute all queries in the holder and pass the results char const *sql = queries[i].first; if(sql) m_holder->SetResult(i, db->Query(sql)); } - /// sync with the caller thread m_queue->add(m_callback); } diff --git a/src/shared/Database/SqlOperations.h b/src/shared/Database/SqlOperations.h index e91d83b6611..164c7258ec3 100644 --- a/src/shared/Database/SqlOperations.h +++ b/src/shared/Database/SqlOperations.h @@ -17,22 +17,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __SQLOPERATIONS_H #define __SQLOPERATIONS_H - #include "Common.h" - #include "ace/Thread_Mutex.h" #include "LockedQueue.h" #include <queue> #include "Utilities/Callback.h" - /// ---- BASE --- - class Database; class SqlDelayThread; - class SqlOperation { public: @@ -40,9 +34,7 @@ class SqlOperation virtual void Execute(Database *db) = 0; virtual ~SqlOperation() {} }; - /// ---- ASYNC STATEMENTS / TRANSACTIONS ---- - class SqlStatement : public SqlOperation { private: @@ -52,7 +44,6 @@ class SqlStatement : public SqlOperation ~SqlStatement() { void* tofree = const_cast<char*>(m_sql); free(tofree); } void Execute(Database *db); }; - class SqlTransaction : public SqlOperation { private: @@ -62,22 +53,18 @@ class SqlTransaction : public SqlOperation void DelayExecute(const char *sql) { m_queue.push(strdup(sql)); } void Execute(Database *db); }; - /// ---- ASYNC QUERIES ---- - class SqlQuery; /// contains a single async query class QueryResult; /// the result of one class SqlResultQueue; /// queue for thread sync class SqlQueryHolder; /// groups several async quries class SqlQueryHolderEx; /// points to a holder, added to the delay thread - class SqlResultQueue : public ACE_Based::LockedQueue<MaNGOS::IQueryCallback* , ACE_Thread_Mutex> { public: SqlResultQueue() {} void Update(); }; - class SqlQuery : public SqlOperation { private: @@ -90,7 +77,6 @@ class SqlQuery : public SqlOperation ~SqlQuery() { void* tofree = const_cast<char*>(m_sql); free(tofree); } void Execute(Database *db); }; - class SqlQueryHolder { friend class SqlQueryHolderEx; @@ -107,7 +93,6 @@ class SqlQueryHolder void SetResult(size_t index, QueryResult *result); bool Execute(Trinity::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue); }; - class SqlQueryHolderEx : public SqlOperation { private: |