Skip to content

Instantly share code, notes, and snippets.

@cyberium
Created September 21, 2012 17:24
Show Gist options
  • Save cyberium/3762757 to your computer and use it in GitHub Desktop.
Save cyberium/3762757 to your computer and use it in GitHub Desktop.
sql storage cleanup by Silverice
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 0dac303..680ccba 100755
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -440,7 +440,7 @@ void ObjectMgr::LoadPointOfInterestLocales()
sLog.outString(">> Loaded " SIZEFMTD " points_of_interest locale strings", mPointOfInterestLocaleMap.size());
}
-struct SQLCreatureLoader : public SQLStorageLoaderBase<SQLCreatureLoader>
+struct SQLCreatureLoader : public SQLStorageLoaderBase<SQLCreatureLoader, SQLStorage>
{
template<class D>
void convert_from_str(uint32 /*field_pos*/, char const* src, D& dst)
@@ -1769,7 +1769,7 @@ void ObjectMgr::LoadItemLocales()
sLog.outString(">> Loaded " SIZEFMTD " Item locale strings", mItemLocaleMap.size());
}
-struct SQLItemLoader : public SQLStorageLoaderBase<SQLItemLoader>
+struct SQLItemLoader : public SQLStorageLoaderBase<SQLItemLoader, SQLStorage>
{
template<class D>
void convert_from_str(uint32 /*field_pos*/, char const* src, D& dst)
@@ -4645,7 +4645,7 @@ void ObjectMgr::LoadInstanceEncounters()
sLog.outString(">> Loaded " SIZEFMTD " Instance Encounters", m_DungeonEncounters.size());
}
-struct SQLInstanceLoader : public SQLStorageLoaderBase<SQLInstanceLoader>
+struct SQLInstanceLoader : public SQLStorageLoaderBase<SQLInstanceLoader, SQLStorage>
{
template<class D>
void convert_from_str(uint32 /*field_pos*/, char const* src, D& dst)
@@ -4706,7 +4706,7 @@ void ObjectMgr::LoadInstanceTemplate()
sLog.outString();
}
-struct SQLWorldLoader : public SQLStorageLoaderBase<SQLWorldLoader>
+struct SQLWorldLoader : public SQLStorageLoaderBase<SQLWorldLoader, SQLStorage>
{
template<class D>
void convert_from_str(uint32 /*field_pos*/, char const* src, D& dst)
@@ -5927,7 +5927,7 @@ void ObjectMgr::LoadGameObjectLocales()
sLog.outString(">> Loaded " SIZEFMTD " gameobject locale strings", mGameObjectLocaleMap.size());
}
-struct SQLGameObjectLoader : public SQLStorageLoaderBase<SQLGameObjectLoader>
+struct SQLGameObjectLoader : public SQLStorageLoaderBase<SQLGameObjectLoader, SQLStorage>
{
template<class D>
void convert_from_str(uint32 /*field_pos*/, char const* src, D& dst)
@@ -6858,7 +6858,7 @@ void ObjectMgr::LoadNPCSpellClickSpells()
static char* SERVER_SIDE_SPELL = "MaNGOS server-side spell";
-struct SQLSpellLoader : public SQLStorageLoaderBase<SQLSpellLoader>
+struct SQLSpellLoader : public SQLStorageLoaderBase<SQLSpellLoader, SQLStorage>
{
template<class S, class D>
void default_fill(uint32 field_pos, S src, D& dst)
diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
index e8c899c..cd70795 100644
--- a/src/shared/Database/SQLStorage.cpp
+++ b/src/shared/Database/SQLStorage.cpp
@@ -18,98 +18,98 @@
#include "SQLStorage.h"
-void SQLStorage::EraseEntry(uint32 id)
+void deallocateRecords(char *& records, const char * format, uint32 numFields, uint32 recordCount, uint32 recordSize)
{
+ if (!records)
+ return;
+
uint32 offset = 0;
- for (uint32 x = 0; x < oNumFields; ++x)
+ for(uint32 x = 0; x < numFields; ++x)
{
- switch (dst_format[x])
+ switch(format[x])
{
- case FT_LOGIC:
- offset += sizeof(bool); break;
- case FT_BYTE:
- offset += sizeof(char); break;
- case FT_INT:
- offset += sizeof(uint32); break;
- case FT_FLOAT:
- offset += sizeof(float); break;
- case FT_STRING:
+ case FT_LOGIC:
+ offset += sizeof(bool); break;
+ case FT_BYTE:
+ offset += sizeof(char); break;
+ case FT_INT:
+ offset += sizeof(uint32); break;
+ case FT_FLOAT:
+ offset += sizeof(float); break;
+ case FT_STRING:
{
- if (pIndex[id])
- delete[] *(char**)((char*)(pIndex[id]) + offset);
+ for (uint32 recordItr = 0; recordItr < recordCount; ++recordItr)
+ delete [] (records + recordItr*recordSize + offset);
offset += sizeof(char*);
break;
}
- case FT_NA:
- offset += sizeof(uint32); break;
- case FT_NA_BYTE:
- offset += sizeof(char); break;
- case FT_NA_FLOAT:
- offset += sizeof(float); break;
- case FT_NA_POINTER:
- offset += sizeof(char*); break;
- case FT_IND:
- case FT_SORT:
- assert(false && "SQL storage not have sort field types");
- break;
- default:
- assert(false && "unknown format character");
- break;
+ case FT_NA:
+ case FT_NA_BYTE:
+ break;
+ case FT_IND:
+ case FT_SORT:
+ assert(false && "SQL storage not have sort field types");
+ break;
+ default:
+ assert(false && "unknown format character");
+ break;
}
}
-
- pIndex[id] = NULL;
+ delete [] records;
+ records = NULL;
}
-void SQLStorage::Free()
+void SQLStorage::EraseEntry(uint32 id)
{
- uint32 offset = 0;
- for (uint32 x = 0; x < oNumFields; ++x)
- {
- switch (dst_format[x])
- {
- case FT_LOGIC:
- offset += sizeof(bool); break;
- case FT_BYTE:
- offset += sizeof(char); break;
- case FT_INT:
- offset += sizeof(uint32); break;
- case FT_FLOAT:
- offset += sizeof(float); break;
- case FT_STRING:
- {
- for (uint32 y = 0; y < MaxEntry; ++y)
- if (pIndex[y])
- delete[] *(char**)((char*)(pIndex[y]) + offset);
-
- offset += sizeof(char*);
- break;
- }
- case FT_NA:
- offset += sizeof(uint32); break;
- case FT_NA_BYTE:
- offset += sizeof(char); break;
- case FT_NA_FLOAT:
- offset += sizeof(float); break;
- case FT_NA_POINTER:
- offset += sizeof(char*); break;
- case FT_IND:
- case FT_SORT:
- assert(false && "SQL storage not have sort field types");
- break;
- default:
- assert(false && "unknown format character");
- break;
- }
- }
+ m_Index[id] = NULL;
+}
- delete[] pIndex;
- delete[] data;
+void SQLStorage::Free ()
+{
+ deallocateRecords(m_data,m_dst_format,oNumFields,RecordCount,m_recordSize);
+ delete [] m_Index;
+ m_Index = NULL;
}
void SQLStorage::Load()
{
+ Free();
SQLStorageLoader loader;
loader.Load(*this);
}
+
+void SQLStorage::prepareToLoad(uint32 maxEntry, uint32 recordCount, uint32 recordSize)
+{
+ MaxEntry = maxEntry;
+ delete[] m_Index;
+ m_Index = new char*[maxEntry];
+ memset(m_Index, 0, maxEntry * sizeof(char*));
+
+ delete[] m_data;
+ m_data = new char[recordCount*recordSize];
+ memset(m_data, 0, recordCount*recordSize);
+ m_recordSize = recordSize;
+ RecordCount = 0;
+}
+
+char* SQLStorage::createRecord(uint32 recordId)
+{
+ m_Index[recordId] = &m_data[RecordCount * m_recordSize];
+ ++RecordCount;
+ return m_Index[recordId];
+}
+
+void SQLStorage::init(const char * _entry_field, const char * sqlname)
+{
+ m_entry_field = _entry_field;
+ m_tableName = sqlname;
+ m_data = NULL;
+ m_Index = NULL;
+ iNumFields = strlen(m_src_format);
+ oNumFields = strlen(m_dst_format);
+
+ MaxEntry = 0;
+ RecordCount = 0;
+ m_recordSize = 0;
+}
\ No newline at end of file
diff --git a/src/shared/Database/SQLStorage.h b/src/shared/Database/SQLStorage.h
index 2bc57bb..aa27fd4 100644
--- a/src/shared/Database/SQLStorage.h
+++ b/src/shared/Database/SQLStorage.h
@@ -22,23 +22,40 @@
#include "Common.h"
#include "Database/DatabaseEnv.h"
-class SQLStorage
+class SQLStorageBase
{
- template<class T>
- friend struct SQLStorageLoaderBase;
+public:
+ uint32 RecordCount;
+ uint32 MaxEntry;
+ uint32 FieldCount;
+ uint32 iNumFields;
+ uint32 oNumFields;
+ char const* GetTableName() const { return m_tableName; }
+ char const* EntryFieldName() const { return m_entry_field; }
+protected:
+ SQLStorageBase() : RecordCount(0), MaxEntry(0), FieldCount(0),
+ m_tableName(NULL), m_entry_field(NULL) {}
+ ~SQLStorageBase() {}
+protected:
+ const char *m_tableName;
+ const char *m_entry_field;
+};
+class SQLStorage :public SQLStorageBase
+{
+ template <class Derived, class T> friend class SQLStorageLoaderBase;
public:
SQLStorage(const char* fmt, const char* _entry_field, const char* sqlname)
{
- src_format = fmt;
- dst_format = fmt;
+ m_src_format = fmt;
+ m_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;
- dst_format = dst_fmt;
+ m_src_format = src_fmt;
+ m_dst_format = dst_fmt;
init(_entry_field, sqlname);
}
@@ -52,48 +69,31 @@ class SQLStorage
{
if (id >= MaxEntry)
return NULL;
- return reinterpret_cast<T const*>(pIndex[id]);
+ return reinterpret_cast<T const*>(m_Index[id]);
}
- uint32 RecordCount;
- uint32 MaxEntry;
- uint32 iNumFields;
- uint32 oNumFields;
-
- char const* GetTableName() const { return table; }
-
void Load();
void Free();
void EraseEntry(uint32 id);
private:
- void init(const char* _entry_field, const char* sqlname)
- {
- entry_field = _entry_field;
- table = sqlname;
- data = NULL;
- pIndex = NULL;
- iNumFields = strlen(src_format);
- oNumFields = strlen(dst_format);
- MaxEntry = 0;
- }
-
- char** pIndex;
-
- char* data;
- const char* src_format;
- const char* dst_format;
- const char* table;
- const char* entry_field;
- // bool HasString;
+ void init(const char * _entry_field, const char * sqlname);
+ void prepareToLoad(uint32 maxRecordId, uint32 recordCount, uint32 recordSize);
+ char* createRecord(uint32 recordId);
+ private:
+ char** m_Index;
+ char* m_data;
+ const char* m_src_format;
+ const char* m_dst_format;
+ uint32 m_recordSize;
};
-template <class T>
-struct SQLStorageLoaderBase
+template <class DerivedLoader, class T>
+class SQLStorageLoaderBase
{
public:
- void Load(SQLStorage& storage, bool error_at_empty = true);
+ void Load(T& storage, bool error_at_empty = true);
template<class S, class D>
void convert(uint32 field_pos, S src, D& dst);
@@ -113,14 +113,14 @@ struct SQLStorageLoaderBase
private:
template<class V>
- void storeValue(V value, SQLStorage& store, char* p, uint32 x, uint32& offset);
- void storeValue(char const* value, SQLStorage& store, char* p, uint32 x, uint32& offset);
+ void storeValue(V value, T &store, char* record, uint32 field_pos, uint32& offset);
+ void storeValue(char const* value, T &store, char* record, uint32 field_pos, uint32& offset);
// trap, no body
- void storeValue(char* value, SQLStorage& store, char* p, uint32 x, uint32& offset);
+ void storeValue(char* value, T &store, char* record, uint32 field_pos, uint32& offset);
};
-struct SQLStorageLoader : public SQLStorageLoaderBase<SQLStorageLoader>
+class SQLStorageLoader : public SQLStorageLoaderBase<SQLStorageLoader, SQLStorage>
{
};
diff --git a/src/shared/Database/SQLStorageImpl.h b/src/shared/Database/SQLStorageImpl.h
index 66bb816..7cb6e5f 100644
--- a/src/shared/Database/SQLStorageImpl.h
+++ b/src/shared/Database/SQLStorageImpl.h
@@ -23,15 +23,15 @@
#include "Log.h"
#include "DBCFileLoader.h"
-template<class T>
+template<class Derived, class T>
template<class S, class D>
-void SQLStorageLoaderBase<T>::convert(uint32 /*field_pos*/, S src, D& dst)
+void SQLStorageLoaderBase<Derived, 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 const* src, char*& dst)
+template<class Derived, class T>
+void SQLStorageLoaderBase<Derived, T>::convert_str_to_str(uint32 /*field_pos*/, char const* src, char*& dst)
{
if (!src)
{
@@ -46,41 +46,41 @@ void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 /*field_pos*/, char cons
}
}
-template<class T>
+template<class Derived, class T>
template<class S>
-void SQLStorageLoaderBase<T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, char*& dst)
+void SQLStorageLoaderBase<Derived, T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, char*& dst)
{
dst = new char[1];
*dst = 0;
}
-template<class T>
+template<class Derived, class T>
template<class D>
-void SQLStorageLoaderBase<T>::convert_from_str(uint32 /*field_pos*/, char const* /*src*/, D& dst)
+void SQLStorageLoaderBase<Derived, T>::convert_from_str(uint32 /*field_pos*/, char const* /*src*/, D& dst)
{
dst = 0;
}
-template<class T>
+template<class Derived, class T>
template<class S, class D>
-void SQLStorageLoaderBase<T>::default_fill(uint32 /*field_pos*/, S src, D& dst)
+void SQLStorageLoaderBase<Derived, T>::default_fill(uint32 /*field_pos*/, S src, D& dst)
{
dst = D(src);
}
-template<class T>
-void SQLStorageLoaderBase<T>::default_fill_to_str(uint32 /*field_pos*/, char const* /*src*/, char*& dst)
+template<class Derived, class T>
+void SQLStorageLoaderBase<Derived, T>::default_fill_to_str(uint32 /*field_pos*/, char const* /*src*/, char*& dst)
{
dst = new char[1];
*dst = 0;
}
-template<class T>
+template<class Derived, class T>
template<class V>
-void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage& store, char* p, uint32 x, uint32& offset)
+void SQLStorageLoaderBase<Derived, T>::storeValue(V value, T &store, char* p, uint32 x, uint32& offset)
{
- T* subclass = (static_cast<T*>(this));
- switch (store.dst_format[x])
+ Derived* subclass = (static_cast<Derived*>(this));
+ switch (store.m_dst_format[x])
{
case FT_LOGIC:
subclass->convert(x, value, *((bool*)(&p[offset])));
@@ -124,11 +124,11 @@ void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage& store, char* p, ui
}
}
-template<class T>
-void SQLStorageLoaderBase<T>::storeValue(char const* value, SQLStorage& store, char* p, uint32 x, uint32& offset)
+template<class Derived, class T>
+void SQLStorageLoaderBase<Derived, T>::storeValue(char const* value, T &store, char* p, uint32 x, uint32& offset)
{
- T* subclass = (static_cast<T*>(this));
- switch (store.dst_format[x])
+ Derived* subclass = (static_cast<Derived*>(this));
+ switch (store.m_dst_format[x])
{
case FT_LOGIC:
subclass->convert_from_str(x, value, *((bool*)(&p[offset])));
@@ -164,52 +164,50 @@ void SQLStorageLoaderBase<T>::storeValue(char const* value, SQLStorage& store, c
}
}
-template<class T>
-void SQLStorageLoaderBase<T>::Load(SQLStorage& store, bool error_at_empty /*= true*/)
+template<class Derived, class T>
+void SQLStorageLoaderBase<Derived, T>::Load(T &store, bool error_at_empty /*= true*/)
{
- uint32 maxi;
- Field* fields;
- QueryResult* result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.entry_field, store.table);
+ Field* fields = NULL;
+ QueryResult* result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.EntryFieldName(), store.GetTableName());
if (!result)
{
- sLog.outError("Error loading %s table (not exist?)\n", store.table);
+ sLog.outError("Error loading %s table (not exist?)\n", store.GetTableName());
Log::WaitBeforeContinueIfNeed();
exit(1); // Stop server at loading non exited table or not accessable table
}
- maxi = (*result)[0].GetUInt32() + 1;
+ uint32 maxRecordId = (*result)[0].GetUInt32()+1;
+ uint32 recordCount = 0;
+ uint32 recordsize = 0;
delete result;
- result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table);
+ result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.GetTableName());
if (result)
{
fields = result->Fetch();
- store.RecordCount = fields[0].GetUInt32();
+ recordCount = fields[0].GetUInt32();
delete result;
}
- else
- store.RecordCount = 0;
- result = WorldDatabase.PQuery("SELECT * FROM %s", store.table);
+ result = WorldDatabase.PQuery("SELECT * FROM %s", store.GetTableName());
if (!result)
{
if (error_at_empty)
- sLog.outError("%s table is empty!\n", store.table);
+ sLog.outError("%s table is empty!\n", store.GetTableName());
else
- sLog.outString("%s table is empty!\n", store.table);
+ sLog.outString("%s table is empty!\n", store.GetTableName());
- store.RecordCount = 0;
+ recordCount = 0;
return;
}
- uint32 recordsize = 0;
uint32 offset = 0;
if (store.iNumFields != result->GetFieldCount())
{
- store.RecordCount = 0;
- sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n", store.table, store.iNumFields);
+ recordCount = 0;
+ sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n", store.GetTableName(), store.iNumFields);
delete result;
Log::WaitBeforeContinueIfNeed();
exit(1); // Stop server at loading broken or non-compatible table.
@@ -218,7 +216,7 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage& store, bool error_at_empty /*= tr
// get struct size
for (uint32 x = 0; x < store.oNumFields; ++x)
{
- switch (store.dst_format[x])
+ switch (store.m_dst_format[x])
{
case FT_LOGIC:
recordsize += sizeof(bool); break;
@@ -248,49 +246,46 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage& store, bool error_at_empty /*= tr
}
}
- char** newIndex = new char*[maxi];
- memset(newIndex, 0, maxi * sizeof(char*));
+ store.prepareToLoad(maxRecordId, recordCount, recordsize);
- char* _data = new char[store.RecordCount * recordsize];
- uint32 count = 0;
- BarGoLink bar(store.RecordCount);
+ BarGoLink bar(recordCount);
do
{
fields = result->Fetch();
bar.step();
- char* p = (char*)&_data[recordsize * count];
- newIndex[fields[0].GetUInt32()] = p;
+ //char* p = (char*)&_data[recordsize * count];
+ char* record = store.createRecord(fields[0].GetUInt32());
offset = 0;
// dependend on dest-size
// iterate two indexes: x over dest, y over source, y++ IFF x1=x/X
for (uint32 x = 0, y = 0; x < store.oNumFields; ++x)
{
- switch (store.dst_format[x])
+ switch (store.m_dst_format[x])
{
// For default fill continue and do not increase y
- case FT_NA: storeValue((uint32)0, store, p, x, offset); continue;
- case FT_NA_BYTE: storeValue((char)0, store, p, x, offset); continue;
- case FT_NA_FLOAT: storeValue((float)0.0f, store, p, x, offset); continue;
- case FT_NA_POINTER: storeValue((char const*)NULL, store, p, x, offset); continue;
+ case FT_NA: storeValue((uint32)0, store, record, x, offset); continue;
+ case FT_NA_BYTE: storeValue((char)0, store, record, x, offset); continue;
+ case FT_NA_FLOAT: storeValue((float)0.0f, store, record, x, offset); continue;
+ case FT_NA_POINTER: storeValue((char const*)NULL, store, record, x, offset); continue;
}
// It is required that the input has at least as many columns set as the output requires
if (y >= store.iNumFields)
assert(false && "SQL storage has too few columns!");
- switch (store.src_format[y])
+ switch (store.m_src_format[y])
{
case FT_LOGIC:
- storeValue((bool)(fields[y].GetUInt32() > 0), store, p, x, offset); break;
+ storeValue((bool)(fields[y].GetUInt32() > 0), store, record, x, offset); break;
case FT_BYTE:
- storeValue((char)fields[y].GetUInt8(), store, p, x, offset); break;
+ storeValue((char)fields[y].GetUInt8(), store, record, x, offset); break;
case FT_INT:
- storeValue((uint32)fields[y].GetUInt32(), store, p, x, offset); break;
+ storeValue((uint32)fields[y].GetUInt32(), store, record, x, offset); break;
case FT_FLOAT:
- storeValue((float)fields[y].GetFloat(), store, p, x, offset); break;
+ storeValue((float)fields[y].GetFloat(), store, record, x, offset); break;
case FT_STRING:
- storeValue((char const*)fields[y].GetString(), store, p, x, offset); break;
+ storeValue((char const*)fields[y].GetString(), store, record, x, offset); break;
case FT_NA:
case FT_NA_BYTE:
case FT_NA_FLOAT:
@@ -305,15 +300,10 @@ void SQLStorageLoaderBase<T>::Load(SQLStorage& store, bool error_at_empty /*= tr
}
++y;
}
- ++count;
}
while (result->NextRow());
delete result;
-
- store.pIndex = newIndex;
- store.MaxEntry = maxi;
- store.data = _data;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment