00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __CLASS_H__
00012 #define __CLASS_H__
00013
00014 #include "stdtp.h"
00015 #include "sync.h"
00016 #include "rectangle.h"
00017
00018 BEGIN_GIGABASE_NAMESPACE
00019
00020 #ifndef dbDatabaseOffsetBits
00021 #ifdef LARGE_DATABASE_SUPPORT
00022 #define dbDatabaseOffsetBits 40 // up to 1 terabyte
00023 #else
00024 #define dbDatabaseOffsetBits 32 // 37 - 128Gb, 40 - up to 1 terabyte
00025 #endif
00026 #endif
00027
00028 #ifndef dbDatabaseOidBits
00029 #define dbDatabaseOidBits 32
00030 #endif
00031
00035 #if dbDatabaseOidBits > 32
00036 typedef nat8 oid_t;
00037 #else
00038 typedef nat4 oid_t;
00039 #endif
00040
00044 #if dbDatabaseOffsetBits > 32
00045 typedef nat8 offs_t;
00046 #else
00047 typedef nat4 offs_t;
00048 #endif
00049
00050 #include "selection.h"
00051
00055 enum dbIndexType {
00056 HASHED = 1,
00057 INDEXED = 2,
00058 CASE_INSENSITIVE = 4,
00059
00060 DB_FIELD_CASCADE_DELETE = 8,
00061 UNIQUE = 16,
00062
00063 AUTOINCREMENT = 32,
00064 OPTIMIZE_DUPLICATES = 64,
00065 DB_BLOB_CASCADE_DELETE = 128,
00066
00067 DB_TIMESTAMP = 256,
00068
00069 DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00070 };
00071
00075 #define KEY(x, index) \
00076 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00077 sizeof(x), index), x)
00078
00082 #define FIELD(x) KEY(x, 0)
00083
00087 typedef int (*dbUDTComparator)(void*, void*, size_t);
00088
00092 #define UDT(x, index, comparator) \
00093 *dbDescribeRawField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00094 sizeof(x), index), (dbUDTComparator)comparator)
00095
00099 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00100
00104 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00105
00106
00112 #define RELATION(x,inverse) \
00113 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00114 sizeof(x), 0, STRLITERAL(#inverse)), x)
00115
00121 #define INDEXED_RELATION(x,inverse) \
00122 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00123 sizeof(x), INDEXED, STRLITERAL(#inverse)), x)
00124
00130 #define OWNER(x,member) \
00131 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00132 sizeof(x), DB_FIELD_CASCADE_DELETE, \
00133 STRLITERAL(#member)), x)
00134
00138 #define METHOD(x) \
00139 *dbDescribeMethod(new dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00140
00147 #define BLOB(x) \
00148 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00149 sizeof(x), DB_BLOB_CASCADE_DELETE), x)
00150
00153 #define SUPERCLASS(x) \
00154 x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00155
00160 #define TYPE_DESCRIPTOR(fields) \
00161 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00162 return &fields; \
00163 } \
00164 static dbTableDescriptor dbDescriptor
00165
00171 #define CLASS_DESCRIPTOR(name, fields) \
00172 typedef name self; \
00173 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00174 return &fields; \
00175 } \
00176 static dbTableDescriptor dbDescriptor
00177
00178 #if (defined(_MSC_VER) && _MSC_VER+0 < 1200) || defined(__MWERKS__)
00179
00182 #if defined(_MSC_VER)
00183 #define TEMPLATE_SPEC
00184 #else
00185 #define TEMPLATE_SPEC template <>
00186 #endif
00187 #define REGISTER_IN(table, database) \
00188 TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00189 { return &table::dbDescriptor; } \
00190 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00191 { return ((table*)0)->dbDescribeComponents(NULL); } \
00192 dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00193 &dbDescribeComponentsOf##table)
00194
00195 #define REGISTER_TEMPLATE_IN(table, database) \
00196 TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00197 { return &table::dbDescriptor; } \
00198 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00199 { return ((table*)0)->dbDescribeComponents(NULL); } \
00200 template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00201 &dbDescribeComponentsOf##table)
00202 #else
00203
00206 #define REGISTER_IN(table, database) \
00207 dbTableDescriptor* dbGetTableDescriptor(table*) \
00208 { return &table::dbDescriptor; } \
00209 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00210 { return ((table*)0)->dbDescribeComponents(NULL); } \
00211 dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00212 &dbDescribeComponentsOf##table)
00213 #define REGISTER_TEMPLATE_IN(table, database) \
00214 dbTableDescriptor* dbGetTableDescriptor(table*) \
00215 { return &table::dbDescriptor; } \
00216 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00217 { return ((table*)0)->dbDescribeComponents(NULL); } \
00218 template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00219 &dbDescribeComponentsOf##table)
00220 #endif
00221
00226 #define REGISTER(table) REGISTER_IN(table, NULL)
00227 #define REGISTER_TEMPLATE(table) REGISTER_TEMPLATE_IN(table, NULL)
00228
00233 #define DETACHED_TABLE ((dbDatabase*)-1)
00234 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00235 #define REGISTER_TEMPLATE_UNASSIGNED(table) REGISTER_TEMPLATE_IN(table, DETACHED_TABLE)
00236
00237
00238 class dbDatabase;
00239 class dbAnyArray;
00240 class dbTableDescriptor;
00241 class dbAnyMethodTrampoline;
00242 class dbTable;
00243
00247 class GIGABASE_DLL_ENTRY dbFieldDescriptor {
00248 public:
00252 dbFieldDescriptor* next;
00253
00257 dbFieldDescriptor* prev;
00258
00262 dbFieldDescriptor* nextField;
00263
00267 dbFieldDescriptor* nextHashedField;
00268
00272 dbFieldDescriptor* nextIndexedField;
00273
00277 dbFieldDescriptor* nextInverseField;
00278
00282 int fieldNo;
00283
00287 char_t* name;
00288
00292 char_t* longName;
00293
00297 char_t* refTableName;
00298
00302 dbTableDescriptor* refTable;
00303
00307 dbTableDescriptor* defTable;
00308
00312 dbFieldDescriptor* inverseRef;
00313
00317 char_t* inverseRefName;
00318
00322 int type;
00323
00327 int appType;
00328
00332 int indexType;
00333
00337 int dbsOffs;
00338
00342 int appOffs;
00343
00347 dbFieldDescriptor* components;
00348
00352 oid_t hashTable;
00353
00357 oid_t bTree;
00358
00362 size_t dbsSize;
00363
00367 size_t appSize;
00368
00373 size_t alignment;
00374
00378 dbUDTComparator comparator;
00379
00383 enum FieldAttributes {
00384 ComponentOfArray = 0x01,
00385 HasArrayComponents = 0x02,
00386 OneToOneMapping = 0x04,
00387 Updated = 0x08
00388 };
00389 int attr;
00390
00394 int oldDbsType;
00398 int oldDbsOffs;
00402 int oldDbsSize;
00403
00404
00408 dbAnyMethodTrampoline* method;
00409
00413 void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00414
00425 size_t calculateRecordSize(byte* base, size_t offs);
00426
00436 size_t calculateNewRecordSize(byte* base, size_t offs);
00437
00447 size_t convertRecord(byte* dst, byte* src, size_t offs);
00448
00459 int sizeWithoutOneField(dbFieldDescriptor* field,
00460 byte* base, size_t& size);
00461
00471 size_t copyRecordExceptOneField(dbFieldDescriptor* field,
00472 byte* dst, byte* src, size_t offs);
00473
00484 size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
00485
00493 void markUpdatedFields(byte* dst, byte* src);
00494
00502 void fetchRecordFields(byte* dst, byte* src);
00503
00509 dbFieldDescriptor* find(const char_t* name);
00510
00515 dbFieldDescriptor* getFirstComponent() {
00516 return components;
00517 }
00518
00523 dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) {
00524 if (field != NULL) {
00525 field = field->next;
00526 if (field == components) {
00527 return NULL;
00528 }
00529 }
00530 return field;
00531 }
00532
00536 dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00537 dbFieldDescriptor* tail = field.prev;
00538 tail->next = this;
00539 prev->next = &field;
00540 field.prev = prev;
00541 prev = tail;
00542 return *this;
00543 }
00544
00545 void* operator new(size_t size);
00546 void operator delete(void* p);
00547
00551 dbFieldDescriptor& adjustOffsets(long offs);
00552
00562 dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00563 char_t const* inverse = NULL,
00564 dbFieldDescriptor* components = NULL);
00565
00570 dbFieldDescriptor(char_t const* name);
00571
00575 ~dbFieldDescriptor();
00576 };
00577
00578
00582 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00583 friend class dbCompiler;
00584 friend class dbDatabase;
00585 friend class dbReplicatedDatabase;
00586 friend class dbTable;
00587 friend class dbAnyCursor;
00588 friend class dbSubSql;
00589 friend class dbParallelQueryContext;
00590 friend class dbServer;
00591 friend class dbAnyContainer;
00592 friend class dbColumnBinding;
00593 friend class dbFieldDescriptor;
00594 friend class dbSelection;
00595 friend class dbTableIterator;
00596 friend class dbCLI;
00597 protected:
00601 dbTableDescriptor* next;
00602 static dbTableDescriptor* chain;
00603
00607 dbTableDescriptor* nextDbTable;
00608
00612 char_t* name;
00613
00617 oid_t tableId;
00618
00622 dbFieldDescriptor* columns;
00623
00627 dbFieldDescriptor* hashedFields;
00628
00632 dbFieldDescriptor* indexedFields;
00633
00637 dbFieldDescriptor* inverseFields;
00638
00642 dbFieldDescriptor* firstField;
00643
00647 dbFieldDescriptor** nextFieldLink;
00648
00652 dbDatabase* db;
00653
00657 bool fixedDatabase;
00658
00662 bool isStatic;
00663
00669 dbTableDescriptor* cloneOf;
00670
00674 size_t appSize;
00675
00679 size_t fixedSize;
00680
00684 size_t nFields;
00685
00689 size_t nColumns;
00690
00694 oid_t firstRow;
00695
00699 oid_t lastRow;
00700
00704 size_t nRows;
00705
00709 int4 autoincrementCount;
00710
00714 dbTableDescriptor* nextBatch;
00715
00719 bool isInBatch;
00720
00724 dbSelection batch;
00725
00729 int transactionId;
00730
00734 typedef dbFieldDescriptor* (*describeFunc)();
00735 describeFunc describeComponentsFunc;
00736
00740 size_t totalNamesLength();
00741
00753 int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00754 char_t const* prefix, int offs,
00755 int indexMask, int& attr);
00756
00765 dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00766 int prefixLen, int& attr);
00770 dbTableDescriptor* clone();
00771
00772 public:
00776 static int initialAutoincrementCount;
00777
00778
00782 dbTableDescriptor* getNextTable() {
00783 return nextDbTable;
00784 }
00785
00789 dbFieldDescriptor* findSymbol(char_t const* name);
00790
00794 dbFieldDescriptor* find(char_t const* name);
00795
00800 dbFieldDescriptor* getFirstField() {
00801 return columns;
00802 }
00803
00808 int getLastValueOfAutoincrementCount() const {
00809 return autoincrementCount;
00810 }
00811
00817 dbFieldDescriptor* getNextField(dbFieldDescriptor* field) {
00818 if (field != NULL) {
00819 field = field->next;
00820 if (field == columns) {
00821 return NULL;
00822 }
00823 }
00824 return field;
00825 }
00826
00830 char_t* getName() {
00831 return name;
00832 }
00833
00837 size_t size() {
00838 return appSize;
00839 }
00840
00847 bool equal(dbTable* table);
00848
00857 bool match(dbTable* table, bool confirmDeleteColumns);
00858
00864 void checkRelationship();
00865
00870 dbDatabase* getDatabase() { return db; }
00871
00876 void storeInDatabase(dbTable* table);
00877
00882 void setFlags();
00883
00884
00888 static void cleanup();
00889
00890
00895 dbTableDescriptor(dbTable* table);
00896
00905 dbTableDescriptor(char_t const* tableName,
00906 dbDatabase* db,
00907 size_t objSize,
00908 describeFunc func,
00909 dbTableDescriptor* original = NULL);
00910
00914 ~dbTableDescriptor();
00915 };
00916
00920 struct dbVarying {
00921 nat4 size;
00922 int4 offs;
00923 };
00924
00928 struct dbField {
00929 enum FieldTypes {
00930 tpBool,
00931 tpInt1,
00932 tpInt2,
00933 tpInt4,
00934 tpInt8,
00935 tpReal4,
00936 tpReal8,
00937 tpString,
00938 tpReference,
00939 tpArray,
00940 tpMethodBool,
00941 tpMethodInt1,
00942 tpMethodInt2,
00943 tpMethodInt4,
00944 tpMethodInt8,
00945 tpMethodReal4,
00946 tpMethodReal8,
00947 tpMethodString,
00948 tpMethodReference,
00949 tpStructure,
00950 tpRawBinary,
00951 tpStdString,
00952 tpMfcString,
00953 tpRectangle,
00954 tpUnknown
00955 };
00956
00960 dbVarying name;
00961
00965 dbVarying tableName;
00966
00970 dbVarying inverse;
00971
00975 #ifdef OLD_FIELD_DESCRIPTOR_FORMAT
00976 int4 type;
00977 #else
00978 #if BYTE_ORDER == BIG_ENDIAN
00979 int4 flags : 24;
00980 int4 type : 8;
00981 #else
00982 int4 type : 8;
00983 int4 flags : 24;
00984 #endif
00985 #endif
00986
00990 int4 offset;
00991
00995 nat4 size;
00996
01000 oid_t hashTable;
01001
01005 oid_t bTree;
01006 };
01007
01008
01012 class dbRecord {
01013 public:
01017 nat4 size;
01018
01022 oid_t next;
01023
01027 oid_t prev;
01028 };
01029
01030
01034 class dbTable : public dbRecord {
01035 public:
01039 dbVarying name;
01040
01044 dbVarying fields;
01045
01049 nat4 fixedSize;
01050
01054 nat4 nRows;
01055
01059 nat4 nColumns;
01060
01064 oid_t firstRow;
01065
01069 oid_t lastRow;
01070 #ifdef AUTOINCREMENT_SUPPORT
01071
01074 nat4 count;
01075 #endif
01076 };
01077
01078 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01079 {
01080 fd->type = fd->appType = dbField::tpRawBinary;
01081 fd->alignment = 1;
01082 fd->comparator = comparator;
01083 return fd;
01084 }
01085
01086 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01087 {
01088 fd->type = fd->appType = dbField::tpInt1;
01089 return fd;
01090 }
01091 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01092 {
01093 fd->type = fd->appType = dbField::tpInt2;
01094 return fd;
01095 }
01096 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01097 {
01098 fd->type = fd->appType = dbField::tpInt4;
01099 return fd;
01100 }
01101 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01102 {
01103 fd->type = fd->appType = dbField::tpInt8;
01104 return fd;
01105 }
01106 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01107 {
01108 fd->type = fd->appType = dbField::tpInt1;
01109 return fd;
01110 }
01111 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01112 {
01113 fd->type = fd->appType = dbField::tpInt2;
01114 return fd;
01115 }
01116 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01117 {
01118 fd->type = fd->appType = dbField::tpInt4;
01119 return fd;
01120 }
01121 #if SIZEOF_LONG != 8
01122 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01123 {
01124 fd->type = fd->appType = dbField::tpInt4;
01125 return fd;
01126 }
01127 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01128 {
01129 fd->type = fd->appType = dbField::tpInt4;
01130 return fd;
01131 }
01132 #endif
01133 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01134 {
01135 fd->type = fd->appType = dbField::tpInt8;
01136 return fd;
01137 }
01138 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01139 {
01140 fd->type = fd->appType = dbField::tpBool;
01141 return fd;
01142 }
01143 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01144 {
01145 fd->type = fd->appType = dbField::tpReal4;
01146 return fd;
01147 }
01148 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01149 {
01150 fd->type = fd->appType = dbField::tpReal8;
01151 return fd;
01152 }
01153 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01154 {
01155 fd->type = fd->appType = dbField::tpRectangle;
01156 fd->alignment = sizeof(coord_t);
01157 return fd;
01158 }
01159
01160 #ifdef USE_STD_STRING
01161 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01162 {
01163 fd->type = dbField::tpString;
01164 fd->appType = dbField::tpStdString;
01165 fd->dbsSize = sizeof(dbVarying);
01166 fd->alignment = 4;
01167 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01168 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01169 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01170 return fd;
01171 }
01172 #endif
01173 #ifdef USE_MFC_STRING
01174 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01175 {
01176 fd->type = dbField::tpString;
01177 fd->appType = dbField::tpMfcString;
01178 fd->dbsSize = sizeof(dbVarying);
01179 fd->alignment = 4;
01180 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01181 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01182 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01183 return fd;
01184 }
01185 #endif
01186
01187 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01188 {
01189 fd->type = fd->appType = dbField::tpString;
01190 fd->dbsSize = sizeof(dbVarying);
01191 fd->alignment = 4;
01192 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01193 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01194 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01195 return fd;
01196 }
01197 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01198 {
01199 fd->type = fd->appType = dbField::tpString;
01200 fd->dbsSize = sizeof(dbVarying);
01201 fd->alignment = 4;
01202 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01203 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01204 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01205 return fd;
01206 }
01207
01208
01209 template<class T>
01210 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01211 {
01212 fd->type = fd->appType = dbField::tpStructure;
01213 fd->components = x.dbDescribeComponents(fd);
01214 return fd;
01215 }
01216
01217
01221 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01222 public:
01223 dbFieldDescriptor* cls;
01224
01230 virtual void invoke(byte* data, void* result) = 0;
01231
01238 virtual dbAnyMethodTrampoline* optimize() = 0;
01239
01244 dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01245
01249 virtual~dbAnyMethodTrampoline();
01250
01251 void* operator new(size_t size);
01252 void operator delete(void* p);
01253 };
01254
01255 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510 && __SUNPRO_CC_COMPAT == 5)
01256
01259 template<class T, class R>
01260 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01261 public:
01262 typedef R (T::*mfunc)();
01263
01264 mfunc method;
01265 dbFieldDescriptor* cls;
01266 bool optimized;
01267
01268 void invoke(byte* data, void* result) {
01269 if (optimized) {
01270 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01271 } else {
01272 T rec;
01273 this->cls->components->fetchRecordFields((byte*)&rec, data);
01274 *(R*)result = (rec.*method)();
01275 }
01276 }
01277 dbAnyMethodTrampoline* optimize() {
01278 optimized = true;
01279 return this;
01280 }
01281
01282 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01283 : dbAnyMethodTrampoline(fd)
01284 {
01285 this->method = f;
01286 this->cls = fd;
01287 this->optimized = false;
01288 }
01289 };
01290
01291 #else
01292
01296 template<class T, class R>
01297 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01298 public:
01299 typedef R (T::*mfunc)();
01300 mfunc method;
01301
01302 void invoke(byte* data, void* result) {
01303 T rec;
01304 this->cls->components->fetchRecordFields((byte*)&rec, data);
01305 *(R*)result = (rec.*method)();
01306 }
01307 dbAnyMethodTrampoline* optimize();
01308
01309 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01310 : dbAnyMethodTrampoline(fd), method(f) {}
01311 };
01312
01313 template<class T, class R>
01314 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01315 typedef R (T::*mfunc)();
01316 mfunc method;
01317 public:
01318 dbAnyMethodTrampoline* optimize() {
01319 return this;
01320 }
01321 void invoke(byte* data, void* result) {
01322 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01323 }
01324 dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt)
01325 : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01326 delete mt;
01327 }
01328 };
01329
01330 template<class T, class R>
01331 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01332 return new dbMethodFastTrampoline<T,R>(this);
01333 }
01334
01335 #endif
01336 template<class T, class R>
01337 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01338 {
01339 R ret;
01340 dbDescribeField(fd, ret);
01341 assert(fd->type <= dbField::tpReference);
01342 fd->appType = fd->type += dbField::tpMethodBool;
01343 fd->method = new dbMethodTrampoline<T,R>(fd, p);
01344 return fd;
01345 }
01346
01347 END_GIGABASE_NAMESPACE
01348
01349 #endif
01350
01351