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
00474
00475 enum StoreMode {
00476 Insert,
00477 Update,
00478 Import
00479 };
00480
00491 size_t storeRecordFields(byte* dst, byte* src, size_t offs, StoreMode mode);
00492
00500 void markUpdatedFields(byte* dst, byte* src);
00501
00509 void fetchRecordFields(byte* dst, byte* src);
00510
00516 dbFieldDescriptor* find(const char_t* name);
00517
00522 dbFieldDescriptor* getFirstComponent() {
00523 return components;
00524 }
00525
00530 dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) {
00531 if (field != NULL) {
00532 field = field->next;
00533 if (field == components) {
00534 return NULL;
00535 }
00536 }
00537 return field;
00538 }
00539
00543 dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00544 dbFieldDescriptor* tail = field.prev;
00545 tail->next = this;
00546 prev->next = &field;
00547 field.prev = prev;
00548 prev = tail;
00549 return *this;
00550 }
00551
00552 void* operator new(size_t size);
00553 void operator delete(void* p);
00554
00558 dbFieldDescriptor& adjustOffsets(long offs);
00559
00569 dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00570 char_t const* inverse = NULL,
00571 dbFieldDescriptor* components = NULL);
00572
00577 dbFieldDescriptor(char_t const* name);
00578
00582 ~dbFieldDescriptor();
00583 };
00584
00585
00589 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00590 friend class dbCompiler;
00591 friend class dbDatabase;
00592 friend class dbReplicatedDatabase;
00593 friend class dbTable;
00594 friend class dbAnyCursor;
00595 friend class dbSubSql;
00596 friend class dbParallelQueryContext;
00597 friend class dbServer;
00598 friend class dbAnyContainer;
00599 friend class dbColumnBinding;
00600 friend class dbFieldDescriptor;
00601 friend class dbSelection;
00602 friend class dbTableIterator;
00603 friend class dbCLI;
00604 protected:
00608 dbTableDescriptor* next;
00609 static dbTableDescriptor* chain;
00610
00614 dbTableDescriptor* nextDbTable;
00615
00619 char_t* name;
00620
00624 oid_t tableId;
00625
00629 dbFieldDescriptor* columns;
00630
00634 dbFieldDescriptor* hashedFields;
00635
00639 dbFieldDescriptor* indexedFields;
00640
00644 dbFieldDescriptor* inverseFields;
00645
00649 dbFieldDescriptor* firstField;
00650
00654 dbFieldDescriptor** nextFieldLink;
00655
00659 dbDatabase* db;
00660
00664 bool fixedDatabase;
00665
00669 bool isStatic;
00670
00676 dbTableDescriptor* cloneOf;
00677
00681 size_t appSize;
00682
00686 size_t fixedSize;
00687
00691 size_t nFields;
00692
00696 size_t nColumns;
00697
00701 oid_t firstRow;
00702
00706 oid_t lastRow;
00707
00711 size_t nRows;
00712
00716 int4 autoincrementCount;
00717
00721 dbTableDescriptor* nextBatch;
00722
00726 bool isInBatch;
00727
00731 dbSelection batch;
00732
00736 int transactionId;
00737
00741 typedef dbFieldDescriptor* (*describeFunc)();
00742 describeFunc describeComponentsFunc;
00743
00747 size_t totalNamesLength();
00748
00760 int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00761 char_t const* prefix, int offs,
00762 int indexMask, int& attr);
00763
00772 dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00773 int prefixLen, int& attr);
00777 dbTableDescriptor* clone();
00778
00779 public:
00783 static int initialAutoincrementCount;
00784
00785
00789 dbTableDescriptor* getNextTable() {
00790 return nextDbTable;
00791 }
00792
00796 dbFieldDescriptor* findSymbol(char_t const* name);
00797
00801 dbFieldDescriptor* find(char_t const* name);
00802
00807 dbFieldDescriptor* getFirstField() {
00808 return columns;
00809 }
00810
00815 int getLastValueOfAutoincrementCount() const {
00816 return autoincrementCount;
00817 }
00818
00824 dbFieldDescriptor* getNextField(dbFieldDescriptor* field) {
00825 if (field != NULL) {
00826 field = field->next;
00827 if (field == columns) {
00828 return NULL;
00829 }
00830 }
00831 return field;
00832 }
00833
00837 char_t* getName() {
00838 return name;
00839 }
00840
00844 size_t size() {
00845 return appSize;
00846 }
00847
00854 bool equal(dbTable* table);
00855
00864 bool match(dbTable* table, bool confirmDeleteColumns);
00865
00871 void checkRelationship();
00872
00877 dbDatabase* getDatabase() { return db; }
00878
00883 void storeInDatabase(dbTable* table);
00884
00889 void setFlags();
00890
00891
00895 static void cleanup();
00896
00897
00902 dbTableDescriptor(dbTable* table);
00903
00912 dbTableDescriptor(char_t const* tableName,
00913 dbDatabase* db,
00914 size_t objSize,
00915 describeFunc func,
00916 dbTableDescriptor* original = NULL);
00917
00921 ~dbTableDescriptor();
00922 };
00923
00927 struct dbVarying {
00928 nat4 size;
00929 int4 offs;
00930 };
00931
00935 struct dbField {
00936 enum FieldTypes {
00937 tpBool,
00938 tpInt1,
00939 tpInt2,
00940 tpInt4,
00941 tpInt8,
00942 tpReal4,
00943 tpReal8,
00944 tpString,
00945 tpReference,
00946 tpArray,
00947 tpMethodBool,
00948 tpMethodInt1,
00949 tpMethodInt2,
00950 tpMethodInt4,
00951 tpMethodInt8,
00952 tpMethodReal4,
00953 tpMethodReal8,
00954 tpMethodString,
00955 tpMethodReference,
00956 tpStructure,
00957 tpRawBinary,
00958 tpStdString,
00959 tpMfcString,
00960 tpRectangle,
00961 tpUnknown
00962 };
00963
00967 dbVarying name;
00968
00972 dbVarying tableName;
00973
00977 dbVarying inverse;
00978
00982 #ifdef OLD_FIELD_DESCRIPTOR_FORMAT
00983 int4 type;
00984 #else
00985 #if BYTE_ORDER == BIG_ENDIAN
00986 int4 flags : 24;
00987 int4 type : 8;
00988 #else
00989 int4 type : 8;
00990 int4 flags : 24;
00991 #endif
00992 #endif
00993
00997 int4 offset;
00998
01002 nat4 size;
01003
01007 oid_t hashTable;
01008
01012 oid_t bTree;
01013 };
01014
01015
01019 class dbRecord {
01020 public:
01024 nat4 size;
01025
01029 oid_t next;
01030
01034 oid_t prev;
01035 };
01036
01037
01041 class dbTable : public dbRecord {
01042 public:
01046 dbVarying name;
01047
01051 dbVarying fields;
01052
01056 nat4 fixedSize;
01057
01061 nat4 nRows;
01062
01066 nat4 nColumns;
01067
01071 oid_t firstRow;
01072
01076 oid_t lastRow;
01077 #ifdef AUTOINCREMENT_SUPPORT
01078
01081 nat4 count;
01082 #endif
01083 };
01084
01085 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01086 {
01087 fd->type = fd->appType = dbField::tpRawBinary;
01088 fd->alignment = 1;
01089 fd->comparator = comparator;
01090 return fd;
01091 }
01092
01093 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01094 {
01095 fd->type = fd->appType = dbField::tpInt1;
01096 return fd;
01097 }
01098 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01099 {
01100 fd->type = fd->appType = dbField::tpInt2;
01101 return fd;
01102 }
01103 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01104 {
01105 fd->type = fd->appType = dbField::tpInt4;
01106 return fd;
01107 }
01108 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01109 {
01110 fd->type = fd->appType = dbField::tpInt8;
01111 return fd;
01112 }
01113 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01114 {
01115 fd->type = fd->appType = dbField::tpInt1;
01116 return fd;
01117 }
01118 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01119 {
01120 fd->type = fd->appType = dbField::tpInt2;
01121 return fd;
01122 }
01123 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01124 {
01125 fd->type = fd->appType = dbField::tpInt4;
01126 return fd;
01127 }
01128 #if SIZEOF_LONG != 8
01129 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01130 {
01131 fd->type = fd->appType = dbField::tpInt4;
01132 return fd;
01133 }
01134 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01135 {
01136 fd->type = fd->appType = dbField::tpInt4;
01137 return fd;
01138 }
01139 #endif
01140 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01141 {
01142 fd->type = fd->appType = dbField::tpInt8;
01143 return fd;
01144 }
01145 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01146 {
01147 fd->type = fd->appType = dbField::tpBool;
01148 return fd;
01149 }
01150 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01151 {
01152 fd->type = fd->appType = dbField::tpReal4;
01153 return fd;
01154 }
01155 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01156 {
01157 fd->type = fd->appType = dbField::tpReal8;
01158 return fd;
01159 }
01160 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01161 {
01162 fd->type = fd->appType = dbField::tpRectangle;
01163 fd->alignment = sizeof(coord_t);
01164 return fd;
01165 }
01166
01167 #ifdef USE_STD_STRING
01168 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01169 {
01170 fd->type = dbField::tpString;
01171 fd->appType = dbField::tpStdString;
01172 fd->dbsSize = sizeof(dbVarying);
01173 fd->alignment = 4;
01174 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01175 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01176 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01177 return fd;
01178 }
01179 #endif
01180 #ifdef USE_MFC_STRING
01181 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01182 {
01183 fd->type = dbField::tpString;
01184 fd->appType = dbField::tpMfcString;
01185 fd->dbsSize = sizeof(dbVarying);
01186 fd->alignment = 4;
01187 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01188 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01189 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01190 return fd;
01191 }
01192 #endif
01193
01194 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01195 {
01196 fd->type = fd->appType = dbField::tpString;
01197 fd->dbsSize = sizeof(dbVarying);
01198 fd->alignment = 4;
01199 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01200 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01201 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01202 return fd;
01203 }
01204 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01205 {
01206 fd->type = fd->appType = dbField::tpString;
01207 fd->dbsSize = sizeof(dbVarying);
01208 fd->alignment = 4;
01209 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01210 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01211 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01212 return fd;
01213 }
01214
01215
01216 template<class T>
01217 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01218 {
01219 fd->type = fd->appType = dbField::tpStructure;
01220 fd->components = x.dbDescribeComponents(fd);
01221 return fd;
01222 }
01223
01224
01228 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01229 public:
01230 dbFieldDescriptor* cls;
01231
01237 virtual void invoke(byte* data, void* result) = 0;
01238
01245 virtual dbAnyMethodTrampoline* optimize() = 0;
01246
01251 dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01252
01256 virtual~dbAnyMethodTrampoline();
01257
01258 void* operator new(size_t size);
01259 void operator delete(void* p);
01260 };
01261
01262 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510 && __SUNPRO_CC_COMPAT == 5)
01263
01266 template<class T, class R>
01267 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01268 public:
01269 typedef R (T::*mfunc)();
01270
01271 mfunc method;
01272 dbFieldDescriptor* cls;
01273 bool optimized;
01274
01275 void invoke(byte* data, void* result) {
01276 if (optimized) {
01277 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01278 } else {
01279 T rec;
01280 this->cls->components->fetchRecordFields((byte*)&rec, data);
01281 *(R*)result = (rec.*method)();
01282 }
01283 }
01284 dbAnyMethodTrampoline* optimize() {
01285 optimized = true;
01286 return this;
01287 }
01288
01289 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01290 : dbAnyMethodTrampoline(fd)
01291 {
01292 this->method = f;
01293 this->cls = fd;
01294 this->optimized = false;
01295 }
01296 };
01297
01298 #else
01299
01303 template<class T, class R>
01304 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01305 public:
01306 typedef R (T::*mfunc)();
01307 mfunc method;
01308
01309 void invoke(byte* data, void* result) {
01310 T rec;
01311 this->cls->components->fetchRecordFields((byte*)&rec, data);
01312 *(R*)result = (rec.*method)();
01313 }
01314 dbAnyMethodTrampoline* optimize();
01315
01316 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01317 : dbAnyMethodTrampoline(fd), method(f) {}
01318 };
01319
01320 template<class T, class R>
01321 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01322 typedef R (T::*mfunc)();
01323 mfunc method;
01324 public:
01325 dbAnyMethodTrampoline* optimize() {
01326 return this;
01327 }
01328 void invoke(byte* data, void* result) {
01329 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01330 }
01331 dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt)
01332 : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01333 delete mt;
01334 }
01335 };
01336
01337 template<class T, class R>
01338 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01339 return new dbMethodFastTrampoline<T,R>(this);
01340 }
01341
01342 #endif
01343 template<class T, class R>
01344 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01345 {
01346 R ret;
01347 dbDescribeField(fd, ret);
01348 assert(fd->type <= dbField::tpReference);
01349 fd->appType = fd->type += dbField::tpMethodBool;
01350 fd->method = new dbMethodTrampoline<T,R>(fd, p);
01351 return fd;
01352 }
01353
01354 END_GIGABASE_NAMESPACE
01355
01356 #endif
01357
01358