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 #define dbDatabaseOffsetBits 32 // 37 - 128Gb, 40 - up to 1 terabyte
00022 #endif
00023
00024 #ifndef dbDatabaseOidBits
00025 #define dbDatabaseOidBits 32
00026 #endif
00027
00031 #if dbDatabaseOidBits > 32
00032 typedef nat8 oid_t;
00033 #else
00034 typedef nat4 oid_t;
00035 #endif
00036
00040 #if dbDatabaseOffsetBits > 32
00041 typedef nat8 offs_t;
00042 #else
00043 typedef nat4 offs_t;
00044 #endif
00045
00046 #include "selection.h"
00047
00051 enum dbIndexType {
00052 HASHED = 1,
00053 INDEXED = 2,
00054 CASE_INSENSITIVE = 4,
00055
00056 DB_FIELD_CASCADE_DELETE = 8,
00057 UNIQUE = 16,
00058
00059 AUTOINCREMENT = 32,
00060 OPTIMIZE_DUPLICATES = 64,
00061
00062 DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00063 };
00064
00068 #define KEY(x, index) \
00069 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00070 sizeof(x), index), x)
00071
00075 #define FIELD(x) KEY(x, 0)
00076
00080 typedef int (*dbUDTComparator)(void*, void*, size_t);
00081
00085 #define UDT(x, index, comparator) \
00086 *dbDescribeRawField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00087 sizeof(x), index), (dbUDTComparator)comparator)
00088
00092 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00093
00097 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00098
00099
00105 #define RELATION(x,inverse) \
00106 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00107 sizeof(x), 0, #inverse), x)
00108
00114 #define INDEXED_RELATION(x,inverse) \
00115 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00116 sizeof(x), INDEXED, #inverse), x)
00117
00123 #define OWNER(x,member) \
00124 *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00125 sizeof(x), DB_FIELD_CASCADE_DELETE, \
00126 #member), x)
00127
00131 #define METHOD(x) \
00132 *dbDescribeMethod(new dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00133
00137 #define SUPERCLASS(x) \
00138 x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00139
00144 #define TYPE_DESCRIPTOR(fields) \
00145 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00146 return &fields; \
00147 } \
00148 static dbTableDescriptor dbDescriptor
00149
00155 #define CLASS_DESCRIPTOR(name, fields) \
00156 typedef name self; \
00157 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00158 return &fields; \
00159 } \
00160 static dbTableDescriptor dbDescriptor
00161
00162 #if (defined(_MSC_VER) && _MSC_VER+0 < 1200) || defined(__MWERKS__)
00163
00166 #if defined(_MSC_VER)
00167 #define TEMPLATE_SPEC
00168 #else
00169 #define TEMPLATE_SPEC template <>
00170 #endif
00171 #define REGISTER_IN(table, database) \
00172 TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00173 { return &table::dbDescriptor; } \
00174 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00175 { return ((table*)0)->dbDescribeComponents(NULL); } \
00176 dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00177 &dbDescribeComponentsOf##table)
00178
00179 #define REGISTER_TEMPLATE_IN(table, database) \
00180 TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00181 { return &table::dbDescriptor; } \
00182 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00183 { return ((table*)0)->dbDescribeComponents(NULL); } \
00184 template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00185 &dbDescribeComponentsOf##table)
00186 #else
00187
00190 #define REGISTER_IN(table, database) \
00191 dbTableDescriptor* dbGetTableDescriptor(table*) \
00192 { return &table::dbDescriptor; } \
00193 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00194 { return ((table*)0)->dbDescribeComponents(NULL); } \
00195 dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00196 &dbDescribeComponentsOf##table)
00197 #define REGISTER_TEMPLATE_IN(table, database) \
00198 dbTableDescriptor* dbGetTableDescriptor(table*) \
00199 { return &table::dbDescriptor; } \
00200 static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00201 { return ((table*)0)->dbDescribeComponents(NULL); } \
00202 template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00203 &dbDescribeComponentsOf##table)
00204 #endif
00205
00210 #define REGISTER(table) REGISTER_IN(table, NULL)
00211 #define REGISTER_TEMPLATE(table) REGISTER_TEMPLATE_IN(table, NULL)
00212
00217 #define DETACHED_TABLE ((dbDatabase*)-1)
00218 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00219 #define REGISTER_TEMPLATE_UNASSIGNED(table) REGISTER_TEMPLATE_IN(table, DETACHED_TABLE)
00220
00221
00222 class dbDatabase;
00223 class dbAnyArray;
00224 class dbTableDescriptor;
00225 class dbAnyMethodTrampoline;
00226 class dbTable;
00227
00231 class GIGABASE_DLL_ENTRY dbFieldDescriptor {
00232 public:
00236 dbFieldDescriptor* next;
00237
00241 dbFieldDescriptor* prev;
00242
00246 dbFieldDescriptor* nextField;
00247
00251 dbFieldDescriptor* nextHashedField;
00252
00256 dbFieldDescriptor* nextIndexedField;
00257
00261 dbFieldDescriptor* nextInverseField;
00262
00266 int fieldNo;
00267
00271 char_t* name;
00272
00276 char_t* longName;
00277
00281 char_t* refTableName;
00282
00286 dbTableDescriptor* refTable;
00287
00291 dbTableDescriptor* defTable;
00292
00296 dbFieldDescriptor* inverseRef;
00297
00301 char_t* inverseRefName;
00302
00306 int type;
00307
00311 int appType;
00312
00316 int indexType;
00317
00321 int dbsOffs;
00322
00326 int appOffs;
00327
00331 dbFieldDescriptor* components;
00332
00336 oid_t hashTable;
00337
00341 oid_t bTree;
00342
00346 size_t dbsSize;
00347
00351 size_t appSize;
00352
00357 size_t alignment;
00358
00362 dbUDTComparator comparator;
00363
00367 enum FieldAttributes {
00368 ComponentOfArray = 0x01,
00369 HasArrayComponents = 0x02,
00370 OneToOneMapping = 0x04,
00371 Updated = 0x08
00372 };
00373 int attr;
00374
00378 int oldDbsType;
00382 int oldDbsOffs;
00386 int oldDbsSize;
00387
00388
00392 dbAnyMethodTrampoline* method;
00393
00397 void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00398
00409 size_t calculateRecordSize(byte* base, size_t offs);
00410
00420 size_t calculateNewRecordSize(byte* base, size_t offs);
00421
00431 size_t convertRecord(byte* dst, byte* src, size_t offs);
00432
00443 int sizeWithoutOneField(dbFieldDescriptor* field,
00444 byte* base, size_t& size);
00445
00455 size_t copyRecordExceptOneField(dbFieldDescriptor* field,
00456 byte* dst, byte* src, size_t offs);
00457
00468 size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
00469
00477 void markUpdatedFields(byte* dst, byte* src);
00478
00486 void fetchRecordFields(byte* dst, byte* src);
00487
00493 dbFieldDescriptor* find(const char_t* name);
00494
00499 dbFieldDescriptor* getFirstComponent() {
00500 return components;
00501 }
00502
00507 dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) {
00508 if (field != NULL) {
00509 field = field->next;
00510 if (field == components) {
00511 return NULL;
00512 }
00513 }
00514 return field;
00515 }
00516
00520 dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00521 dbFieldDescriptor* tail = field.prev;
00522 tail->next = this;
00523 prev->next = &field;
00524 field.prev = prev;
00525 prev = tail;
00526 return *this;
00527 }
00528
00529 void* operator new(size_t size);
00530 void operator delete(void* p);
00531
00535 dbFieldDescriptor& adjustOffsets(long offs);
00536
00546 dbFieldDescriptor(char_t* name, int offs, int size, int indexType,
00547 char_t* inverse = NULL,
00548 dbFieldDescriptor* components = NULL);
00549
00554 dbFieldDescriptor(char_t* name);
00555
00559 ~dbFieldDescriptor();
00560 };
00561
00562
00566 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00567 friend class dbCompiler;
00568 friend class dbDatabase;
00569 friend class dbReplicatedDatabase;
00570 friend class dbTable;
00571 friend class dbAnyCursor;
00572 friend class dbSubSql;
00573 friend class dbParallelQueryContext;
00574 friend class dbServer;
00575 friend class dbAnyContainer;
00576 friend class dbColumnBinding;
00577 friend class dbFieldDescriptor;
00578 friend class dbSelection;
00579 friend class dbCLI;
00580 protected:
00584 dbTableDescriptor* next;
00585 static dbTableDescriptor* chain;
00586
00590 dbTableDescriptor* nextDbTable;
00591
00595 char_t* name;
00596
00600 oid_t tableId;
00601
00605 dbFieldDescriptor* columns;
00606
00610 dbFieldDescriptor* hashedFields;
00611
00615 dbFieldDescriptor* indexedFields;
00616
00620 dbFieldDescriptor* inverseFields;
00621
00625 dbFieldDescriptor* firstField;
00626
00630 dbFieldDescriptor** nextFieldLink;
00631
00635 dbDatabase* db;
00636
00640 bool fixedDatabase;
00641
00645 bool isStatic;
00646
00652 dbTableDescriptor* cloneOf;
00653
00657 size_t appSize;
00658
00662 size_t fixedSize;
00663
00667 size_t nFields;
00668
00672 size_t nColumns;
00673
00677 oid_t firstRow;
00678
00682 oid_t lastRow;
00683
00687 size_t nRows;
00688
00692 int4 autoincrementCount;
00693
00697 dbTableDescriptor* nextBatch;
00698
00702 bool isInBatch;
00703
00707 dbSelection batch;
00708
00709
00710
00714 typedef dbFieldDescriptor* (*describeFunc)();
00715 describeFunc describeComponentsFunc;
00716
00720 size_t totalNamesLength();
00721
00733 int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00734 char_t const* prefix, int offs,
00735 int indexMask, int& attr);
00736
00745 dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00746 int prefixLen, int& attr);
00750 dbTableDescriptor* clone();
00751
00752 public:
00756 static int initialAutoincrementCount;
00757
00758
00762 dbTableDescriptor* getNextTable() {
00763 return nextDbTable;
00764 }
00765
00769 dbFieldDescriptor* findSymbol(char_t const* name);
00770
00774 dbFieldDescriptor* find(char_t const* name);
00775
00780 dbFieldDescriptor* getFirstField() {
00781 return columns;
00782 }
00783
00784
00790 dbFieldDescriptor* getNextField(dbFieldDescriptor* field) {
00791 if (field != NULL) {
00792 field = field->next;
00793 if (field == columns) {
00794 return NULL;
00795 }
00796 }
00797 return field;
00798 }
00799
00803 char_t* getName() {
00804 return name;
00805 }
00806
00807
00814 bool equal(dbTable* table);
00815
00824 bool match(dbTable* table, bool confirmDeleteColumns);
00825
00831 void checkRelationship();
00832
00837 dbDatabase* getDatabase() { return db; }
00838
00843 void storeInDatabase(dbTable* table);
00844
00849 void setFlags();
00850
00851
00855 static void cleanup();
00856
00857
00862 dbTableDescriptor(dbTable* table);
00863
00872 dbTableDescriptor(char_t* tableName,
00873 dbDatabase* db,
00874 size_t objSize,
00875 describeFunc func,
00876 dbTableDescriptor* original = NULL);
00877
00881 ~dbTableDescriptor();
00882 };
00883
00887 struct dbVarying {
00888 nat4 size;
00889 int4 offs;
00890 };
00891
00895 struct dbField {
00896 enum FieldTypes {
00897 tpBool,
00898 tpInt1,
00899 tpInt2,
00900 tpInt4,
00901 tpInt8,
00902 tpReal4,
00903 tpReal8,
00904 tpString,
00905 tpReference,
00906 tpArray,
00907 tpMethodBool,
00908 tpMethodInt1,
00909 tpMethodInt2,
00910 tpMethodInt4,
00911 tpMethodInt8,
00912 tpMethodReal4,
00913 tpMethodReal8,
00914 tpMethodString,
00915 tpMethodReference,
00916 tpStructure,
00917 tpRawBinary,
00918 tpStdString,
00919 tpMfcString,
00920 tpRectangle,
00921 tpUnknown
00922 };
00923
00927 dbVarying name;
00928
00932 dbVarying tableName;
00933
00937 dbVarying inverse;
00938
00942 int4 type;
00943
00947 int4 offset;
00948
00952 nat4 size;
00953
00957 oid_t hashTable;
00958
00962 oid_t bTree;
00963 };
00964
00965
00969 class dbRecord {
00970 public:
00974 nat4 size;
00975
00979 oid_t next;
00980
00984 oid_t prev;
00985 };
00986
00987
00991 class dbTable : public dbRecord {
00992 public:
00996 dbVarying name;
00997
01001 dbVarying fields;
01002
01006 nat4 fixedSize;
01007
01011 nat4 nRows;
01012
01016 nat4 nColumns;
01017
01021 oid_t firstRow;
01022
01026 oid_t lastRow;
01027 #ifdef AUTOINCREMENT_SUPPORT
01028
01031 nat4 count;
01032 #endif
01033 };
01034
01035 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01036 {
01037 fd->type = fd->appType = dbField::tpRawBinary;
01038 fd->alignment = 1;
01039 fd->comparator = comparator;
01040 return fd;
01041 }
01042
01043 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01044 {
01045 fd->type = fd->appType = dbField::tpInt1;
01046 return fd;
01047 }
01048 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01049 {
01050 fd->type = fd->appType = dbField::tpInt2;
01051 return fd;
01052 }
01053 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01054 {
01055 fd->type = fd->appType = dbField::tpInt4;
01056 return fd;
01057 }
01058 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01059 {
01060 fd->type = fd->appType = dbField::tpInt8;
01061 return fd;
01062 }
01063 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01064 {
01065 fd->type = fd->appType = dbField::tpInt1;
01066 return fd;
01067 }
01068 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01069 {
01070 fd->type = fd->appType = dbField::tpInt2;
01071 return fd;
01072 }
01073 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01074 {
01075 fd->type = fd->appType = dbField::tpInt4;
01076 return fd;
01077 }
01078 #if SIZEOF_LONG != 8
01079 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01080 {
01081 fd->type = fd->appType = dbField::tpInt4;
01082 return fd;
01083 }
01084 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01085 {
01086 fd->type = fd->appType = dbField::tpInt4;
01087 return fd;
01088 }
01089 #endif
01090 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01091 {
01092 fd->type = fd->appType = dbField::tpInt8;
01093 return fd;
01094 }
01095 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01096 {
01097 fd->type = fd->appType = dbField::tpBool;
01098 return fd;
01099 }
01100 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01101 {
01102 fd->type = fd->appType = dbField::tpReal4;
01103 return fd;
01104 }
01105 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01106 {
01107 fd->type = fd->appType = dbField::tpReal8;
01108 return fd;
01109 }
01110 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01111 {
01112 fd->type = fd->appType = dbField::tpRectangle;
01113 fd->alignment = sizeof(coord_t);
01114 return fd;
01115 }
01116
01117 #ifdef USE_STD_STRING
01118 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01119 {
01120 fd->type = dbField::tpString;
01121 fd->appType = dbField::tpStdString;
01122 fd->dbsSize = sizeof(dbVarying);
01123 fd->alignment = 4;
01124 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01125 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01126 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01127 return fd;
01128 }
01129 #endif
01130 #ifdef USE_MFC_STRING
01131 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01132 {
01133 fd->type = dbField::tpString;
01134 fd->appType = dbField::tpMfcString;
01135 fd->dbsSize = sizeof(dbVarying);
01136 fd->alignment = 4;
01137 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01138 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01139 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01140 return fd;
01141 }
01142 #endif
01143
01144 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01145 {
01146 fd->type = fd->appType = dbField::tpString;
01147 fd->dbsSize = sizeof(dbVarying);
01148 fd->alignment = 4;
01149 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01150 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01151 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01152 return fd;
01153 }
01154 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01155 {
01156 fd->type = fd->appType = dbField::tpString;
01157 fd->dbsSize = sizeof(dbVarying);
01158 fd->alignment = 4;
01159 fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01160 fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01161 fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01162 return fd;
01163 }
01164
01165
01166 template<class T>
01167 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01168 {
01169 fd->type = fd->appType = dbField::tpStructure;
01170 fd->components = x.dbDescribeComponents(fd);
01171 return fd;
01172 }
01173
01174
01178 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01179 public:
01180 dbFieldDescriptor* cls;
01181
01187 virtual void invoke(byte* data, void* result) = 0;
01188
01195 virtual dbAnyMethodTrampoline* optimize() = 0;
01196
01201 dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01202
01206 virtual~dbAnyMethodTrampoline();
01207
01208 void* operator new(size_t size);
01209 void operator delete(void* p);
01210 };
01211
01212 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || \
01213 (__SUNPRO_CC >= 0x520 && __SUNPRO_CC_COMPAT == 5)
01214
01217 template<class T, class R>
01218 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01219 public:
01220 typedef R (T::*mfunc)();
01221
01222 mfunc method;
01223 dbFieldDescriptor* cls;
01224 bool optimized;
01225
01226 void invoke(byte* data, void* result) {
01227 if (optimized) {
01228 *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01229 } else {
01230 T rec;
01231 cls->components->fetchRecordFields((byte*)&rec, data);
01232 *(R*)result = (rec.*method)();
01233 }
01234 }
01235 dbAnyMethodTrampoline* optimize() {
01236 optimized = true;
01237 return this;
01238 }
01239
01240 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01241 : dbAnyMethodTrampoline(fd), method(f), cls(fd), optimized(false) {}
01242 };
01243
01244 #else
01245
01249 template<class T, class R>
01250 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01251 public:
01252 typedef R (T::*mfunc)();
01253 mfunc method;
01254
01255 void invoke(byte* data, void* result) {
01256 T rec;
01257 cls->components->fetchRecordFields((byte*)&rec, data);
01258 *(R*)result = (rec.*method)();
01259 }
01260 dbAnyMethodTrampoline* optimize();
01261
01262 dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01263 : dbAnyMethodTrampoline(fd), method(f) {}
01264 };
01265
01266 template<class T, class R>
01267 class dbMethodFastTrampoline : public dbMethodTrampoline<T,R> {
01268 public:
01269 void invoke(byte* data, void* result) {
01270 *(R*)result = (((T*)(data + cls->dbsOffs))->*method)();
01271 }
01272 dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt)
01273 : dbMethodTrampoline<T,R>(mt->cls, mt->method) {
01274 delete mt;
01275 }
01276 };
01277
01278 template<class T, class R>
01279 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01280 return new dbMethodFastTrampoline<T,R>(this);
01281 }
01282
01283 #endif
01284 template<class T, class R>
01285 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01286 {
01287 R ret;
01288 dbDescribeField(fd, ret);
01289 assert(fd->type <= dbField::tpReference);
01290 fd->appType = fd->type += dbField::tpMethodBool;
01291 fd->method = new dbMethodTrampoline<T,R>(fd, p);
01292 return fd;
01293 }
01294
01295 END_GIGABASE_NAMESPACE
01296
01297 #endif
01298
01299