root/trunk/src/shared/Database/SQLStorageImpl.h @ 263

Revision 263, 6.4 kB (checked in by yumileroy, 17 years ago)

Some missing changes. This should fix the bug that loading char causes crash.
Please do not commit to the other tip (I do not know how to delete it).

Original author: megamage
Date: 2008-11-20 17:40:13-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "ProgressBar.h"
20#include "Log.h"
21#include "dbcfile.h"
22
23template<class T>
24template<class S, class D>
25void SQLStorageLoaderBase<T>::convert(uint32 field_pos, S src, D &dst)
26{
27    dst = D(src);
28}
29
30template<class T>
31void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 field_pos, char *src, char *&dst)
32{
33    if(!src)
34    {
35        dst = new char[1];
36        *dst = 0;
37    }
38    else
39    {
40        uint32 l = strlen(src) + 1;
41        dst = new char[l];
42        memcpy(dst, src, l);
43    }
44}
45
46template<class T>
47template<class S>
48void SQLStorageLoaderBase<T>::convert_to_str(uint32 field_pos, S src, char * & dst)
49{
50    dst = new char[1];
51    *dst = 0;
52}
53
54template<class T>
55template<class D>
56void SQLStorageLoaderBase<T>::convert_from_str(uint32 field_pos, char * src, D& dst)
57{
58    dst = 0;
59}
60
61template<class T>
62template<class V>
63void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset)
64{
65    T * subclass = (static_cast<T*>(this));
66    switch(store.dst_format[x])
67    {
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;
88    }
89}
90
91template<class T>
92void SQLStorageLoaderBase<T>::storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset)
93{
94    T * subclass = (static_cast<T*>(this));
95    switch(store.dst_format[x])
96    {
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;
117    }
118}
119
120template<class T>
121void SQLStorageLoaderBase<T>::Load(SQLStorage &store)
122{
123    uint32 maxi;
124    Field *fields;
125    QueryResult *result  = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.entry_field, store.table);
126    if(!result)
127    {
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
130    }
131
132    maxi = (*result)[0].GetUInt32()+1;
133    delete result;
134
135    result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table);
136    if(result)
137    {
138        fields = result->Fetch();
139        store.RecordCount = fields[0].GetUInt32();
140        delete result;
141    }
142    else
143        store.RecordCount = 0;
144
145    result = WorldDatabase.PQuery("SELECT * FROM %s", store.table);
146
147    if(!result)
148    {
149        sLog.outError("%s table is empty!\n", store.table);
150        store.RecordCount = 0;
151        return;
152    }
153
154    uint32 recordsize = 0;
155    uint32 offset = 0;
156
157    if(store.iNumFields != result->GetFieldCount())
158    {
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.
163    }
164
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);
177
178    char** newIndex=new char*[maxi];
179    memset(newIndex,0,maxi*sizeof(char*));
180
181    char * _data= new char[store.RecordCount *recordsize];
182    uint32 count=0;
183    barGoLink bar( store.RecordCount );
184    do
185    {
186        fields = result->Fetch();
187        bar.step();
188        char *p=(char*)&_data[recordsize*count];
189        newIndex[fields[0].GetUInt32()]=p;
190
191        offset=0;
192        for(uint32 x = 0; x < store.iNumFields; x++)
193            switch(store.src_format[x])
194            {
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;
205            }
206        ++count;
207    }while( result->NextRow() );
208
209    delete result;
210
211    store.pIndex = newIndex;
212    store.MaxEntry = maxi;
213    store.data = _data;
214}
Note: See TracBrowser for help on using the browser.