Main Page | Class Hierarchy | Class List | File List | Class Members

class.h

00001 //-< CLASS.H >-------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 26-Nov-2001  K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Metaclass information
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;  // It will work only for 64-bit OS
00033 #else
00034 typedef nat4 oid_t;
00035 #endif
00036 
00040 #if dbDatabaseOffsetBits > 32
00041 typedef nat8 offs_t; // It will work only for 64-bit OS
00042 #else
00043 typedef nat4 offs_t;
00044 #endif
00045 
00046 #include "selection.h"
00047 
00051 enum dbIndexType {
00052     HASHED  = 1, // hash table
00053     INDEXED = 2, // B-tree
00054     CASE_INSENSITIVE = 4, // Index is case insensetive
00055 
00056     DB_FIELD_CASCADE_DELETE = 8,   // Used by OWNER macro, do not set it explicitly
00057     UNIQUE = 16, // should be used in conjunction with HASHED or INDEXED - unique constraint 
00058 
00059     AUTOINCREMENT = 32, // field is assigned automaticall incremented value
00060     OPTIMIZE_DUPLICATES = 64,    // index with lot of duplicate key values
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; // next table in the database
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; // number of elements in the array
00889     int4 offs; // offset from the beginning of the record
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; // only for references: name of referenced table
00933 
00937     dbVarying inverse;   // only for relations: name of inverse reference field
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 

Generated on Thu Feb 12 18:46:27 2004 for GigaBASE by doxygen 1.3.5