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 #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;  // It will work only for 64-bit OS
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, // hash table
00057     INDEXED = 2, // B-tree
00058     CASE_INSENSITIVE = 4, // Index is case insensitive
00059 
00060     DB_FIELD_CASCADE_DELETE = 8,   // Used by OWNER macro, do not set it explicitly
00061     UNIQUE = 16, // should be used in conjunction with HASHED or INDEXED - unique constraint 
00062 
00063     AUTOINCREMENT = 32, // field is assigned automaticall incremented value
00064     OPTIMIZE_DUPLICATES = 64,    // index with lot of duplicate key values
00065 
00066     DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00067 };
00068 
00072 #define KEY(x, index) \
00073     *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00074                                            sizeof(x), index), x)
00075 
00079 #define FIELD(x) KEY(x, 0)
00080 
00084 typedef int (*dbUDTComparator)(void*, void*, size_t);
00085 
00089 #define UDT(x, index, comparator) \
00090     *dbDescribeRawField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00091                                                 sizeof(x), index), (dbUDTComparator)comparator)
00092 
00096 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00097 
00101 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00102 
00103 
00109 #define RELATION(x,inverse) \
00110     *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00111                                            sizeof(x), 0, STRLITERAL(#inverse)), x)
00112 
00118 #define INDEXED_RELATION(x,inverse) \
00119     *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00120                                            sizeof(x), INDEXED, STRLITERAL(#inverse)), x)
00121  
00127 #define OWNER(x,member) \
00128     *dbDescribeField(new dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00129                                              sizeof(x), DB_FIELD_CASCADE_DELETE, \
00130                                              #member), x)
00131 
00135 #define METHOD(x) \
00136     *dbDescribeMethod(new dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00137 
00141 #define SUPERCLASS(x) \
00142     x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00143 
00148 #define TYPE_DESCRIPTOR(fields) \
00149     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00150         return &fields; \
00151     } \
00152     static dbTableDescriptor dbDescriptor
00153 
00159 #define CLASS_DESCRIPTOR(name, fields) \
00160     typedef name self; \
00161     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00162         return &fields; \
00163     } \
00164     static dbTableDescriptor dbDescriptor
00165 
00166 #if (defined(_MSC_VER) && _MSC_VER+0 < 1200) || defined(__MWERKS__)
00167 
00170 #if defined(_MSC_VER)
00171 #define TEMPLATE_SPEC
00172 #else
00173 #define TEMPLATE_SPEC  template <>
00174 #endif
00175 #define REGISTER_IN(table, database) \
00176     TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00177       { return &table::dbDescriptor; }              \
00178     static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00179      { return ((table*)0)->dbDescribeComponents(NULL); }     \
00180     dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00181                                           &dbDescribeComponentsOf##table)
00182 
00183 #define REGISTER_TEMPLATE_IN(table, database) \
00184     TEMPLATE_SPEC dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00185       { return &table::dbDescriptor; }              \
00186     static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00187      { return ((table*)0)->dbDescribeComponents(NULL); }     \
00188     template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00189                                           &dbDescribeComponentsOf##table)
00190 #else
00191 
00194 #define REGISTER_IN(table, database) \
00195     dbTableDescriptor* dbGetTableDescriptor(table*) \
00196       { return &table::dbDescriptor; }              \
00197     static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00198       { return ((table*)0)->dbDescribeComponents(NULL); }     \
00199     dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00200                                           &dbDescribeComponentsOf##table)
00201 #define REGISTER_TEMPLATE_IN(table, database) \
00202     dbTableDescriptor* dbGetTableDescriptor(table*) \
00203       { return &table::dbDescriptor; }              \
00204     static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00205       { return ((table*)0)->dbDescribeComponents(NULL); }     \
00206     template<> dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00207                                           &dbDescribeComponentsOf##table)
00208 #endif
00209 
00214 #define REGISTER(table) REGISTER_IN(table, NULL)
00215 #define REGISTER_TEMPLATE(table) REGISTER_TEMPLATE_IN(table, NULL)
00216 
00221 #define DETACHED_TABLE ((dbDatabase*)-1)
00222 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00223 #define REGISTER_TEMPLATE_UNASSIGNED(table) REGISTER_TEMPLATE_IN(table, DETACHED_TABLE)
00224 
00225 
00226 class dbDatabase;
00227 class dbAnyArray;
00228 class dbTableDescriptor;
00229 class dbAnyMethodTrampoline;
00230 class dbTable;
00231 
00235 class GIGABASE_DLL_ENTRY dbFieldDescriptor {
00236   public:
00240     dbFieldDescriptor* next;
00241 
00245     dbFieldDescriptor* prev;
00246 
00250     dbFieldDescriptor* nextField;
00251 
00255     dbFieldDescriptor* nextHashedField;
00256 
00260     dbFieldDescriptor* nextIndexedField;
00261 
00265     dbFieldDescriptor* nextInverseField;
00266 
00270     int                fieldNo;
00271     
00275     char_t*            name;
00276 
00280     char_t*            longName;
00281 
00285     char_t*            refTableName;
00286 
00290     dbTableDescriptor* refTable;
00291 
00295     dbTableDescriptor* defTable;
00296 
00300     dbFieldDescriptor* inverseRef;
00301 
00305     char_t*            inverseRefName;
00306 
00310     int                type;
00311 
00315     int                appType;
00316 
00320     int                indexType;
00321 
00325     int                dbsOffs;
00326 
00330     int                appOffs;
00331 
00335     dbFieldDescriptor* components;
00336 
00340     oid_t              hashTable;
00341 
00345     oid_t              bTree;
00346 
00350     size_t             dbsSize;
00351     
00355     size_t             appSize;
00356 
00361     size_t             alignment;
00362 
00366     dbUDTComparator    comparator;
00367 
00371     enum FieldAttributes {
00372         ComponentOfArray   = 0x01,
00373         HasArrayComponents = 0x02,
00374         OneToOneMapping    = 0x04,
00375         Updated            = 0x08
00376     };
00377     int                attr;
00378 
00382     int                oldDbsType;
00386     int                oldDbsOffs;
00390     int                oldDbsSize;
00391 
00392 
00396     dbAnyMethodTrampoline* method;
00397 
00401     void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00402 
00413     size_t calculateRecordSize(byte* base, size_t offs);
00414 
00424     size_t calculateNewRecordSize(byte* base, size_t offs);
00425     
00435     size_t convertRecord(byte* dst, byte* src, size_t offs);
00436 
00447     int    sizeWithoutOneField(dbFieldDescriptor* field,
00448                                byte* base, size_t& size);
00449 
00459     size_t copyRecordExceptOneField(dbFieldDescriptor* field,
00460                                     byte* dst, byte* src, size_t offs);
00461 
00472     size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
00473 
00481     void markUpdatedFields(byte* dst, byte* src);
00482 
00490      void fetchRecordFields(byte* dst, byte* src);
00491 
00497     dbFieldDescriptor* find(const char_t* name);
00498 
00503     dbFieldDescriptor* getFirstComponent() { 
00504         return components;
00505     }
00506 
00511     dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) { 
00512         if (field != NULL) { 
00513             field = field->next;
00514             if (field == components) { 
00515                 return NULL;
00516             }
00517         }
00518         return field;
00519     }
00520 
00524     dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00525         dbFieldDescriptor* tail = field.prev;
00526         tail->next = this;
00527         prev->next = &field;
00528         field.prev = prev;
00529         prev = tail;
00530         return *this;
00531     }
00532 
00533     void* operator new(size_t size);
00534     void  operator delete(void* p);
00535 
00539     dbFieldDescriptor& adjustOffsets(long offs);
00540 
00550     dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00551                       char_t const* inverse = NULL,
00552                       dbFieldDescriptor* components = NULL);
00553 
00558     dbFieldDescriptor(char_t const* name);
00559 
00563     ~dbFieldDescriptor();
00564 };
00565 
00566 
00570 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00571     friend class dbCompiler;
00572     friend class dbDatabase;
00573     friend class dbReplicatedDatabase;
00574     friend class dbTable;
00575     friend class dbAnyCursor;
00576     friend class dbSubSql;
00577     friend class dbParallelQueryContext;
00578     friend class dbServer;
00579     friend class dbAnyContainer;
00580     friend class dbColumnBinding;
00581     friend class dbFieldDescriptor;
00582     friend class dbSelection;
00583     friend class dbTableIterator;
00584     friend class dbCLI;
00585   protected:
00589     dbTableDescriptor*  next;
00590     static dbTableDescriptor* chain;
00591 
00595     dbTableDescriptor*  nextDbTable; // next table in the database
00596 
00600     char_t*             name;
00601 
00605     oid_t               tableId;
00606 
00610     dbFieldDescriptor*  columns;
00611     
00615     dbFieldDescriptor*  hashedFields;
00616 
00620     dbFieldDescriptor*  indexedFields;
00621 
00625     dbFieldDescriptor*  inverseFields;
00626 
00630     dbFieldDescriptor*  firstField;
00631 
00635     dbFieldDescriptor** nextFieldLink;
00636 
00640     dbDatabase*         db;
00641     
00645     bool                fixedDatabase;
00646 
00650     bool                isStatic;
00651     
00657     dbTableDescriptor*  cloneOf;
00658 
00662     size_t              appSize;
00663 
00667     size_t              fixedSize;
00668 
00672     size_t              nFields;
00673 
00677     size_t              nColumns;
00678 
00682     oid_t               firstRow;
00683 
00687     oid_t               lastRow;
00688     
00692     size_t              nRows;
00693 
00697     int4                autoincrementCount;
00698 
00702     dbTableDescriptor*        nextBatch;
00703 
00707     bool                      isInBatch;
00708 
00712     dbSelection               batch;
00713 
00714 
00715 
00719     typedef dbFieldDescriptor* (*describeFunc)();
00720     describeFunc        describeComponentsFunc;
00721 
00725     size_t              totalNamesLength();
00726 
00738     int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00739                                   char_t const* prefix, int offs,
00740                                   int indexMask, int& attr);
00741 
00750     dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00751                                        int prefixLen, int& attr);
00755     dbTableDescriptor* clone();
00756 
00757   public:
00761     static int initialAutoincrementCount;
00762 
00763 
00767     dbTableDescriptor* getNextTable() { 
00768         return nextDbTable;
00769     }
00770 
00774     dbFieldDescriptor* findSymbol(char_t const* name);
00775 
00779     dbFieldDescriptor* find(char_t const* name);
00780 
00785      dbFieldDescriptor* getFirstField() { 
00786         return columns;
00787     }
00788 
00789 
00795     dbFieldDescriptor* getNextField(dbFieldDescriptor* field) { 
00796         if (field != NULL) { 
00797             field = field->next;
00798             if (field == columns) { 
00799                 return NULL;
00800             }
00801         }
00802         return field;
00803     }
00804 
00808     char_t* getName() { 
00809         return name;
00810     }
00811 
00815     size_t size() { 
00816         return appSize;
00817     }
00818 
00825      bool equal(dbTable* table);
00826 
00835     bool match(dbTable* table, bool confirmDeleteColumns);
00836 
00842     void checkRelationship();
00843 
00848     dbDatabase* getDatabase() { return db; }
00849 
00854     void storeInDatabase(dbTable* table);
00855 
00860     void setFlags();
00861 
00862 
00866     static void cleanup();
00867 
00868 
00873     dbTableDescriptor(dbTable* table);
00874 
00883     dbTableDescriptor(char_t const*      tableName, 
00884                       dbDatabase*        db, 
00885                       size_t             objSize,
00886                       describeFunc       func,
00887                       dbTableDescriptor* original = NULL);
00888 
00892      ~dbTableDescriptor();
00893 };
00894 
00898 struct dbVarying {
00899     nat4 size; // number of elements in the array
00900     int4 offs; // offset from the beginning of the record
00901 };
00902 
00906 struct dbField {
00907     enum FieldTypes {
00908         tpBool,
00909         tpInt1,
00910         tpInt2,
00911         tpInt4,
00912         tpInt8,
00913         tpReal4,
00914         tpReal8,
00915         tpString,
00916         tpReference,
00917         tpArray,
00918         tpMethodBool,
00919         tpMethodInt1,
00920         tpMethodInt2,
00921         tpMethodInt4,
00922         tpMethodInt8,
00923         tpMethodReal4,
00924         tpMethodReal8,
00925         tpMethodString,
00926         tpMethodReference,
00927         tpStructure,
00928         tpRawBinary,
00929         tpStdString,
00930         tpMfcString,
00931         tpRectangle,
00932         tpUnknown
00933     };
00934 
00938     dbVarying name;
00939 
00943     dbVarying tableName; // only for references: name of referenced table
00944 
00948     dbVarying inverse;   // only for relations: name of inverse reference field
00949     
00953     int4      type;
00954 
00958     int4      offset;
00959 
00963     nat4      size;
00964 
00968     oid_t     hashTable;
00969 
00973     oid_t     bTree;
00974 };
00975 
00976 
00980 class dbRecord {
00981   public:
00985     nat4   size;
00986 
00990     oid_t  next;
00991 
00995     oid_t  prev;
00996 };
00997 
00998 
01002 class dbTable : public dbRecord {
01003   public:
01007     dbVarying name;
01008     
01012     dbVarying fields;
01013 
01017     nat4      fixedSize;
01018 
01022     nat4      nRows;
01023 
01027     nat4      nColumns;
01028     
01032     oid_t     firstRow;
01033 
01037     oid_t     lastRow;
01038 #ifdef AUTOINCREMENT_SUPPORT
01039 
01042     nat4      count;
01043 #endif
01044 };
01045 
01046 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01047 {
01048     fd->type = fd->appType = dbField::tpRawBinary;
01049     fd->alignment = 1;
01050     fd->comparator = comparator;
01051     return fd;
01052 }
01053 
01054 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01055 {
01056     fd->type = fd->appType = dbField::tpInt1;
01057     return fd;
01058 }
01059 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01060 {
01061     fd->type = fd->appType = dbField::tpInt2;
01062     return fd;
01063 }
01064 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01065 {
01066     fd->type = fd->appType = dbField::tpInt4;
01067     return fd;
01068 }
01069 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01070 {
01071     fd->type = fd->appType = dbField::tpInt8;
01072     return fd;
01073 }
01074 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01075 {
01076     fd->type = fd->appType = dbField::tpInt1;
01077     return fd;
01078 }
01079 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01080 {
01081     fd->type = fd->appType = dbField::tpInt2;
01082     return fd;
01083 }
01084 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01085 {
01086     fd->type = fd->appType = dbField::tpInt4;
01087     return fd;
01088 }
01089 #if SIZEOF_LONG != 8
01090 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01091 {
01092     fd->type = fd->appType = dbField::tpInt4;
01093     return fd;
01094 }
01095 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01096 {
01097     fd->type = fd->appType = dbField::tpInt4;
01098     return fd;
01099 }
01100 #endif
01101 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01102 {
01103     fd->type = fd->appType = dbField::tpInt8;
01104     return fd;
01105 }
01106 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01107 {
01108     fd->type = fd->appType = dbField::tpBool;
01109     return fd;
01110 }
01111 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01112 {
01113     fd->type = fd->appType = dbField::tpReal4;
01114     return fd;
01115 }
01116 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01117 {
01118     fd->type = fd->appType = dbField::tpReal8;
01119     return fd;
01120 }
01121 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01122 {
01123     fd->type = fd->appType = dbField::tpRectangle;
01124     fd->alignment = sizeof(coord_t);
01125     return fd;
01126 }
01127 
01128 #ifdef USE_STD_STRING
01129 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01130 {
01131     fd->type = dbField::tpString;
01132     fd->appType = dbField::tpStdString;
01133     fd->dbsSize = sizeof(dbVarying);
01134     fd->alignment = 4;
01135     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01136     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01137     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01138     return fd;
01139 }
01140 #endif
01141 #ifdef USE_MFC_STRING
01142 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01143 {
01144     fd->type = dbField::tpString;
01145     fd->appType = dbField::tpMfcString;
01146     fd->dbsSize = sizeof(dbVarying);
01147     fd->alignment = 4;
01148     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01149     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01150     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01151     return fd;
01152 }
01153 #endif
01154 
01155 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01156 {
01157     fd->type = fd->appType = dbField::tpString;
01158     fd->dbsSize = sizeof(dbVarying);
01159     fd->alignment = 4;
01160     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01161     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01162     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01163     return fd;
01164 }
01165 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01166 {
01167     fd->type = fd->appType = dbField::tpString;
01168     fd->dbsSize = sizeof(dbVarying);
01169     fd->alignment = 4;
01170     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01171     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01172     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01173     return fd;
01174 }
01175 
01176 
01177 template<class T>
01178 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01179 {
01180     fd->type = fd->appType = dbField::tpStructure;
01181     fd->components = x.dbDescribeComponents(fd);
01182     return fd;
01183 }
01184 
01185 
01189 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01190   public:
01191     dbFieldDescriptor* cls;
01192 
01198     virtual void invoke(byte* data, void* result) = 0;
01199 
01206     virtual dbAnyMethodTrampoline* optimize() = 0;
01207 
01212     dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01213     
01217     virtual~dbAnyMethodTrampoline();
01218 
01219     void* operator new(size_t size);
01220     void  operator delete(void* p);
01221 };
01222 
01223 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x520 && __SUNPRO_CC_COMPAT == 5)
01224 
01227 template<class T, class R>
01228 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01229   public:
01230     typedef R (T::*mfunc)();
01231 
01232     mfunc              method;
01233     dbFieldDescriptor* cls;
01234     bool               optimized;
01235 
01236     void invoke(byte* data, void* result) {
01237         if (optimized) { 
01238             *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01239         } else { 
01240             T rec;
01241             this->cls->components->fetchRecordFields((byte*)&rec, data);
01242             *(R*)result = (rec.*method)();
01243         }
01244     }
01245     dbAnyMethodTrampoline* optimize() { 
01246         optimized = true;
01247         return this;
01248     }
01249 
01250     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01251     : dbAnyMethodTrampoline(fd)
01252     {
01253         this->method = f;
01254         this->cls = fd;
01255         this->optimized = false;
01256     }
01257 };
01258 
01259 #else
01260 
01264 template<class T, class R>
01265 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01266   public:
01267     typedef R (T::*mfunc)();
01268     mfunc method;
01269 
01270     void invoke(byte* data, void* result) {
01271         T rec;
01272         this->cls->components->fetchRecordFields((byte*)&rec, data);
01273         *(R*)result = (rec.*method)();
01274     }
01275     dbAnyMethodTrampoline* optimize();
01276 
01277     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01278     : dbAnyMethodTrampoline(fd), method(f) {}
01279 };
01280 
01281 template<class T, class R>
01282 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01283     typedef R (T::*mfunc)();
01284     mfunc method;
01285   public:
01286     dbAnyMethodTrampoline* optimize() { 
01287         return this;
01288     }
01289     void invoke(byte* data, void* result) {
01290         *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01291     }
01292     dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
01293     : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01294         delete mt;
01295     }
01296 };
01297 
01298 template<class T, class R>
01299 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01300     return new dbMethodFastTrampoline<T,R>(this);
01301 }
01302 
01303 #endif
01304 template<class T, class R>
01305 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01306 {
01307     R ret;
01308     dbDescribeField(fd, ret);
01309     assert(fd->type <= dbField::tpReference);
01310     fd->appType = fd->type += dbField::tpMethodBool;
01311     fd->method = new dbMethodTrampoline<T,R>(fd, p);
01312     return fd;
01313 }
01314 
01315 END_GIGABASE_NAMESPACE
01316 
01317 #endif
01318 
01319 

Generated on Thu Nov 24 23:14:29 2005 for GigaBASE by doxygen 1.3.5