[7193] Renamed output Field Flags to Unit Flags in npc info command.
[getmangos.git] / src / shared / Database / SQLStorageImpl.h
blobb820d68619b1e450b9d952d4bbab7706217a64c1
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "ProgressBar.h"
20 #include "Log.h"
21 #include "dbcfile.h"
23 template<class T>
24 template<class S, class D>
25 void SQLStorageLoaderBase<T>::convert(uint32 field_pos, S src, D &dst)
27 dst = D(src);
30 template<class T>
31 void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 field_pos, char *src, char *&dst)
33 if(!src)
35 dst = new char[1];
36 *dst = 0;
38 else
40 uint32 l = strlen(src) + 1;
41 dst = new char[l];
42 memcpy(dst, src, l);
46 template<class T>
47 template<class S>
48 void SQLStorageLoaderBase<T>::convert_to_str(uint32 field_pos, S src, char * & dst)
50 dst = new char[1];
51 *dst = 0;
54 template<class T>
55 template<class D>
56 void SQLStorageLoaderBase<T>::convert_from_str(uint32 field_pos, char * src, D& dst)
58 dst = 0;
61 template<class T>
62 template<class V>
63 void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset)
65 T * subclass = (static_cast<T*>(this));
66 switch(store.dst_format[x])
68 case FT_LOGIC:
69 subclass->convert(x, value, *((bool*)(&p[offset])) );
70 offset+=sizeof(bool);
71 break;
72 case FT_BYTE:
73 subclass->convert(x, value, *((char*)(&p[offset])) );
74 offset+=sizeof(char);
75 break;
76 case FT_INT:
77 subclass->convert(x, value, *((uint32*)(&p[offset])) );
78 offset+=sizeof(uint32);
79 break;
80 case FT_FLOAT:
81 subclass->convert(x, value, *((float*)(&p[offset])) );
82 offset+=sizeof(float);
83 break;
84 case FT_STRING:
85 subclass->convert_to_str(x, value, *((char**)(&p[offset])) );
86 offset+=sizeof(char*);
87 break;
91 template<class T>
92 void SQLStorageLoaderBase<T>::storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset)
94 T * subclass = (static_cast<T*>(this));
95 switch(store.dst_format[x])
97 case FT_LOGIC:
98 subclass->convert_from_str(x, value, *((bool*)(&p[offset])) );
99 offset+=sizeof(bool);
100 break;
101 case FT_BYTE:
102 subclass->convert_from_str(x, value, *((char*)(&p[offset])) );
103 offset+=sizeof(char);
104 break;
105 case FT_INT:
106 subclass->convert_from_str(x, value, *((uint32*)(&p[offset])) );
107 offset+=sizeof(uint32);
108 break;
109 case FT_FLOAT:
110 subclass->convert_from_str(x, value, *((float*)(&p[offset])) );
111 offset+=sizeof(float);
112 break;
113 case FT_STRING:
114 subclass->convert_str_to_str(x, value, *((char**)(&p[offset])) );
115 offset+=sizeof(char*);
116 break;
120 template<class T>
121 void SQLStorageLoaderBase<T>::Load(SQLStorage &store)
123 uint32 maxi;
124 Field *fields;
125 QueryResult *result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.entry_field, store.table);
126 if(!result)
128 sLog.outError("Error loading %s table (not exist?)\n", store.table);
129 exit(1); // Stop server at loading non exited table or not accessable table
132 maxi = (*result)[0].GetUInt32()+1;
133 delete result;
135 result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table);
136 if(result)
138 fields = result->Fetch();
139 store.RecordCount = fields[0].GetUInt32();
140 delete result;
142 else
143 store.RecordCount = 0;
145 result = WorldDatabase.PQuery("SELECT * FROM %s", store.table);
147 if(!result)
149 sLog.outError("%s table is empty!\n", store.table);
150 store.RecordCount = 0;
151 return;
154 uint32 recordsize = 0;
155 uint32 offset = 0;
157 if(store.iNumFields != result->GetFieldCount())
159 store.RecordCount = 0;
160 sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n", store.table, store.iNumFields);
161 delete result;
162 exit(1); // Stop server at loading broken or non-compatible table.
165 //get struct size
166 uint32 sc=0;
167 uint32 bo=0;
168 uint32 bb=0;
169 for(uint32 x=0; x< store.iNumFields; x++)
170 if(store.dst_format[x]==FT_STRING)
171 ++sc;
172 else if (store.dst_format[x]==FT_LOGIC)
173 ++bo;
174 else if (store.dst_format[x]==FT_BYTE)
175 ++bb;
176 recordsize=(store.iNumFields-sc-bo-bb)*4+sc*sizeof(char*)+bo*sizeof(bool)+bb*sizeof(char);
178 char** newIndex=new char*[maxi];
179 memset(newIndex,0,maxi*sizeof(char*));
181 char * _data= new char[store.RecordCount *recordsize];
182 uint32 count=0;
183 barGoLink bar( store.RecordCount );
186 fields = result->Fetch();
187 bar.step();
188 char *p=(char*)&_data[recordsize*count];
189 newIndex[fields[0].GetUInt32()]=p;
191 offset=0;
192 for(uint32 x = 0; x < store.iNumFields; x++)
193 switch(store.src_format[x])
195 case FT_LOGIC:
196 storeValue((bool)(fields[x].GetUInt32() > 0), store, p, x, offset); break;
197 case FT_BYTE:
198 storeValue((char)fields[x].GetUInt8(), store, p, x, offset); break;
199 case FT_INT:
200 storeValue((uint32)fields[x].GetUInt32(), store, p, x, offset); break;
201 case FT_FLOAT:
202 storeValue((float)fields[x].GetFloat(), store, p, x, offset); break;
203 case FT_STRING:
204 storeValue((char*)fields[x].GetString(), store, p, x, offset); break;
206 ++count;
207 }while( result->NextRow() );
209 delete result;
211 store.pIndex = newIndex;
212 store.MaxEntry = maxi;
213 store.data = _data;