OregonCore  revision fb2a440-git
Your Favourite TBC server
SQLStorageImpl.h
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Log.h"
19 #include "DBCFileLoader.h"
20 
21 template<class T>
22 template<class S, class D>
23 void SQLStorageLoaderBase<T>::convert(uint32 /*field_pos*/, S src, D& dst)
24 {
25  dst = D(src);
26 }
27 
28 template<class T>
29 void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 /*field_pos*/, char* src, char*& dst)
30 {
31  if (!src)
32  {
33  dst = new char[1];
34  *dst = 0;
35  }
36  else
37  {
38  uint32 l = strlen(src) + 1;
39  dst = new char[l];
40  memcpy(dst, src, l);
41  }
42 }
43 
44 template<class T>
45 template<class S>
46 void SQLStorageLoaderBase<T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, char*& dst)
47 {
48  dst = new char[1];
49  *dst = 0;
50 }
51 
52 template<class T>
53 template<class D>
54 void SQLStorageLoaderBase<T>::convert_from_str(uint32 /*field_pos*/, char* /*src*/, D& dst)
55 {
56  dst = 0;
57 }
58 
59 template<class T>
60 template<class V>
61 void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage& store, char* p, int x, uint32& offset)
62 {
63  T* subclass = (static_cast<T*>(this));
64  switch (store.dst_format[x])
65  {
66  case FT_LOGIC:
67  subclass->convert(x, value, *((bool*)(&p[offset])) );
68  offset += sizeof(bool);
69  break;
70  case FT_BYTE:
71  subclass->convert(x, value, *((char*)(&p[offset])) );
72  offset += sizeof(char);
73  break;
74  case FT_INT:
75  subclass->convert(x, value, *((uint32*)(&p[offset])) );
76  offset += sizeof(uint32);
77  break;
78  case FT_FLOAT:
79  subclass->convert(x, value, *((float*)(&p[offset])) );
80  offset += sizeof(float);
81  break;
82  case FT_STRING:
83  subclass->convert_to_str(x, value, *((char**)(&p[offset])) );
84  offset += sizeof(char*);
85  break;
86  }
87 }
88 
89 template<class T>
90 void SQLStorageLoaderBase<T>::storeValue(char* value, SQLStorage& store, char* p, int x, uint32& offset)
91 {
92  T* subclass = (static_cast<T*>(this));
93  switch (store.dst_format[x])
94  {
95  case FT_LOGIC:
96  subclass->convert_from_str(x, value, *((bool*)(&p[offset])) );
97  offset += sizeof(bool);
98  break;
99  case FT_BYTE:
100  subclass->convert_from_str(x, value, *((char*)(&p[offset])) );
101  offset += sizeof(char);
102  break;
103  case FT_INT:
104  subclass->convert_from_str(x, value, *((uint32*)(&p[offset])) );
105  offset += sizeof(uint32);
106  break;
107  case FT_FLOAT:
108  subclass->convert_from_str(x, value, *((float*)(&p[offset])) );
109  offset += sizeof(float);
110  break;
111  case FT_STRING:
112  subclass->convert_str_to_str(x, value, *((char**)(&p[offset])) );
113  offset += sizeof(char*);
114  break;
115  }
116 }
117 
118 template<class T>
120 {
121  uint32 maxi;
122  Field* fields;
123  QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.entry_field, store.table);
124  if (!result)
125  sLog.outFatal("Error loading %s table (not exist?)\n", store.table);
126 
127  maxi = (*result)[0].GetUInt32() + 1;
128 
129  result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table);
130  if (result)
131  {
132  fields = result->Fetch();
133  store.RecordCount = fields[0].GetUInt32();
134  }
135  else
136  store.RecordCount = 0;
137 
138  result = WorldDatabase.PQuery("SELECT * FROM %s", store.table);
139 
140  if (!result)
141  {
142  sLog.outError("%s table is empty!\n", store.table);
143  store.RecordCount = 0;
144  return;
145  }
146 
147  uint32 recordsize = 0;
148  uint32 offset = 0;
149 
150  if (store.iNumFields != result->GetFieldCount())
151  {
152  store.RecordCount = 0;
153  sLog.outFatal("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n", store.table, store.iNumFields);
154  }
155 
156  //get struct size
157  uint32 sc = 0;
158  uint32 bo = 0;
159  uint32 bb = 0;
160  for (uint32 x = 0; x < store.iNumFields; x++)
161  if (store.dst_format[x] == FT_STRING)
162  ++sc;
163  else if (store.dst_format[x] == FT_LOGIC)
164  ++bo;
165  else if (store.dst_format[x] == FT_BYTE)
166  ++bb;
167  recordsize = (store.iNumFields - sc - bo - bb) * 4 + sc * sizeof(char*) + bo * sizeof(bool) + bb * sizeof(char);
168 
169  char** newIndex = new char* [maxi];
170  memset(newIndex, 0, maxi * sizeof(char*));
171 
172  char* _data = new char[store.RecordCount * recordsize];
173  uint32 count = 0;
174  do
175  {
176  fields = result->Fetch();
177  char* p = (char*)&_data[recordsize * count];
178  newIndex[fields[0].GetUInt32()] = p;
179 
180  offset = 0;
181  for (uint32 x = 0; x < store.iNumFields; x++)
182  switch (store.src_format[x])
183  {
184  case FT_LOGIC:
185  storeValue((bool)(fields[x].GetUInt32() > 0), store, p, x, offset);
186  break;
187  case FT_BYTE:
188  storeValue((char)fields[x].GetUInt8(), store, p, x, offset);
189  break;
190  case FT_INT:
191  storeValue((uint32)fields[x].GetUInt32(), store, p, x, offset);
192  break;
193  case FT_FLOAT:
194  storeValue((float)fields[x].GetFloat(), store, p, x, offset);
195  break;
196  case FT_STRING:
197  storeValue((char*)fields[x].GetString(), store, p, x, offset);
198  break;
199  }
200  ++count;
201  }
202  while ( result->NextRow() );
203 
204  store.pIndex = newIndex;
205  store.MaxEntry = maxi;
206  store.data = _data;
207 }
208 
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
void storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset)
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
Definition: Field.h:24
void Load(SQLStorage &storage)
#define sLog
Log class singleton.
Definition: Log.h:187
const char * src_format
Definition: SQLStorage.h:82
uint32 RecordCount
Definition: SQLStorage.h:61
void convert_str_to_str(uint32 field_pos, char *src, char *&dst)
char * data
Definition: SQLStorage.h:81
uint32 iNumFields
Definition: SQLStorage.h:63
char ** pIndex
Definition: SQLStorage.h:79
void convert_from_str(uint32 field_pos, char *src, D &dst)
etc mysql my cnf *Then change max_allowed_packet to a bigger value
const char * entry_field
Definition: SQLStorage.h:85
const char * dst_format
Definition: SQLStorage.h:83
void convert_to_str(uint32 field_pos, S src, char *&dst)
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
void convert(uint32 field_pos, S src, D &dst)
uint32 MaxEntry
Definition: SQLStorage.h:62
ACE_UINT32 uint32
Definition: Define.h:71
const char * table
Definition: SQLStorage.h:84