2
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; version 2 of the
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., 51 Franklin St, Fifth Floor, Boston, MA
33
#include <boost/function.hpp>
34
#include <libxml/xmlmemory.h>
35
#include <boost/signals2.hpp>
43
# pragma warning (disable: 4275)
44
# pragma warning(disable:4251)
45
# ifdef MYSQLGRTLIBRARY_EXPORTS
46
# define MYSQLGRT_PUBLIC __declspec(dllexport)
48
# define MYSQLGRT_PUBLIC __declspec(dllimport)
54
#ifndef MYSQLGRT_PUBLIC
55
# define MYSQLGRT_PUBLIC
61
#define THROW(...) throw (__VA_ARGS__)
66
typedef stdext::hash_set<std::string> string_hash_set;
68
#include <ext/hash_set>
70
struct string_hash : public std::unary_function<std::string, size_t>
72
size_t operator() (const std::string &v) const
74
return __gnu_cxx::hash<const char*>()(v.c_str());
78
typedef __gnu_cxx::hash_set<std::string, string_hash> string_hash_set;
82
#define GRT_VERSION "4.1.0"
88
class MYSQLGRT_PUBLIC os_error : public std::runtime_error
91
os_error(const std::string &msg) : std::runtime_error(msg) {}
92
os_error(int err) : std::runtime_error(g_strerror(err)) {}
93
os_error(const std::string &msg, int err) : std::runtime_error(msg+": "+g_strerror(err)) {}
96
class MYSQLGRT_PUBLIC null_value : public std::logic_error
99
explicit null_value(const std::string &msg) : std::logic_error(msg) {}
100
explicit null_value() : std::logic_error("Attempt to operate on a NULL GRT value.") {}
103
class MYSQLGRT_PUBLIC read_only_item : public std::logic_error
106
explicit read_only_item(const std::string &value) : std::logic_error(value+" is read-only") {}
109
class MYSQLGRT_PUBLIC bad_item : public std::logic_error
112
// virtual ~bad_item() THROW() {};
114
bad_item(size_t index, size_t count) : std::logic_error("Index out of range.") {}
115
bad_item(const std::string &name) : std::logic_error("Invalid item name '" + name + "'.") {}
118
class MYSQLGRT_PUBLIC bad_class : public std::logic_error
121
bad_class(const std::string &name) : std::logic_error("Invalid class "+name) {}
124
class MYSQLGRT_PUBLIC grt_runtime_error : public std::runtime_error
130
grt_runtime_error(const grt_runtime_error &other) : std::runtime_error(other), detail(other.detail), fatal(other.fatal) {}
131
grt_runtime_error(const std::string &exc, const std::string &adetail, bool afatal= false) : std::runtime_error(exc), detail(adetail), fatal(afatal) {}
133
virtual ~grt_runtime_error() THROW() {}
136
class MYSQLGRT_PUBLIC module_error : public std::runtime_error
139
module_error(const std::string &exc) : std::runtime_error(exc) {}
142
class MYSQLGRT_PUBLIC user_cancelled : public std::runtime_error
145
user_cancelled(const std::string &exc) : std::runtime_error(exc) {}
149
//------------------------------------------------------------------------------------------------
150
//------------------------------------------------------------------------------------------------
153
* @htmlinclude GRT.html
158
#include "grtpp_value.h"
170
//------------------------------------------------------------------------------------------------
172
/** Base GRT value reference class.
173
* The Ref classes act as a smart pointer for GRT values. Because GRT
174
* values are allocated on the heap and are reference counted, the Ref
175
* classes will wrap around these values and perform automatic reference
176
* incrementing or decrementing when statically allocated. In most cases
177
* you must not directly reference or allocate a GRT value.
179
* They also have methods for accessing meta-information about the value
180
* like the type and implement some basic operators like assignment, ==,
183
* The comparison operators will work on the actual GRT value wrapped,
184
* even when you compare through the ValueRef type. In this case, if the
185
* types of the compared values do not match they will also compare the
186
* type of each value.
190
class MYSQLGRT_PUBLIC ValueRef
193
ValueRef() : _value(0) {}
195
explicit ValueRef(internal::Value *value)
202
ValueRef(const ValueRef &value)
203
: _value(value._value)
209
/*virtual*/ ~ValueRef()
222
inline bool is_valid() const { return _value != 0; }
223
inline bool is_same(const ValueRef &value) const { return valueptr() == value.valueptr(); }
225
inline Type type() const { return _value ? _value->get_type() : UnknownType; }
227
ValueRef &operator= (const ValueRef& other) { swap(other._value); return *this; }
229
// for non-simple types will only check if its the same object
230
inline bool operator == (const ValueRef &other) const
232
if (_value == other._value) return true;
233
if (!_value || !other._value) return false;
234
if (type() != other.type()) return false;
236
return _value->equals(other._value);
239
inline bool operator != (const ValueRef &other) const
241
return !(operator ==(other));
244
// for non-simple types will check order of the pointer of the object
245
// (ie gives an arbitrary order)
246
inline bool operator < (const ValueRef &other) const
248
if (!_value || !other._value) return _value < other._value;
249
if (type() != other.type())
250
return (type() < other.type());
252
return _value->less_than(other._value);
255
std::string repr() const { return _value ? _value->repr() : "NULL"; }
257
inline internal::Value *valueptr() const { return _value; }
259
int refcount() const { return _value->refcount(); }
260
void retain() { if (_value) _value->retain(); }
261
void release() { if (_value)_value->release(); }
264
internal::Value *_value;
266
void swap(internal::Value *nvalue)
268
if (nvalue != _value)
280
//----------------------------------------------------------------------
283
template<class C> class Ref;
285
typedef Ref<internal::Object> ObjectRef;
288
/** Holds a reference to a GRT object.
290
* Use it as Ref<db_Table> or db_TableRef, which is an alias created along
291
* auto-generated classes.
293
* To allocate a new object from C++ code:
295
* db_TableRef table(grt);
298
* To access members and methods:
303
* Reference counting is performed automatically.
307
template<class Class>
308
class Ref : public ValueRef
311
typedef Class RefType;
322
/** Constructor for creating and initializing a new object.
324
explicit Ref(GRT *grt)
325
: ValueRef(new Class(grt))
330
Ref(const Ref<Class> &ref)
334
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) // this causes errors in mac, with gcc 4.2
335
// just to give an error if Class is not an object
336
Class::static_class_name();
341
template<class Subclass>
342
Ref(const Ref<Subclass> &ref)
345
// poor mans compile-time type "check". compiler will throw an error if Subclass is not derived from Class
347
Class *dummy_variable_just_for_type_check __attribute__((unused))= static_cast<Subclass*>(ref.valueptr());
349
Class *dummy_variable_just_for_type_check= static_cast<Subclass*>(ref.valueptr());
352
_value= ref.valueptr();
356
static inline bool can_wrap(const ValueRef &value)
358
return (value.type() == ObjectType) && (!value.is_valid() || dynamic_cast<Class*>(value.valueptr()));
361
static inline Ref<Class> cast_from(const ValueRef &ov)
365
Class *obj= dynamic_cast<Class*>(ov.valueptr());
368
internal::Object* object= dynamic_cast<internal::Object*>(ov.valueptr());
370
throw grt::type_error(Class::static_class_name(), object->class_name());
372
throw grt::type_error(Class::static_class_name(), ov.type());
374
return Ref<Class>(obj);
379
const std::string &id() const { return content().id(); }
380
const std::string &class_name() const { return content().class_name(); }
381
MetaClass *get_metaclass() const { return content().get_metaclass(); }
383
bool is_instance(MetaClass *mc) const { return content().is_instance(mc); }
384
bool is_instance(const std::string &klass) const { return content().is_instance(klass); }
386
bool is_instance() const { return C::static_class_name().empty() ? true : content().is_instance(C::static_class_name()); }
388
Ref<Class> &operator= (const Ref<Class>& other) { Ref<Class> tmp(other); swap(tmp._value); return *this; }
390
bool operator == (const ValueRef& other) const { return _value == other.valueptr() || (_value && content().equals(other.valueptr())); }
391
bool operator != (const ValueRef& other) const { return !(operator == (other)); }
393
Class *operator->() const { return static_cast<Class*>(_value); }
395
ValueRef get_member(const std::string &m) const { return content().get_member(m); }
396
ValueRef get_member(const struct ClassMember *m) const;
397
void set_member(const std::string &m, const ValueRef &new_value) { content().set_member(m, new_value); }
399
std::string get_string_member(const std::string &member) const { return content().get_string_member(member); }
400
internal::Double::storage_type get_double_member(const std::string &member) const { return content().get_double_member(member); }
401
internal::Integer::storage_type get_integer_member(const std::string &member) const { return content().get_integer_member(member); }
402
bool has_member(const std::string &member) const { return content().has_member(member); }
404
bool has_method(const std::string &method) const { return content().has_method(method); }
405
// Class *operator*() const { return static_cast<Class*>(_value); }
407
GRT *get_grt() const { return content().get_grt(); }
410
Class &content() const { return *static_cast<Class*>(_value); }
413
//----------------------------------------------------------------------
416
template<class C> class WeakRef;
418
typedef WeakRef<internal::Object> WeakObjectRef;
420
/** Holds a weak reference to a GRT object.
422
* Use it as WeakRef<db_Table>
424
* Weak references will not increment the reference count of the referenced object,
425
* but will be able to tell whether it has been deleted. Use it to avoid circular
426
* loops and other situations where you don't want a real reference to an object.
430
template<class Class>
434
typedef Class RefType;
436
/// unitialized weak reference is invalid
437
WeakRef() : _content(0), _valid_flag(false) // unassigned means reference is undefined
442
WeakRef(const WeakRef<Class> ©)
443
: _content(copy._content), _valid_flag(copy._valid_flag)
447
// Create a weak-ref from a normal ref
448
WeakRef(const Ref<Class> &object_ref)
449
: _content(object_ref.is_valid() ? &object_ref.content() : 0),
450
_valid_flag(object_ref.is_valid() ? object_ref->weakref_valid_flag() : internal::ObjectValidFlag(false))
454
// gets a real usable reference to the object
455
Ref<Class> lock() const
457
if (!_valid_flag.valid())
458
throw std::logic_error("attempt to access invalid weak-reference");
459
return Ref<Class>(_content);
464
_content= 0; // pointer was nullified, it's a valid reference to null (ie not undefined)
465
_valid_flag= internal::ObjectValidFlag(true);
468
//! Returns true if the reference is still valid, false if the referenced object is gone
471
return _valid_flag.valid();
474
WeakRef<Class> &operator= (const WeakRef<Class>& other)
476
WeakRef<Class> tmp(other);
481
WeakRef<Class> &operator= (const Ref<Class>& other)
483
WeakRef<Class> tmp(other);
488
void swap(Ref<Class> &other)
490
std::swap(_content, other._content);
491
_valid_flag.swap(other._valid_flag);
494
bool operator == (const WeakRef<Class>& other) const
496
return lock() == other.lock();
499
bool operator != (const WeakRef<Class>& other) const
501
return lock() != other.lock();
505
/* Create a weak reference to a raw object pointer... is not safe, so we just disallow it */
506
explicit WeakRef(Class *instance)
507
: _content(instance), // if object is null, the reference is valid, just null
508
_valid_flag(instance ? instance->weakref_valid_flag() : internal::ObjectValidFlag(true))
514
internal::ObjectValidFlag _valid_flag;
517
//----------------------------------------------------------------------
520
typedef Ref<internal::Integer> IntegerRef;
522
/** Reference object class for integer GRT values.
526
* To create an integer value:
531
* An implicit constructor for long is available, so you can assign
532
* to a IntegerRef as:
534
* IntegerRef i= 1234;
540
class Ref<internal::Integer> : public ValueRef
543
typedef internal::Integer RefType;
544
typedef internal::Integer::storage_type storage_type;
546
static inline Ref<internal::Integer> cast_from(const ValueRef &svalue)
548
if (svalue.is_valid() && svalue.type() != IntegerType)
549
throw type_error(IntegerType, svalue.type());
550
return Ref<internal::Integer>(svalue);
553
static inline storage_type extract_from(const ValueRef &svalue)
555
if (!svalue.is_valid() || svalue.type() != IntegerType)
556
throw type_error(IntegerType, svalue.type());
557
return *static_cast<internal::Integer*>(svalue.valueptr());
560
static inline bool can_wrap(const ValueRef &value)
562
return (value.type() == internal::Integer::static_type());
567
Ref(const Ref &value)
571
explicit Ref(internal::Integer *ptr)
577
: ValueRef(internal::Integer::get(value))
582
: ValueRef(internal::Integer::get(value))
586
inline operator storage_type () const { return *content(); }
587
inline storage_type operator *() const { return *content(); }
589
Ref<internal::Integer> &operator= (const Ref<internal::Integer>& other) { swap(other._value); return *this; }
591
inline bool operator==(const IntegerRef &o) const
593
return _value == o._value || (_value && o._value && *content() == *o);
596
inline bool operator==(long v) const
598
return _value && (*content() == v);
601
inline bool operator==(int v) const
603
return _value && (*content() == v);
606
inline bool operator!=(const IntegerRef &o) const
608
return !(operator ==(o));
611
inline bool operator!=(long v) const
613
return _value && (*content() != v);
616
inline bool operator!=(int v) const
618
return _value && (*content() != v);
622
explicit Ref(const ValueRef &ivalue)
624
if (ivalue.is_valid() && ivalue.type() != internal::Integer::static_type())
625
throw type_error(internal::Integer::static_type(), ivalue.type());
626
_value= ivalue.valueptr();
631
internal::Integer& content() const { return *static_cast<internal::Integer*>(_value); }
635
//----------------------------------------------------------------------
638
typedef Ref<internal::Double> DoubleRef;
640
/** Reference object class for double GRT values.
644
* To create a double value:
649
* An implicit constructor for long is available, so you can assign
652
* DoubleRef i= 12.34;
658
class Ref<internal::Double> : public ValueRef
661
typedef internal::Double RefType;
662
typedef internal::Double::storage_type storage_type;
664
static inline Ref<internal::Double> cast_from(const ValueRef &svalue)
666
if (svalue.is_valid() && svalue.type() != DoubleType)
667
throw type_error(DoubleType, svalue.type());
668
return Ref<internal::Double>(svalue);
671
static inline storage_type extract_from(const ValueRef &svalue)
673
if (!svalue.is_valid() || svalue.type() != DoubleType)
674
throw type_error(DoubleType, svalue.type());
675
return *static_cast<internal::Double*>(svalue.valueptr());
678
static inline bool can_wrap(const ValueRef &value)
680
return (value.type() == internal::Double::static_type());
685
Ref(const Ref &value)
689
explicit Ref(internal::Double *ptr)
694
Ref(storage_type value)
695
: ValueRef(internal::Double::get(value))
699
inline operator storage_type () const { return *content(); }
700
inline storage_type operator *() const { return *content(); }
702
Ref<internal::Double> &operator= (const Ref<internal::Double>& other) { swap(other._value); return *this; }
704
inline bool operator==(const DoubleRef &o) const
706
return _value == o._value || (_value && o._value && (*content() == *o));
709
inline bool operator==(storage_type v) const
711
return _value && (*content() == v);
714
inline bool operator!=(storage_type v) const
716
return _value && (*content() != v);
719
inline bool operator!=(const DoubleRef &o) const
721
return !(operator == (o));
726
explicit Ref(const ValueRef &ivalue)
728
if (ivalue.is_valid() && ivalue.type() != internal::Double::static_type())
729
throw type_error(internal::Double::static_type(), ivalue.type());
730
_value= ivalue.valueptr();
735
internal::Double& content() const { return *static_cast<internal::Double*>(_value); }
739
//----------------------------------------------------------------------
742
typedef Ref<internal::String> StringRef;
744
/** Reference object class for string GRT values.
748
* To create a string value:
753
* An implicit constructor for string is available, so you can assign
756
* StringRef s= "foo";
762
class MYSQLGRT_PUBLIC Ref<internal::String> : public ValueRef
765
typedef internal::String RefType;
766
typedef internal::String::storage_type storage_type;
768
static inline Ref<internal::String> cast_from(const ValueRef &svalue)
770
if (svalue.is_valid() && svalue.type() != StringType)
771
throw type_error(StringType, svalue.type());
772
return Ref<internal::String>(svalue);
775
static inline std::string extract_from(const ValueRef &svalue)
777
if (!svalue.is_valid() || svalue.type() != StringType)
778
throw type_error(StringType, svalue.type());
779
return *static_cast<internal::String*>(svalue.valueptr());
782
static inline bool can_wrap(const ValueRef &value)
784
return (value.type() == internal::String::static_type());
787
static Ref format(const char *format, ...);
791
Ref(const Ref &value)
795
explicit Ref(internal::String *ptr)
800
Ref(const std::string &value)
801
: ValueRef(internal::String::get(value))
805
Ref(const char *value)
806
: ValueRef(internal::String::get(value))
810
inline operator storage_type () const { return *content(); }
811
inline storage_type operator *() const { return *content(); }
813
const char *c_str() const { return content().c_str(); }
814
bool empty() const { return content().empty(); }
816
Ref<internal::String> &operator= (const Ref<internal::String>& other) { swap(other._value); return *this; }
818
inline bool operator==(const StringRef &v) const
820
return _value == v._value || (_value && v._value && (*content() == *v));
823
inline bool operator==(const storage_type &v) const
825
return _value && (*content() == v);
828
inline bool operator==(const char *v) const
830
return _value && (strcmp(content().c_str(), v)==0);
833
inline bool operator!=(const StringRef &v) const
835
return !operator ==(v);
838
inline bool operator!=(const storage_type &v) const
840
return !operator ==(v);
843
inline bool operator!=(const char *v) const
845
return !operator ==(v);
850
explicit Ref(const ValueRef &ivalue)
852
if (ivalue.is_valid() && ivalue.type() != internal::String::static_type())
853
throw type_error(internal::String::static_type(), ivalue.type());
854
_value= ivalue.valueptr();
859
internal::String& content() const { return *static_cast<internal::String*>(_value); }
863
//----------------------------------------------------------------------
867
struct TypedListConstIterator
869
typedef std::random_access_iterator_tag iterator_category;
870
typedef C value_type;
871
typedef int difference_type;
873
typedef C& reference;
874
typedef internal::List::raw_const_iterator IterType;
878
TypedListConstIterator() : iter(0) {}
880
TypedListConstIterator(const TypedListConstIterator &content) : iter(content.iter) {}
882
TypedListConstIterator(const IterType &content)
886
inline bool operator < (const TypedListConstIterator &o) const
888
return iter < o.iter;
891
inline Ref<C> operator *() const
893
return Ref<C>((C*)iter->valueptr());
896
inline bool operator == (const TypedListConstIterator &o) const
898
return iter == o.iter;
901
inline bool operator != (const TypedListConstIterator &o) const
903
return iter != o.iter;
906
inline TypedListConstIterator& operator ++()
912
inline TypedListConstIterator operator ++(int)
914
TypedListConstIterator temp(*this);
921
struct TypedListConstReverseIterator
923
typedef std::random_access_iterator_tag iterator_category;
924
typedef C value_type;
925
typedef int difference_type;
927
typedef C& reference;
928
typedef internal::List::raw_const_reverse_iterator IterType;
932
TypedListConstReverseIterator() {}
934
TypedListConstReverseIterator(const TypedListConstReverseIterator &content) : iter(content.iter) {}
936
TypedListConstReverseIterator(const IterType &content)
940
inline bool operator < (const TypedListConstReverseIterator &o) const
942
return iter < o.iter;
945
inline Ref<C> operator *() const
947
return Ref<C>((C*)iter->valueptr());
950
inline bool operator == (const TypedListConstReverseIterator &o) const
952
return iter == o.iter;
955
inline bool operator != (const TypedListConstReverseIterator &o) const
957
return iter != o.iter;
960
inline TypedListConstReverseIterator& operator ++()
966
inline TypedListConstReverseIterator operator ++(int)
968
TypedListConstReverseIterator temp(*this);
976
/** Base GRT list reference class.
980
class MYSQLGRT_PUBLIC BaseListRef : public ValueRef
983
typedef internal::List RefType;
984
typedef internal::List::raw_const_iterator raw_const_iterator;
985
typedef internal::List::raw_const_reverse_iterator raw_const_reverse_iterator;
988
npos= internal::List::npos
993
BaseListRef(const BaseListRef &list)
998
BaseListRef(internal::List *list)
1003
BaseListRef(GRT *grt, bool allow_null= true)
1004
: ValueRef(new internal::List(grt, allow_null))
1008
BaseListRef(GRT *grt, Type type, const std::string &class_name= "", internal::Object *owner= 0, bool allow_null= true)
1009
: ValueRef(owner ? new internal::OwnedList(grt, type, class_name, owner, allow_null) : new internal::List(grt, type, class_name, allow_null))
1013
inline Type content_type() const { return content().content_type(); };
1014
inline std::string content_class_name() const { return content().content_class_name(); }
1016
static bool can_wrap(const ValueRef &value)
1018
return value.type() == ListType;
1021
static BaseListRef cast_from(const ValueRef &value)
1023
return BaseListRef(value);
1026
inline void remove(size_t index)
1028
content().remove(index);
1031
inline void remove_all()
1033
while (content().count() > 0)
1034
content().remove(0);
1037
inline size_t count() const
1039
return is_valid() ? content().count() : 0;
1042
inline const ValueRef &operator[](size_t index) const
1044
return content().get(index);
1047
inline const ValueRef &get(size_t index) const
1049
return content().get(index);
1052
inline raw_const_iterator begin() const
1054
return content().raw_begin();
1057
inline raw_const_iterator end() const
1059
return content().raw_end();
1062
inline raw_const_reverse_iterator rbegin() const
1064
return content().raw_rbegin();
1067
inline raw_const_reverse_iterator rend() const
1069
return content().raw_rend();
1072
template<typename TPred>
1073
bool foreach(TPred pred) const
1075
for (internal::List::raw_const_iterator end= content().raw_end(), iter= content().raw_begin();
1076
iter != end; ++iter)
1084
inline size_t get_index(const ValueRef &value) const
1086
return content().get_index(value);
1089
inline void reorder(size_t oindex, size_t nindex)
1091
content().reorder(oindex, nindex);
1094
// methods beginning with g perform type checking at runtime
1095
inline void gset(size_t index, const ValueRef &value)
1097
content().set_checked(index, value);
1100
inline void ginsert(const ValueRef &value, size_t index= npos)
1102
content().insert_checked(value, index);
1105
inline void gremove_value(const ValueRef &value)
1107
content().remove(value);
1111
inline void gset_unchecked(size_t index, const ValueRef &value)
1113
content().set_unchecked(index, value);
1116
inline void ginsert_unchecked(const ValueRef &value, size_t index= npos)
1118
content().insert_unchecked(value, index);
1121
GRT *get_grt() const { return content().get_grt(); }
1124
inline internal::List &content() const { return *static_cast<internal::List*>(_value); }
1126
// For consistency with other Ref<> templates use -> operator as shortcut for content().
1127
inline internal::List *operator->() const { return static_cast<internal::List*>(_value); }
1129
explicit BaseListRef(const ValueRef &lvalue)
1131
if (lvalue.is_valid() && lvalue.type() != ListType)
1132
throw type_error(ListType, lvalue.type());
1134
_value= lvalue.valueptr();
1141
//----------------------------------------------------------------------
1145
/** GRT object list reference class.
1150
class ListRef : public BaseListRef
1153
typedef TypedListConstIterator<O> const_iterator;
1154
typedef TypedListConstReverseIterator<O> const_reverse_iterator;
1155
typedef Ref<O> value_type;
1160
ListRef(GRT *grt, bool allow_null= true)
1161
: BaseListRef(grt, ObjectType, O::static_class_name(), 0, allow_null)
1165
ListRef(GRT *grt, internal::Object *owner, bool allow_null= true)
1166
: BaseListRef(grt, ObjectType, O::static_class_name(), owner, allow_null)
1170
template<class Subclass>
1171
ListRef(const ListRef<Subclass> &other)
1172
: BaseListRef(other)
1176
O *tmp __attribute__((unused))= x;// hack so that we get a compile error if Subclass is not a subclass of O
1178
O *tmp= x;// hack so that we get a compile error if Subclass is not a subclass of O
1182
static ListRef<O> cast_from(const ValueRef &value)
1185
if (!value.is_valid() || can_wrap(value))
1186
return ListRef<O>(value);
1189
expected.base.type= ListType;
1190
expected.content.type= ObjectType;
1191
expected.content.object_class= O::static_class_name();
1193
if (value.type() == ListType)
1196
actual.base.type= ListType;
1197
actual.content= BaseListRef::cast_from(value)->content_type_spec();
1198
throw type_error(expected, actual);
1201
throw type_error(ListType, value.type());
1204
static bool can_wrap(const ValueRef &value);
1206
inline void insert(const Ref<O> &value, size_t index= npos)
1208
content().insert_unchecked(value, index);
1211
inline void remove_value(const Ref<O> &value)
1213
content().remove(value);
1216
// Return const Ref<> so that list[i]= newvalue; won't be attempted (that wouldnt work as expected)
1217
inline const Ref<O> operator[](size_t index) const
1222
inline Ref<O> get(size_t index) const
1224
return Ref<O>::cast_from(content().get(index));
1227
inline void set(size_t index, const Ref<O> &value)
1229
content().set_unchecked(index, value);
1232
inline const_iterator begin() const
1234
return const_iterator(content().raw_begin());
1237
inline const_iterator end() const
1239
return const_iterator(content().raw_end());
1242
inline const_reverse_iterator rbegin() const
1244
return const_reverse_iterator(content().raw_rbegin());
1247
inline const_reverse_iterator rend() const
1249
return const_reverse_iterator(content().raw_rend());
1252
template<typename TPred>
1253
bool foreach(TPred pred) const
1255
for (internal::List::raw_const_iterator end= content().raw_end(), iter= content().raw_begin();
1256
iter != end; ++iter)
1258
Ref<O> tmp((O*)iter->valueptr());
1266
explicit ListRef(const ValueRef &lvalue)
1267
: BaseListRef(lvalue)
1269
if (lvalue.is_valid() && content().content_type() != O::static_type())
1270
throw type_error(O::static_type(), content().content_type(), ListType);
1274
typedef ListRef<internal::Object> ObjectListRef;
1276
//----------------------------------------------------------------------
1279
typedef ListRef<internal::Integer> IntegerListRef;
1281
/** GRT integer list reference class.
1283
* aka IntegerListRef
1288
class MYSQLGRT_PUBLIC ListRef<internal::Integer> : public BaseListRef
1295
ListRef(GRT *grt, internal::Object *owner= 0, bool allow_null= true)
1296
: BaseListRef(grt, IntegerType, "", owner, allow_null)
1300
static inline bool can_wrap(const ValueRef &value)
1302
if (value.type() != ListType)
1304
if (static_cast<internal::List*>(value.valueptr())->content_type() != IntegerType)
1309
static ListRef<internal::Integer> cast_from(const ValueRef &value)
1311
return ListRef<internal::Integer>(value);
1314
inline void insert(const IntegerRef &value, size_t index= npos)
1316
content().insert_unchecked(value, index);
1319
inline IntegerRef operator[](size_t index) const
1324
inline IntegerRef get(size_t index) const
1326
return IntegerRef::cast_from(content().get(index));
1329
inline void set(size_t index, const IntegerRef &value)
1331
content().set_unchecked(index, value);
1334
template<typename TPred>
1335
bool foreach(TPred pred) const
1337
for (internal::List::raw_const_iterator end= content().raw_end(), iter= content().raw_begin();
1338
iter != end; ++iter)
1340
if (!pred(*(internal::Integer*)iter->valueptr()))
1346
inline void remove_value(const IntegerRef &value)
1348
content().remove(value);
1352
explicit ListRef<internal::Integer>(const ValueRef &lvalue)
1353
: BaseListRef(lvalue)
1355
if (lvalue.is_valid() && content().content_type() != IntegerType)
1356
throw type_error(IntegerType, content().content_type(), ListType);
1361
//----------------------------------------------------------------------
1364
typedef ListRef<internal::Double> DoubleListRef;
1366
/** GRT double number list reference class.
1373
class MYSQLGRT_PUBLIC ListRef<internal::Double> : public BaseListRef
1380
ListRef(GRT *grt, internal::Object *owner= 0, bool allow_null= true)
1381
: BaseListRef(grt, DoubleType, "", owner, allow_null)
1385
static inline bool can_wrap(const ValueRef &value)
1387
if (value.type() != ListType)
1389
if (static_cast<internal::List*>(value.valueptr())->content_type() != DoubleType)
1394
static ListRef<internal::Double> cast_from(const ValueRef &value)
1396
return ListRef<internal::Double>(value);
1399
inline void insert(const DoubleRef &value, size_t index= npos)
1401
content().insert_unchecked(value, index);
1404
inline DoubleRef operator[](size_t index) const
1409
inline DoubleRef get(size_t index) const
1411
return DoubleRef::cast_from(content().get(index));
1414
inline void set(size_t index, const DoubleRef &value)
1416
content().set_unchecked(index, value);
1419
template<typename TPred>
1420
bool foreach(TPred pred) const
1422
for (internal::List::raw_const_iterator end= content().raw_end(), iter= content().raw_begin();
1423
iter != end; ++iter)
1425
if (!pred(*(internal::Double*)iter->valueptr()))
1431
inline void remove_value(const DoubleRef &value)
1433
content().remove(value);
1437
explicit ListRef(const ValueRef &lvalue)
1438
: BaseListRef(lvalue)
1440
if (lvalue.is_valid() && content().content_type() != DoubleType)
1441
throw type_error(DoubleType, content().content_type(), ListType);
1446
//----------------------------------------------------------------------
1447
// ListRef<internal::String>
1449
typedef ListRef<internal::String> StringListRef;
1451
/** GRT string list reference class.
1458
class MYSQLGRT_PUBLIC ListRef<internal::String> : public BaseListRef
1461
typedef TypedListConstIterator<internal::String> const_iterator;
1462
typedef TypedListConstReverseIterator<internal::String> const_reverse_iterator;
1468
ListRef(GRT *grt, internal::Object *owner= 0, bool allow_null= true)
1469
: BaseListRef(grt, StringType, "", owner, allow_null)
1473
static inline bool can_wrap(const ValueRef &value)
1475
if (value.type() != ListType)
1477
if (static_cast<internal::List*>(value.valueptr())->content_type() != StringType)
1482
static ListRef<internal::String> cast_from(const ValueRef &value) THROW(type_error)
1484
return ListRef<internal::String>(value);
1487
inline void insert(const StringRef &value, size_t index= npos)
1489
content().insert_unchecked(value, index);
1493
inline Reference operator[](size_t index) THROW (bad_item)
1498
inline StringRef operator[](size_t index) const
1503
inline StringRef get(size_t index) const THROW (bad_item)
1505
return StringRef::cast_from(content().get(index));
1508
inline void set(size_t index, const StringRef &value) THROW (bad_item, std::invalid_argument)
1510
content().set_unchecked(index, value);
1513
inline const_iterator begin() const
1515
return const_iterator(content().raw_begin());
1518
inline const_iterator end() const
1520
return const_iterator(content().raw_end());
1523
inline const_reverse_iterator rbegin() const
1525
return const_reverse_iterator(content().raw_rbegin());
1528
inline const_reverse_iterator rend() const
1530
return const_reverse_iterator(content().raw_rend());
1533
template<typename TPred>
1534
bool foreach(TPred pred) const
1536
for (internal::List::raw_const_iterator end= content().raw_end(), iter= content().raw_begin();
1537
iter != end; ++iter)
1539
if (!pred(*(internal::String*)iter->valueptr()))
1545
inline void remove_value(const StringRef &value)
1547
content().remove(value);
1550
inline size_t get_index(const std::string &str)
1552
return BaseListRef::get_index(StringRef(str));
1556
explicit ListRef(const ValueRef &lvalue)
1557
: BaseListRef(lvalue)
1559
if (lvalue.is_valid() && content().content_type() != StringType)
1560
throw type_error(StringType, content().content_type(), ListType);
1565
//----------------------------------------------------------------------
1568
/** GRT dictionary reference class.
1572
class MYSQLGRT_PUBLIC DictRef : public ValueRef
1575
typedef internal::Dict RefType;
1577
typedef internal::Dict::const_iterator const_iterator;
1582
DictRef(GRT *grt, bool allow_null= true)
1583
: ValueRef(new internal::Dict(grt, allow_null))
1587
DictRef(GRT *grt, Type type, const std::string &cclass="", bool allow_null= true)
1588
: ValueRef(new internal::Dict(grt, type, cclass, allow_null))
1592
DictRef(internal::Dict *dict)
1597
DictRef(GRT *grt, internal::Object *owner, bool allow_null= true)
1598
: ValueRef(new internal::OwnedDict(grt, AnyType, "", owner, allow_null))
1602
DictRef(GRT *grt, Type type, const std::string &cclass, internal::Object *owner, bool allow_null= true)
1603
: ValueRef(new internal::OwnedDict(grt, type, cclass, owner, allow_null))
1607
static DictRef cast_from(const ValueRef& ivalue)
1609
if (ivalue.is_valid() && ivalue.type() != DictType)
1610
throw type_error(DictType, ivalue.type());
1611
return DictRef(ivalue);
1614
inline Type content_type() const { return content().content_type(); };
1615
inline std::string content_class_name() const { return content().content_class_name(); }
1617
const_iterator begin() const { return content().begin(); }
1618
const_iterator end() const { return content().end(); }
1620
template<typename TPred>
1621
bool foreach(TPred pred) const
1623
for (const_iterator end= content().end(), iter= content().begin();
1624
iter != end; ++iter)
1626
if (!pred(iter->first, iter->second))
1632
inline bool has_key(const std::string &k) const
1634
return content().has_key(k);
1637
inline ValueRef operator[](const std::string &k) const
1642
inline DictRef& operator = (const DictRef &o) { DictRef tmp(o); swap(o.valueptr()); return *this; }
1645
inline Reference operator[](const std::string &k)
1649
return Reference(this, k);
1652
inline size_t count() const { return content().count(); }
1654
inline void remove(const std::string &k)
1656
content().remove(k);
1659
void reset_entries()
1661
content().reset_entries();
1664
inline ValueRef get(const std::string &k) const
1666
return ValueRef(content().get(k));
1669
inline ValueRef get(const std::string &k, const ValueRef &defvalue) const
1671
// No need to check here if the key exists.
1672
// If it does not then an invalid ValueRef will be returned.
1673
ValueRef tmp= content().get(k);
1674
if (!tmp.is_valid())
1679
std::string get_string(const std::string &k, const std::string &defvalue="") const
1681
ValueRef value= get(k);
1682
if (value.is_valid())
1683
return StringRef::extract_from(value);
1687
internal::Integer::storage_type get_int(const std::string &k, internal::Integer::storage_type defvalue=0) const
1689
ValueRef value= get(k);
1690
if (value.is_valid())
1691
return IntegerRef::extract_from(value);
1695
internal::Double::storage_type get_double(const std::string &k, internal::Double::storage_type defvalue=0.0) const
1697
ValueRef value= get(k);
1698
if (value.is_valid())
1699
return DoubleRef::extract_from(value);
1703
inline void set(const std::string &k, const ValueRef &value)
1705
content().set(k, value);
1708
inline void gset(const std::string &k, const std::string &value)
1710
content().set(k, StringRef(value));
1713
inline void gset(const std::string &k, long value)
1715
content().set(k, IntegerRef(value));
1718
inline void gset(const std::string &k, int value)
1720
content().set(k, IntegerRef(value));
1723
inline void gset(const std::string &k, internal::Double::storage_type value)
1725
content().set(k, DoubleRef(value));
1728
inline GRT *get_grt() const
1730
return content().get_grt();
1733
inline internal::Dict &content() const { return *static_cast<internal::Dict*>(_value); }
1736
explicit DictRef(const ValueRef &dvalue)
1739
if (dvalue.is_valid() && dvalue.type() != DictType)
1740
throw type_error(DictType, dvalue.type());
1744
//--------------------------------------------------------------------------------------------------
1746
typedef ListRef<internal::Dict> DictListRef;
1748
/** GRT Dict list reference class.
1755
class MYSQLGRT_PUBLIC ListRef<internal::Dict> : public BaseListRef
1762
ListRef(GRT *grt, internal::Object *owner= 0, bool allow_null= true)
1763
: BaseListRef(grt, DictType, "", owner, allow_null)
1767
static inline bool can_wrap(const ValueRef &value)
1769
if (value.type() != ListType)
1771
if (static_cast<internal::List*>(value.valueptr())->content_type() != DictType)
1776
static ListRef<internal::Dict> cast_from(const ValueRef &value)
1778
return ListRef<internal::Dict>(value);
1781
inline void insert(const DictRef &value, size_t index= npos)
1783
content().insert_unchecked(value, index);
1786
inline DictRef operator[](size_t index) const
1791
inline DictRef get(size_t index) const
1793
return DictRef::cast_from(content().get(index));
1796
inline void set(size_t index, const DictRef &value)
1798
content().set_unchecked(index, value);
1801
template<typename TPred>
1802
bool foreach(TPred pred) const
1804
for (internal::List::raw_const_iterator end= content().raw_end(), iter= content().raw_begin();
1805
iter != end; ++iter)
1807
if (!pred(*(internal::Dict*)iter->valueptr()))
1813
inline void remove_value(const DictRef &value)
1815
content().remove(value);
1819
explicit ListRef<internal::Dict>(const ValueRef &lvalue)
1820
: BaseListRef(lvalue)
1822
if (lvalue.is_valid() && content().content_type() != DictType)
1823
throw type_error(DictType, content().content_type(), ListType);
1828
//--------------------------------------------------------------------------------------------------
1830
struct MYSQLGRT_PUBLIC ArgSpec
1836
typedef std::vector<ArgSpec> ArgSpecList;
1842
virtual bool has_setter() const= 0;
1844
virtual void set(internal::Object *obj, const grt::ValueRef &value)= 0;
1845
virtual grt::ValueRef get(const internal::Object *obj) const= 0;
1849
/** Describes a GRT object member variable.
1850
* Contains information about a member variable for a GRT metaclass.
1851
* The meta-information in this is read from the struct*.xml files but
1852
* the property pointer is set at runtime when each class registers itself
1855
struct MYSQLGRT_PUBLIC ClassMember
1859
std::string default_value;
1860
bool read_only; //!< member not directly settable (setter still needed for unserializing)
1861
bool delegate_get; //!< getter is user implemented
1862
bool delegate_set; //!< setter is user implemented
1863
bool private_; //!< member has no getter/setter and is not stored
1864
bool calculated; //!< whether a instance var should be created for this value
1865
bool owned_object; //!< ref object is owned by this one (owned)
1866
bool overrides; //!< member overrides another one
1867
bool null_content_allowed; //!< whether inserting NULL values to a list or dict is allowed (allow-null)
1869
//! set by class when registering
1870
PropertyBase *property;
1874
/** Describes a GRT object method.
1875
* Contains information about a method for a GRT metaclass.
1876
* The meta-information in this is read from the struct*.xml files but
1877
* the method pointer is set at runtime when each class registers itself
1880
struct MYSQLGRT_PUBLIC ClassMethod
1882
typedef ValueRef (*Function)(internal::Object *self, const BaseListRef &args);
1885
// for stuff to be re-routed to methods
1886
std::string module_name;
1887
std::string module_function;
1890
ArgSpecList arg_types;
1901
typedef boost::function<void (const ObjectRef&, const std::string&, const int)> MessageSlot;
1903
typedef std::string Tag;
1905
virtual ~Validator() {};
1906
virtual int validate(const Tag& what, const ObjectRef& obj) = 0;
1909
/** GRT Class descriptor, formerly known as "struct".
1910
* Contains information about member variables and methods of a GRT class/object.
1911
* The class descriptions are loaded from XML files, which contain
1912
* the list of members and methods with information about types and
1913
* other metadata. This information is used for generating C++ classes
1914
* that actually implement these classes and also for exposing the
1915
* interface to these classes to the scripting interface (such as Lua).
1919
class MYSQLGRT_PUBLIC MetaClass//
1922
template<class C,class T>
1923
class Property : public PropertyBase
1926
void (C::*setter)(const T &value);
1927
T (C::*getter)() const;
1930
Property(T (C::*agetter)() const, void (C::*asetter)(const T &value)= 0)
1931
: setter(asetter), getter(agetter) {}
1933
virtual ~Property() {}
1935
virtual bool has_setter() const
1940
virtual void set(internal::Object *obj, const grt::ValueRef &value)
1942
(((C*)obj)->*setter)(T::cast_from(value));
1945
virtual grt::ValueRef get(const internal::Object *obj) const
1947
return (((C*)obj)->*getter)();
1951
typedef ObjectRef (*Allocator)(GRT *grt);
1953
typedef ClassMember Member;
1954
typedef ClassMethod Method;
1969
std::string object_class;
1972
/** Describes a signal from a GRT object.
1975
struct MYSQLGRT_PUBLIC Signal
1979
std::vector<SignalArg> arg_types;
1983
typedef std::map<std::string,Member> MemberList;
1984
typedef std::map<std::string,Method> MethodList;
1985
typedef std::list<Signal> SignalList;
1986
typedef std::vector<Validator*> ValidatorList;
1989
const std::string &name() const { return _name; }
1990
GRT *get_grt() const { return _grt; }
1991
MetaClass *parent() const { return _parent; }
1993
unsigned int crc32() const { return _crc32; }
1995
/** Calls slot iterating through all members of the metaclass.
1997
* The slot will be called for each member of the metaclass,
1998
* including inherited ones. If a member is overriden,
1999
* it will be called only once, for the "topmost" one.
2000
* The slot must return true as long as the iteration is
2001
* to be continued. Returning false will stop it.
2003
* @return true if iteration was completed and false if it
2004
* was cancelled by the slot before completion.
2006
template<typename TPred>
2007
bool foreach_member(TPred pred)
2009
// set of already seen members (only overriden ones)
2010
string_hash_set seen;
2011
MetaClass *mc= this;
2015
for (MemberList::const_iterator mem= mc->_members.begin(); mem != mc->_members.end(); ++mem)
2017
if (seen.find(mem->first) != seen.end())
2019
seen.insert(mem->first);
2021
if (!pred(&mem->second))
2031
/** Calls slot iterating through all methods of the metaclass.
2033
* The slot will be called for each method of the metaclass,
2034
* including inherited ones. If a method is overriden,
2035
* it will be called only once, for the "topmost" one.
2036
* The slot must return true as long as the iteration is
2037
* to be continued. Returning false will stop it.
2039
* @return true if iteration was completed and false if it
2040
* was cancelled by the slot before completion.
2043
template<typename TPred>
2044
bool foreach_method(TPred pred)
2046
// set of already seen methods (only overriden ones)
2047
string_hash_set seen;
2048
MetaClass *mc= this;
2052
for (MethodList::const_iterator mem= mc->_methods.begin(); mem != mc->_methods.end(); ++mem)
2054
if (seen.find(mem->first) != seen.end())
2056
seen.insert(mem->first);
2058
if (!pred(&mem->second))
2068
/** Calls slot iterating through all signals of the metaclass.
2070
* The slot will be called for each signal of the metaclass,
2071
* including inherited ones.
2072
* The slot must return true as long as the iteration is
2073
* to be continued. Returning false will stop it.
2075
* @return true if iteration was completed and false if it
2076
* was cancelled by the slot before completion.
2078
template<typename TPred>
2079
bool foreach_signal(TPred pred)
2081
// set of already seen methods (only overriden ones)
2082
string_hash_set seen;
2083
MetaClass *mc= this;
2087
for (SignalList::const_iterator mem= mc->_signals.begin(); mem != mc->_signals.end(); ++mem)
2089
if (seen.find(mem->name) != seen.end())
2091
seen.insert(mem->name);
2105
/** Applies all validators to obj and tag
2107
* @return true upon success and false if any validator has failed
2109
bool foreach_validator(const ObjectRef& obj, const Validator::Tag& tag);
2111
inline const MemberList &get_members_partial() { return _members; }
2112
inline const MethodList &get_methods_partial() { return _methods; }
2113
inline const SignalList &get_signals_partial() { return _signals; }
2115
bool is_a(const std::string &name) const;
2116
bool is_a(MetaClass *struc) const;
2118
bool has_member(const std::string &member) const;
2119
bool has_method(const std::string &method) const;
2121
const Member *get_member_info(const std::string &member) const;
2122
const Method *get_method_info(const std::string &method) const;
2124
TypeSpec get_member_type(const std::string &member) const;
2126
std::string get_attribute(const std::string &attr, bool search_parents=true);
2127
std::string get_member_attribute(const std::string &member, const std::string &attr, bool search_parents=true);
2129
bool is_abstract() const;
2131
void set_member_value(internal::Object* object, const std::string &name, const ValueRef &value);
2132
ValueRef get_member_value(const internal::Object *object, const std::string &name);
2133
ValueRef get_member_value(const internal::Object *object, const Member *member);
2135
ValueRef call_method(internal::Object *object, const std::string &name, const BaseListRef &args);
2136
ValueRef call_method(internal::Object *object, const Method *method, const BaseListRef &args);
2138
ObjectRef allocate();
2141
// for use by GRT only
2144
static MetaClass* create_base_class(GRT *grt);
2145
static MetaClass* from_xml(GRT *grt, const std::string &source, xmlNodePtr node);
2146
bool placeholder() const { return _placeholder; }
2148
bool is_bound() const;
2149
std::string source() { return _source; }
2151
bool force_impl() const { return _force_impl; }
2152
bool watch_lists() const { return _watch_lists; }
2153
bool watch_dicts() const { return _watch_dicts; }
2154
bool impl_data() const { return _impl_data; }
2156
void set_member_internal(internal::Object* object, const std::string &name, const ValueRef &value, bool force);
2158
public: // for use by Objects during registration
2159
void bind_allocator(Allocator alloc);
2160
void bind_member(const std::string &name, PropertyBase *prop);
2162
void bind_method(const std::string &name, Method::Function method);
2163
void add_validator(Validator* v);
2164
void remove_validator(Validator* v);
2167
friend class Serializer;
2168
friend class Unserializer;
2170
MetaClass(GRT *grt);
2171
void load_xml(xmlNodePtr node);
2172
void load_attribute_list(xmlNodePtr node, const std::string &member= "");
2179
std::string _source;
2183
std::map<std::string,std::string> _attributes;
2184
MemberList _members;
2185
MethodList _methods;
2186
SignalList _signals;
2187
ValidatorList _validators;
2189
unsigned int _crc32;
2194
bool _watch_lists; //< adds the virtual method that's called when owned lists are changed (watch-lists)
2195
bool _watch_dicts; //< adds the virtual method that's called when owned dicts are changed (watch-dicts)
2197
bool _impl_data; //< needs extra data for the object
2201
//------------------------------------------------------------------------------------------------
2202
//------------------------------------------------------------------------------------------------
2207
/** Module loader base class.
2209
* Supports loading and execution of modules composed of functions written in
2210
* a language. @a CPPModuleLoader is a special module loader to handle modules
2215
class MYSQLGRT_PUBLIC ModuleLoader
2218
ModuleLoader(GRT *grt) : _grt(grt) {}
2219
virtual ~ModuleLoader() {}
2221
virtual std::string get_loader_name()= 0;
2223
virtual Module *init_module(const std::string &path)= 0;
2225
virtual void refresh()= 0;
2227
virtual bool load_library(const std::string &path)= 0;
2228
virtual bool run_script_file(const std::string &path)= 0;
2229
virtual bool run_script(const std::string &script)= 0;
2230
virtual bool check_file_extension(const std::string &path)= 0;
2232
GRT *get_grt() const { return _grt; }
2235
GRT *_grt; //TODO: make it private, get_grt is as fast as direct access
2239
/** A GRT module class.
2241
* This class may be subclassed to create C++ modules.
2242
* A C++ module may be called directly through its @a Module
2243
* object or indirectly, through a @a ModuleWrapper
2247
class LuaModuleLoader;
2248
class MYSQLGRT_PUBLIC Module//
2250
friend class LuaModuleLoader;
2255
std::string description;
2257
ArgSpecList arg_types;
2259
boost::function<ValueRef (const grt::BaseListRef&)> call;
2262
bool has_function(const std::string &name) const;
2263
virtual ValueRef call_function(const std::string &name, const grt::BaseListRef &args);
2265
Module(ModuleLoader *loader);
2266
virtual ~Module() {}
2268
std::string name() const { return _name; }
2269
std::string version() const { return _meta_version; }
2270
std::string author() const { return _meta_author; }
2271
std::string description() const { return _meta_description; }
2272
std::string extends() const { return _extends; }
2273
std::string path() const { return _path; }
2274
std::string bundle_path() const;
2275
std::string default_icon_path() const;
2277
bool is_bundle() const { return _is_bundle; }
2279
const std::vector<Function> &get_functions() const { return _functions; }
2281
const Function *get_function(const std::string &name) const;
2283
typedef std::vector<std::string> Interfaces;
2285
//! Returns list of the interfaces which Module implements
2286
const Interfaces &get_interfaces() const { return _interfaces; }
2288
ModuleLoader *get_loader() const { return _loader; }
2289
GRT *get_grt() const { return _loader->get_grt(); }
2291
void validate() const;
2294
void set_global_data(const std::string &key, const std::string &value);
2295
void set_global_data(const std::string &key, int value);
2296
int global_int_data(const std::string &key, int default_value= 0);
2297
std::string global_string_data(const std::string &key, const std::string &default_value= "");
2299
void set_document_data(const std::string &key, const std::string &value);
2300
void set_document_data(const std::string &key, int value);
2301
int document_int_data(const std::string &key, int default_value= 0);
2302
std::string document_string_data(const std::string &key, const std::string &default_value= "");
2306
/** Parse a String defined module function specification.
2308
* Function parameter list syntax:
2310
* param_list::= param[, param_list]
2311
* param::= type [ label]
2312
* label::= a name for the parameter
2313
* type::= i | r | s | l[<content_spec>] | d[<content_spec>] | o[@struct]
2314
* content_spec::= i | r | s | o@struct
2315
* struct::= name of a valid struct
2319
* doSomething:s:i count,l<i> poslist,o<db.mysql.Table> table,d args
2321
virtual bool add_parse_function_spec(const std::string &spec, const boost::function<ValueRef (BaseListRef, Module*, Module::Function)> &caller);
2323
void add_function(const Function &func);
2328
std::string _meta_version;
2329
std::string _meta_author;
2330
std::string _meta_description;
2332
std::vector<Function> _functions;
2334
std::string _extends;
2336
Interfaces _interfaces;
2340
ModuleLoader *_loader;
2344
/** Base class for module wrapper classes.
2346
* This class is inherited by classes automatically generated by the genwrap tool.
2347
* These wrapper classes expose GRT modules written in any language as a C++ object.
2351
class MYSQLGRT_PUBLIC ModuleWrapper
2354
ModuleWrapper(Module *module) : _module(module) {}
2355
virtual ~ModuleWrapper() {}
2357
Module *get_module() const { return _module; }
2358
GRT *get_grt() const { return _module->get_grt(); }
2365
//------------------------------------------------------------------------------------------------
2366
//------------------------------------------------------------------------------------------------
2377
NoErrorMsg = 0x1000 //!< NoErrorMsg is used for live validation. ValidationManager uses this message type to
2378
//!< inform listeners that certain UI (list of errors, etc..) should be cleared
2382
struct MYSQLGRT_PUBLIC Message
2390
std::string format(bool withtype= false) const;
2393
typedef boost::function<void (const Message&, void*)> MessageSlot;
2394
typedef boost::function<bool ()> StatusQuerySlot;
2396
//-----------------------------------------------------------------------------------------------
2398
// gcc and msc produce different output for typeid(arg).name()
2399
// this function is a platform independent wrapper for typeid(arg).name()
2400
inline std::string get_full_type_name(const std::type_info& ti)
2404
char *tmp= __cxxabiv1::__cxa_demangle(ti.name(), NULL, NULL, &s);
2405
std::string ret(tmp);
2409
const char *name= ti.name();
2410
if(strncmp("class ", name, sizeof("class ") - 1) == 0)
2411
return std::string(name + sizeof("class ") - 1);
2412
else if(strncmp("struct ", name, sizeof("struct ") - 1) == 0)
2413
return std::string(name + sizeof("struct ") - 1);
2415
return std::string(name);
2417
# error Unknown compiler
2421
inline std::string get_type_name(const std::type_info& ti)
2423
std::string name= get_full_type_name(ti);
2425
// strip namespace::
2426
std::string::size_type p= name.rfind(':');
2427
if (p != std::string::npos)
2428
return name.substr(p+1);
2433
//------------------------------------------------------------------------------------------------
2434
//------------------------------------------------------------------------------------------------
2438
class ModuleWrapper;
2439
class CPPModuleLoader;
2444
/** The main GRT context object.
2448
class MYSQLGRT_PUBLIC GRT//
2459
void set_verbose(bool flag);
2460
bool verbose() const { return _verbose; }
2464
/** Load metaclasses defined in a XML file.
2466
* @ref end_loading_metaclasses() must be called once no more metaclasses
2469
* @param requires list of other XML files required by the loaded one
2471
void load_metaclasses(const std::string &file, std::list<std::string> *requires= 0);
2472
/** Scans a directory for metaclass definition files and load them.
2473
* Looks in the directory for files with the structs*.xml pattern and loads metaclasses
2474
* defined in them. The list of other struct files pre-required is returned in the optional
2475
* @a requires parameter.
2477
* @ref end_loading_metaclasses() must be called once no more metaclasses
2480
* @param dir directory to look for struct files
2481
* @param requires optional pointer to a multimap where required XML files for each loaded
2484
int scan_metaclasses_in(const std::string &dir, std::multimap<std::string,std::string> *requires= 0);
2485
/** End loading of metaclass definition files.
2486
* Finishes up loading of metaclass definition XMLs files. This will
2487
* check that all metaclasses referred by something were loaded. It will
2488
* also perform initialization of all known implementatin classes by
2489
* binding properties and method pointers.
2491
void end_loading_metaclasses(bool check_class_binding=true);
2493
const std::list<MetaClass*>& get_metaclasses() const { return _metaclasses_list; }
2495
MetaClass *get_metaclass(const std::string &name) const;
2498
Ref<C> create_object(const std::string &class_name) const
2500
MetaClass *mc= get_metaclass(class_name);
2501
if (!mc) throw bad_class(class_name);
2502
return Ref<C>::cast_from(mc->allocate());
2506
void serialize(const ValueRef &value, const std::string &path,
2507
const std::string &doctype="", const std::string &version="",
2508
bool list_objects_as_links= false);
2509
ValueRef unserialize(const std::string &path);
2510
ValueRef unserialize(const std::string &path, std::string &doctype_ret, std::string &version_ret);
2512
xmlDocPtr load_xml(const std::string &path);
2513
void get_xml_metainfo(xmlDocPtr doc, std::string &doctype_ret, std::string &version_ret);
2514
ValueRef unserialize_xml(xmlDocPtr doc, const std::string &source_path);
2516
std::string serialize_xml_data(const ValueRef &value, const std::string &doctype="",
2517
const std::string &version="", bool list_objects_as_links= false);
2518
ValueRef unserialize_xml_data(const std::string &data);
2523
inline ValueRef root() const { return _root; }
2524
void set_root(const ValueRef &root);
2526
ValueRef get(const std::string &path) const;
2527
void set(const std::string &path, const ValueRef &value);
2529
ObjectRef find_object_by_id(const std::string &id, const std::string &subpath);
2534
// path in globals tree for modules to store options
2535
void set_global_module_data_path(const std::string &path) { _global_module_options_path= path; }
2536
std::string global_module_data_path() { return _global_module_options_path; }
2538
void set_document_module_data_path(const std::string &path) { _document_module_options_path= path; }
2539
std::string document_module_data_path() { return _document_module_options_path; }
2541
void add_module_loader(ModuleLoader *loader);
2542
bool load_module(const std::string &path, bool refresh);
2543
void end_loading_modules();
2545
ModuleLoader *get_module_loader(const std::string &name);
2546
ModuleLoader *get_module_loader_for_file(const std::string &path);
2547
void refresh_loaders();
2549
void register_new_module(Module *module);
2550
void refresh_module(Module *module);
2551
void unregister_module(Module *module);
2553
void register_new_interface(Interface *iface);
2554
const std::map<std::string,Interface*> &get_interfaces() const { return _interfaces; }
2555
const Interface *get_interface(const std::string &name);
2557
int scan_modules_in(const std::string &path, const std::list<std::string> &exts,
2560
const std::vector<Module*> &get_modules() const { return _modules; }
2562
Module *get_module(const std::string &name);
2564
// create an instance of the given native module and registers it with the GRT.
2565
// this should not be used for accessing modules, use the
2566
// wrapper class for the module you want, instead (with get_module())
2567
template<class ModuleImplClass>
2568
ModuleImplClass *get_native_module()
2570
std::string mname= get_type_name(typeid(ModuleImplClass));
2573
if (mname.size() > 4 && mname.substr(mname.size()-4)=="Impl")
2574
mname= mname.substr(0, mname.size()-4);
2576
ModuleImplClass *instance;
2578
module= get_module(mname);
2581
instance= new ModuleImplClass((CPPModuleLoader*)get_module_loader("cpp"));
2582
instance->init_module();
2583
register_new_module(instance);
2587
instance= dynamic_cast<ModuleImplClass*>(module);
2595
// locate an instance of a module. suitable for direct access to modules
2596
template<class ModuleImplClass>
2597
ModuleImplClass *find_native_module(const char *name)
2599
Module *module= get_module(name);
2601
return static_cast<ModuleImplClass*>(module);
2604
std::vector<Module*> find_modules_matching(const std::string &interface_name, const std::string &name_pattern);
2606
template<class InterfaceWrapperClass>
2607
std::vector<InterfaceWrapperClass*> get_implementing_modules()
2609
std::vector<Module*> modules;
2610
std::vector<InterfaceWrapperClass*> mlist;
2612
modules= find_modules_matching(InterfaceWrapperClass::static_get_name(), "");
2614
for (std::vector<Module*>::const_iterator i= modules.begin();
2615
i != modules.end(); ++i)
2617
mlist.push_back(get_module_wrapper<InterfaceWrapperClass>(*i));
2623
// create an instance of a wrapper for the given module
2624
template<class ModuleWrapperClass>
2625
ModuleWrapperClass *get_module_wrapper(Module *amodule)
2627
ModuleWrapper *bmodule= _cached_module_wrapper[std::string(ModuleWrapperClass::static_get_name()).append("/").append(amodule->name())];
2628
ModuleWrapperClass *wrapper= dynamic_cast<ModuleWrapperClass*>(bmodule);
2632
wrapper= new ModuleWrapperClass(amodule);
2633
_cached_module_wrapper[std::string(ModuleWrapperClass::static_get_name()).append("/").append(amodule->name())]= wrapper;
2638
template<class ModuleWrapperClass>
2639
ModuleWrapperClass *get_module_wrapper(const std::string &module)
2641
ModuleWrapper *bmodule= _cached_module_wrapper[std::string(ModuleWrapperClass::static_get_name()).append("/").append(module)];
2642
ModuleWrapperClass *wrapper= dynamic_cast<ModuleWrapperClass*>(bmodule);
2646
Module *amodule= get_module(module);
2649
wrapper= new ModuleWrapperClass(amodule);
2650
_cached_module_wrapper[std::string(ModuleWrapperClass::static_get_name()).append("/").append(amodule->name())]= wrapper;
2659
void set_context_data(const std::string &key, void *value, void(*free_value)(void*)= 0);
2660
void unset_context_data(const std::string &key);
2661
void *get_context_data(const std::string &key);
2665
bool init_shell(const std::string &shell_type);
2667
std::string shell_type();
2670
void push_undo_manager(UndoManager *um);
2671
UndoManager *pop_undo_manager();
2673
UndoManager *get_undo_manager() const;
2674
void start_tracking_changes();
2675
void stop_tracking_changes();
2676
bool tracking_changes() const { return _tracking_changes > 0; }
2678
/** Starts tracking undo changes and opens an undo group.
2679
* Use the AutoUndo class for auto-trackign.
2681
UndoGroup *begin_undoable_action(UndoGroup *group= 0);
2682
void end_undoable_action(const std::string &group_description);
2683
void cancel_undoable_action();
2686
// grt logging/messaging
2687
MessageSlot set_message_handler(const MessageSlot &slot);
2688
StatusQuerySlot set_status_query_handler(const StatusQuerySlot &slot);
2690
void make_output_visible(void *sender= NULL);
2692
void send_error(const std::string &message, const std::string &details="", void *sender= NULL);
2693
void send_warning(const std::string &message, const std::string &details="", void *sender= NULL);
2694
void send_info(const std::string &message, const std::string &details="", void *sender= NULL);
2695
void send_progress(float percentage, const std::string &message, const std::string &details="", void *sender= NULL);
2697
void send_verbose(const std::string &message, void *sender= NULL);
2698
void send_output(const std::string &text, void *sender= NULL);
2704
AutoLock(const GRT *grt) : _grt(grt) { _grt->lock(); }
2705
~AutoLock() { _grt->unlock(); }
2708
void unlock() const;
2711
friend class MetaClass;
2713
//std::map<std::string,internal::Object*> _objects;
2715
MessageSlot _message_slot;
2716
StatusQuerySlot _status_query_slot;
2718
GStaticRecMutex _message_mutex;
2720
std::list<ModuleLoader*> _loaders;
2721
std::vector<Module*> _modules;
2722
std::map<std::string,Interface*> _interfaces;
2723
std::map<std::string,ModuleWrapper*> _cached_module_wrapper;
2725
std::map<std::string, std::pair<void*,void(*)(void*)> > _context_data;
2729
//std::list<ModuleLoader*> _loaders;
2731
// GStaticRecMutex _global_mutex;
2732
// GStaticRWLock _global_tree_lock;
2734
void add_metaclass(MetaClass *stru);
2735
std::string module_path_in_bundle(const std::string &path);
2737
std::map<std::string,MetaClass*> _metaclasses;
2738
std::list<MetaClass*> _metaclasses_list;
2741
std::list<UndoManager*> _undo_managers;
2742
UndoManager *_default_undo_manager;
2743
std::string _global_module_options_path;
2744
std::string _document_module_options_path;
2745
int _tracking_changes;
2746
bool _check_serialized_crc;
2748
bool _scanning_modules;
2751
//------------------------------------------------------------------------------------------------
2752
//------------------------------------------------------------------------------------------------
2755
inline bool ListRef<O>::can_wrap(const ValueRef &value)
2757
if (value.type() != ListType)
2760
if (!value.is_valid())
2763
internal::List *candidate_list= static_cast<internal::List*>(value.valueptr());
2765
if (candidate_list->content_type() != O::static_type())
2768
// we allow stuff like List<db_Table> = List<db_mysql_Table>
2770
MetaClass *content_class= candidate_list->get_grt()->get_metaclass(O::static_class_name());
2771
if (!content_class && !O::static_class_name().empty())
2772
throw std::runtime_error(std::string("metaclass without runtime info ").append(O::static_class_name()));
2774
MetaClass *candidate_class= candidate_list->get_grt()->get_metaclass(candidate_list->content_class_name());
2775
if (!candidate_class && !candidate_list->content_class_name().empty())
2776
throw std::runtime_error(std::string("metaclass without runtime info ").append(candidate_list->content_class_name()));
2778
if (candidate_class == content_class) // classes are the same
2780
if (!content_class) // we're a generic list
2782
if (!candidate_class) // candidate is a generic list and we're not
2784
return candidate_class->is_a(content_class);