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

Revision 260, 6.6 kB (checked in by yumileroy, 17 years ago)

*DB script table stucture change. Source Mangos. Also fix some bugs. Hopefully this rev will make program usable again.

Original author: megamage
Date: 2008-11-20 10:43:20-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.