EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
RowsetReader.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24 */
25 
26 #include "eve-common.h"
27 
28 #include "database/RowsetReader.h"
29 #include "database/RowsetToSQL.h"
30 #include "python/PyRep.h"
31 
32 /************************************************************************/
33 /* BaseRowsetReader */
34 /************************************************************************/
35 size_t BaseRowsetReader::FindColumn( const char* name )
36 {
37  const uint32 cc = columnCount();
38 
39  for( uint32 i = 0; i < cc; ++i )
40  {
41  if( 0 == strcmp( name, columnName( i ) ) )
42  return i;
43  }
44 
45  return cc;
46 }
47 
48 /************************************************************************/
49 /* BaseRowsetReader::iterator */
50 /************************************************************************/
52 : mRowIndex( -1 )
53 {
54 }
55 
56 std::string BaseRowsetReader::iterator::GetAsString( size_t index ) const
57 {
58  const PyRep::PyType t = GetType( index );
59 
60  switch( t )
61  {
62  case PyRep::PyTypeNone:
63  return "None";
64  case PyRep::PyTypeBool:
65  return std::to_string( GetBool( index ) ? 1 : 0 );
66  case PyRep::PyTypeInt:
67  return std::to_string( GetInt( index ) );
68  case PyRep::PyTypeLong:
69  return std::to_string( GetLong( index ) );
70  case PyRep::PyTypeFloat:
71  {
72  char buf[64];
73  snprintf( buf, 64, "%f", GetFloat( index ) );
74  return buf;
75  }
77  {
78  std::string str = GetString( index );
79  SearchReplace( str, "'", "\\'" );
80 
81  str.insert( str.begin(), '\'' );
82  str.insert( str.end(), '\'' );
83 
84  return str;
85  }
87  {
88  std::string str = GetWString( index );
89  SearchReplace( str, "'", "\\'" );
90 
91  str.insert( str.begin(), '\'' );
92  str.insert( str.end(), '\'' );
93 
94  return str;
95  }
96  default:
97  {
98  char buf[64];
99  snprintf( buf, 64, "'UNKNOWN TYPE %u'", t );
100  return buf;
101  }
102  }
103 }
104 
106 {
107  if( _baseReader()->rowCount() > _rowIndex() )
108  _SetRow( _rowIndex() + 1 );
109 
110  return *this;
111 }
112 
114 {
115  if( 0 < _rowIndex() )
116  _SetRow( _rowIndex() - 1 );
117 
118  return *this;
119 }
120 
122 {
123  if( _baseReader() != other._baseReader() )
124  return false;
125  else if( _rowIndex() != other._rowIndex() )
126  return false;
127  return true;
128 }
129 
130 /************************************************************************/
131 /* PyRowsetReader::iterator */
132 /************************************************************************/
133 bool PyRowsetReader::iterator::IsNone( size_t index ) const
134 {
135  if( NULL == GetRep( index ) )
136  return true;
137  return BaseRowsetReader::iterator::IsNone( index );
138 }
139 
140 bool PyRowsetReader::iterator::GetBool( size_t index ) const
141 {
142  return GetRep( index )->AsBool()->value();
143 }
144 
146 {
147  return GetRep( index )->AsInt()->value();
148 }
149 
151 {
152  return GetRep( index )->AsLong()->value();
153 }
154 
155 double PyRowsetReader::iterator::GetFloat( size_t index ) const
156 {
157  return GetRep( index )->AsFloat()->value();
158 }
159 
160 const char* PyRowsetReader::iterator::GetString( size_t index ) const
161 {
162  return GetRep( index )->AsString()->content().c_str();
163 }
164 
165 const char* PyRowsetReader::iterator::GetWString( size_t index ) const
166 {
167  return GetRep( index )->AsWString()->content().c_str();
168 }
169 
170 /************************************************************************/
171 /* RowsetReader */
172 /************************************************************************/
173 RowsetReader::RowsetReader( const util_Rowset& rowset )
174 : mSet( rowset )
175 {
176 }
177 
179 {
180 }
181 
182 /************************************************************************/
183 /* RowsetReader::iterator */
184 /************************************************************************/
186 : mParent( NULL ),
187  mRow( NULL )
188 {
189 }
190 
192 : mParent( parent ),
193  mRow( NULL )
194 {
195  _SetRow( rowIndex );
196 }
197 
198 void RowsetReader::iterator::_SetRow( size_t rowIndex )
199 {
200  if( _rowIndex() != rowIndex )
201  {
202  mRow = ( mParent->rowCount() > rowIndex
203  ? mParent->_GetRow( rowIndex )
204  : NULL );
205  }
206 
208 }
209 
210 /************************************************************************/
211 /* TuplesetReader */
212 /************************************************************************/
213 TuplesetReader::TuplesetReader( const util_Tupleset& tupleset )
214 : mSet( tupleset )
215 {
216 }
217 
218 /************************************************************************/
219 /* TuplesetReader::iterator */
220 /************************************************************************/
222 : mParent( NULL )
223 {
224 }
225 
227 : mParent( parent )
228 {
229  _SetRow( rowIndex );
230 }
231 
232 void TuplesetReader::iterator::_SetRow( size_t rowIndex )
233 {
234  if( _rowIndex() != rowIndex )
235  {
236  mRow = ( mParent->rowCount() > rowIndex
237  ? mParent->_GetRow( rowIndex )
238  : NULL );
239  }
240 
242 }
243 
244 /************************************************************************/
245 /* SetSQLDumper */
246 /************************************************************************/
247 SetSQLDumper::SetSQLDumper( const char* table, const char* keyField, FILE* out )
248 : mTable( table ),
249  mKeyField( keyField ),
250  mOut( out )
251 {
252 }
253 
255 {
256  //first we want to check to see if this could possibly even be a tupleset.
257  if( 2 == rep->size()
258  && rep->GetItem( 0 )->IsList()
259  && rep->GetItem( 1 )->IsList() )
260  {
261  const PyList* possible_header = rep->GetItem( 0 )->AsList();
262  const PyList* possible_items = rep->GetItem( 1 )->AsList();
263 
264  //check each element of the lists to make sure they line up.
265  bool valid = true;
266  PyList::const_iterator cur, end;
267 
268  cur = possible_header->begin();
269  end = possible_header->end();
270  for(; valid && cur != end; ++cur)
271  {
272  if( !(*cur)->IsString() )
273  valid = false;
274  }
275 
276  cur = possible_items->begin();
277  end = possible_items->end();
278  for(; valid && cur != end; ++cur)
279  {
280  if( !(*cur)->IsList() )
281  valid = false;
282 
283  //it would be possible I guess to check each element of each item to make sure
284  //it is a terminal type (non-container), but I dont care right now.
285  }
286 
287  if( valid )
288  {
289  //ok, it looks like a tupleset... nothing we can do now but interpret it as one...
290  util_Tupleset rowset;
291 
292  //must be duplicated in order to be decoded ...
293  PyTuple* dup = new PyTuple( *rep );
294  if( !rowset.Decode( &dup ) )
295  sLog.Error( "SetSQLDumper", "Unable to interpret tuple as a tupleset, it may not even be one." );
296  else
297  {
298  TuplesetReader reader( rowset );
299  if( ReaderToSQL<TuplesetReader>( mTable.c_str(), mKeyField.c_str(), mOut, reader ) )
300  return true;
301 
302  sLog.Error( "SetSQLDumper", "Failed to convert tupleset to SQL." );
303  }
304  }
305  }
306 
307  //fallback
308  return PyVisitor::VisitTuple( rep );
309 }
310 
312 {
313  if( rep->type()->content() == "util.Rowset" )
314  {
315  //we found a friend, decode it
316  util_Rowset rowset;
317 
318  //must be duplicated in order to be decoded ...
319  PyObject* dup = new PyObject( *rep );
320  if( !rowset.Decode( &dup ) )
321  sLog.Error( "SetSQLDumper", "Unable to load a rowset from the object body!" );
322  else
323  {
324  RowsetReader reader( rowset );
325  if( ReaderToSQL<RowsetReader>( mTable.c_str(), mKeyField.c_str(), mOut, reader ) )
326  return true;
327 
328  sLog.Error( "SetSQLDumper", "Failed to convert rowset to SQL." );
329  }
330  }
331 
332  //fallback
333  return PyVisitor::VisitObject( rep );
334 }
std::string GetAsString(size_t index) const
virtual size_t columnCount() const =0
virtual bool VisitTuple(const PyTuple *rep)
the nested types Visitor
Definition: PyVisitor.cpp:36
PyRep * GetItem(size_t index) const
Returns Python object.
Definition: PyRep.h:602
virtual const char * columnName(size_t index) const =0
virtual size_t rowCount() const =0
size_t size() const
Definition: PyRep.h:591
const iterator & operator++()
bool operator==(const iterator &oth) const
virtual BaseRowsetReader * _baseReader() const =0
const std::string mKeyField
Definition: RowsetReader.h:203
SetSQLDumper(const char *table, const char *keyField, FILE *out)
const_iterator begin() const
Definition: PyRep.h:660
storage_type::const_iterator const_iterator
Definition: PyRep.h:644
uint32 GetInt(size_t index) const
virtual void _SetRow(size_t rowIndex)
Definition: RowsetReader.h:79
void _SetRow(size_t rowIndex)
Python tuple.
Definition: PyRep.h:567
PyToken * GetType() const
Definition: PyRep.cpp:829
bool IsList() const
Definition: PyRep.h:109
const iterator & operator--()
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
TuplesetReader(const util_Tupleset &tupleset)
Python object.
Definition: PyRep.h:826
const util_Rowset & mSet
Definition: RowsetReader.h:141
#define snprintf
Definition: eve-compat.h:184
bool VisitObject(const PyObject *rep)
Object type visitor.
virtual size_t FindColumn(const char *name)
PyList * AsList()
Definition: PyRep.h:140
int64 GetLong(size_t index) const
bool GetBool(size_t index) const
virtual size_t _rowIndex() const
Definition: RowsetReader.h:76
bool IsNone(size_t index) const
void _SetRow(size_t rowIndex)
unsigned __int32 uint32
Definition: eve-compat.h:50
PyType
Python wire object types.
Definition: PyRep.h:72
PyString * type() const
Definition: PyRep.h:844
virtual bool VisitObject(const PyObject *rep)
Object type visitor.
Definition: PyVisitor.cpp:69
const char * GetString(size_t index) const
signed __int64 int64
Definition: eve-compat.h:51
const_iterator end() const
Definition: PyRep.h:661
const char * GetWString(size_t index) const
FILE *const mOut
Definition: RowsetReader.h:204
bool VisitTuple(const PyTuple *rep)
the nested types Visitor
double GetFloat(size_t index) const
const std::string & content() const
Get the PyString content.
Definition: PyRep.h:458
void SearchReplace(std::string &subject, const std::string &search, const std::string &replace)
Does search & replace on subject.
const std::string mTable
Definition: RowsetReader.h:202
virtual bool IsNone(size_t index) const
Definition: RowsetReader.h:53
Python list.
Definition: PyRep.h:639
RowsetReader(const util_Rowset &rowset)