Main Page   Class Hierarchy   Compound List   File List   Compound 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;
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     DB_BLOB_CASCADE_DELETE = 128,  // Used by BLOB macro to mark BLOB fields which should be deleted together with 
00066                                    // containing them record
00067     DB_TIMESTAMP = 256,            // field is used as timestamp (this flag is used by CLI to perfrom proper mapping,
00068                                    // it is not used by C++ API)
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; // next table in the database
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; // number of elements in the array
00929     int4 offs; // offset from the beginning of the record
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; // only for references: name of referenced table
00973 
00977     dbVarying inverse;   // only for relations: name of inverse reference field
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 

Generated on Thu Aug 23 19:35:51 2007 for GigaBASE by doxygen1.2.18