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 
00484     size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
00485 
00493     void markUpdatedFields(byte* dst, byte* src);
00494 
00502      void fetchRecordFields(byte* dst, byte* src);
00503 
00509     dbFieldDescriptor* find(const char_t* name);
00510 
00515     dbFieldDescriptor* getFirstComponent() { 
00516         return components;
00517     }
00518 
00523     dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) { 
00524         if (field != NULL) { 
00525             field = field->next;
00526             if (field == components) { 
00527                 return NULL;
00528             }
00529         }
00530         return field;
00531     }
00532 
00536     dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00537         dbFieldDescriptor* tail = field.prev;
00538         tail->next = this;
00539         prev->next = &field;
00540         field.prev = prev;
00541         prev = tail;
00542         return *this;
00543     }
00544 
00545     void* operator new(size_t size);
00546     void  operator delete(void* p);
00547 
00551     dbFieldDescriptor& adjustOffsets(long offs);
00552 
00562     dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00563                       char_t const* inverse = NULL,
00564                       dbFieldDescriptor* components = NULL);
00565 
00570     dbFieldDescriptor(char_t const* name);
00571 
00575     ~dbFieldDescriptor();
00576 };
00577 
00578 
00582 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00583     friend class dbCompiler;
00584     friend class dbDatabase;
00585     friend class dbReplicatedDatabase;
00586     friend class dbTable;
00587     friend class dbAnyCursor;
00588     friend class dbSubSql;
00589     friend class dbParallelQueryContext;
00590     friend class dbServer;
00591     friend class dbAnyContainer;
00592     friend class dbColumnBinding;
00593     friend class dbFieldDescriptor;
00594     friend class dbSelection;
00595     friend class dbTableIterator;
00596     friend class dbCLI;
00597   protected:
00601     dbTableDescriptor*  next;
00602     static dbTableDescriptor* chain;
00603 
00607     dbTableDescriptor*  nextDbTable; // next table in the database
00608 
00612     char_t*             name;
00613 
00617     oid_t               tableId;
00618 
00622     dbFieldDescriptor*  columns;
00623     
00627     dbFieldDescriptor*  hashedFields;
00628 
00632     dbFieldDescriptor*  indexedFields;
00633 
00637     dbFieldDescriptor*  inverseFields;
00638 
00642     dbFieldDescriptor*  firstField;
00643 
00647     dbFieldDescriptor** nextFieldLink;
00648 
00652     dbDatabase*         db;
00653     
00657     bool                fixedDatabase;
00658 
00662     bool                isStatic;
00663     
00669     dbTableDescriptor*  cloneOf;
00670 
00674     size_t              appSize;
00675 
00679     size_t              fixedSize;
00680 
00684     size_t              nFields;
00685 
00689     size_t              nColumns;
00690 
00694     oid_t               firstRow;
00695 
00699     oid_t               lastRow;
00700     
00704     size_t              nRows;
00705 
00709     int4                autoincrementCount;
00710 
00714     dbTableDescriptor*        nextBatch;
00715 
00719     bool                      isInBatch;
00720 
00724     dbSelection               batch;
00725 
00729     int                       transactionId;
00730 
00734     typedef dbFieldDescriptor* (*describeFunc)();
00735     describeFunc        describeComponentsFunc;
00736 
00740     size_t              totalNamesLength();
00741 
00753     int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00754                                   char_t const* prefix, int offs,
00755                                   int indexMask, int& attr);
00756 
00765     dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00766                                        int prefixLen, int& attr);
00770     dbTableDescriptor* clone();
00771 
00772   public:
00776     static int initialAutoincrementCount;
00777 
00778 
00782     dbTableDescriptor* getNextTable() { 
00783         return nextDbTable;
00784     }
00785 
00789     dbFieldDescriptor* findSymbol(char_t const* name);
00790 
00794     dbFieldDescriptor* find(char_t const* name);
00795 
00800      dbFieldDescriptor* getFirstField() { 
00801         return columns;
00802     }
00803 
00808     int getLastValueOfAutoincrementCount() const { 
00809         return autoincrementCount;
00810     }
00811 
00817     dbFieldDescriptor* getNextField(dbFieldDescriptor* field) { 
00818         if (field != NULL) { 
00819             field = field->next;
00820             if (field == columns) { 
00821                 return NULL;
00822             }
00823         }
00824         return field;
00825     }
00826 
00830     char_t* getName() { 
00831         return name;
00832     }
00833 
00837     size_t size() { 
00838         return appSize;
00839     }
00840 
00847      bool equal(dbTable* table);
00848 
00857     bool match(dbTable* table, bool confirmDeleteColumns);
00858 
00864     void checkRelationship();
00865 
00870     dbDatabase* getDatabase() { return db; }
00871 
00876     void storeInDatabase(dbTable* table);
00877 
00882     void setFlags();
00883 
00884 
00888     static void cleanup();
00889 
00890 
00895     dbTableDescriptor(dbTable* table);
00896 
00905     dbTableDescriptor(char_t const*      tableName, 
00906                       dbDatabase*        db, 
00907                       size_t             objSize,
00908                       describeFunc       func,
00909                       dbTableDescriptor* original = NULL);
00910 
00914      ~dbTableDescriptor();
00915 };
00916 
00920 struct dbVarying {
00921     nat4 size; // number of elements in the array
00922     int4 offs; // offset from the beginning of the record
00923 };
00924 
00928 struct dbField {
00929     enum FieldTypes {
00930         tpBool,
00931         tpInt1,
00932         tpInt2,
00933         tpInt4,
00934         tpInt8,
00935         tpReal4,
00936         tpReal8,
00937         tpString,
00938         tpReference,
00939         tpArray,
00940         tpMethodBool,
00941         tpMethodInt1,
00942         tpMethodInt2,
00943         tpMethodInt4,
00944         tpMethodInt8,
00945         tpMethodReal4,
00946         tpMethodReal8,
00947         tpMethodString,
00948         tpMethodReference,
00949         tpStructure,
00950         tpRawBinary,
00951         tpStdString,
00952         tpMfcString,
00953         tpRectangle,
00954         tpUnknown
00955     };
00956 
00960     dbVarying name;
00961 
00965     dbVarying tableName; // only for references: name of referenced table
00966 
00970     dbVarying inverse;   // only for relations: name of inverse reference field
00971     
00975 #ifdef OLD_FIELD_DESCRIPTOR_FORMAT
00976     int4      type;
00977 #else 
00978 #if BYTE_ORDER == BIG_ENDIAN
00979     int4      flags : 24;
00980     int4      type  : 8;
00981 #else
00982     int4      type  : 8;
00983     int4      flags : 24;
00984 #endif
00985 #endif
00986 
00990     int4      offset;
00991 
00995     nat4      size;
00996 
01000     oid_t     hashTable;
01001 
01005     oid_t     bTree;
01006 };
01007 
01008 
01012 class dbRecord {
01013   public:
01017     nat4   size;
01018 
01022     oid_t  next;
01023 
01027     oid_t  prev;
01028 };
01029 
01030 
01034 class dbTable : public dbRecord {
01035   public:
01039     dbVarying name;
01040     
01044     dbVarying fields;
01045 
01049     nat4      fixedSize;
01050 
01054     nat4      nRows;
01055 
01059     nat4      nColumns;
01060     
01064     oid_t     firstRow;
01065 
01069     oid_t     lastRow;
01070 #ifdef AUTOINCREMENT_SUPPORT
01071 
01074     nat4      count;
01075 #endif
01076 };
01077 
01078 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01079 {
01080     fd->type = fd->appType = dbField::tpRawBinary;
01081     fd->alignment = 1;
01082     fd->comparator = comparator;
01083     return fd;
01084 }
01085 
01086 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01087 {
01088     fd->type = fd->appType = dbField::tpInt1;
01089     return fd;
01090 }
01091 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01092 {
01093     fd->type = fd->appType = dbField::tpInt2;
01094     return fd;
01095 }
01096 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01097 {
01098     fd->type = fd->appType = dbField::tpInt4;
01099     return fd;
01100 }
01101 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01102 {
01103     fd->type = fd->appType = dbField::tpInt8;
01104     return fd;
01105 }
01106 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01107 {
01108     fd->type = fd->appType = dbField::tpInt1;
01109     return fd;
01110 }
01111 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01112 {
01113     fd->type = fd->appType = dbField::tpInt2;
01114     return fd;
01115 }
01116 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01117 {
01118     fd->type = fd->appType = dbField::tpInt4;
01119     return fd;
01120 }
01121 #if SIZEOF_LONG != 8
01122 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01123 {
01124     fd->type = fd->appType = dbField::tpInt4;
01125     return fd;
01126 }
01127 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01128 {
01129     fd->type = fd->appType = dbField::tpInt4;
01130     return fd;
01131 }
01132 #endif
01133 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01134 {
01135     fd->type = fd->appType = dbField::tpInt8;
01136     return fd;
01137 }
01138 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01139 {
01140     fd->type = fd->appType = dbField::tpBool;
01141     return fd;
01142 }
01143 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01144 {
01145     fd->type = fd->appType = dbField::tpReal4;
01146     return fd;
01147 }
01148 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01149 {
01150     fd->type = fd->appType = dbField::tpReal8;
01151     return fd;
01152 }
01153 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01154 {
01155     fd->type = fd->appType = dbField::tpRectangle;
01156     fd->alignment = sizeof(coord_t);
01157     return fd;
01158 }
01159 
01160 #ifdef USE_STD_STRING
01161 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01162 {
01163     fd->type = dbField::tpString;
01164     fd->appType = dbField::tpStdString;
01165     fd->dbsSize = sizeof(dbVarying);
01166     fd->alignment = 4;
01167     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01168     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01169     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01170     return fd;
01171 }
01172 #endif
01173 #ifdef USE_MFC_STRING
01174 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01175 {
01176     fd->type = dbField::tpString;
01177     fd->appType = dbField::tpMfcString;
01178     fd->dbsSize = sizeof(dbVarying);
01179     fd->alignment = 4;
01180     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01181     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01182     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01183     return fd;
01184 }
01185 #endif
01186 
01187 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01188 {
01189     fd->type = fd->appType = dbField::tpString;
01190     fd->dbsSize = sizeof(dbVarying);
01191     fd->alignment = 4;
01192     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01193     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01194     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01195     return fd;
01196 }
01197 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01198 {
01199     fd->type = fd->appType = dbField::tpString;
01200     fd->dbsSize = sizeof(dbVarying);
01201     fd->alignment = 4;
01202     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01203     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01204     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01205     return fd;
01206 }
01207 
01208 
01209 template<class T>
01210 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01211 {
01212     fd->type = fd->appType = dbField::tpStructure;
01213     fd->components = x.dbDescribeComponents(fd);
01214     return fd;
01215 }
01216 
01217 
01221 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01222   public:
01223     dbFieldDescriptor* cls;
01224 
01230     virtual void invoke(byte* data, void* result) = 0;
01231 
01238     virtual dbAnyMethodTrampoline* optimize() = 0;
01239 
01244     dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01245     
01249     virtual~dbAnyMethodTrampoline();
01250 
01251     void* operator new(size_t size);
01252     void  operator delete(void* p);
01253 };
01254 
01255 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510 && __SUNPRO_CC_COMPAT == 5)
01256 
01259 template<class T, class R>
01260 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01261   public:
01262     typedef R (T::*mfunc)();
01263 
01264     mfunc              method;
01265     dbFieldDescriptor* cls;
01266     bool               optimized;
01267 
01268     void invoke(byte* data, void* result) {
01269         if (optimized) { 
01270             *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01271         } else { 
01272             T rec;
01273             this->cls->components->fetchRecordFields((byte*)&rec, data);
01274             *(R*)result = (rec.*method)();
01275         }
01276     }
01277     dbAnyMethodTrampoline* optimize() { 
01278         optimized = true;
01279         return this;
01280     }
01281 
01282     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01283     : dbAnyMethodTrampoline(fd)
01284     {
01285         this->method = f;
01286         this->cls = fd;
01287         this->optimized = false;
01288     }
01289 };
01290 
01291 #else
01292 
01296 template<class T, class R>
01297 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01298   public:
01299     typedef R (T::*mfunc)();
01300     mfunc method;
01301 
01302     void invoke(byte* data, void* result) {
01303         T rec;
01304         this->cls->components->fetchRecordFields((byte*)&rec, data);
01305         *(R*)result = (rec.*method)();
01306     }
01307     dbAnyMethodTrampoline* optimize();
01308 
01309     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01310     : dbAnyMethodTrampoline(fd), method(f) {}
01311 };
01312 
01313 template<class T, class R>
01314 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01315     typedef R (T::*mfunc)();
01316     mfunc method;
01317   public:
01318     dbAnyMethodTrampoline* optimize() { 
01319         return this;
01320     }
01321     void invoke(byte* data, void* result) {
01322         *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01323     }
01324     dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
01325     : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01326         delete mt;
01327     }
01328 };
01329 
01330 template<class T, class R>
01331 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01332     return new dbMethodFastTrampoline<T,R>(this);
01333 }
01334 
01335 #endif
01336 template<class T, class R>
01337 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01338 {
01339     R ret;
01340     dbDescribeField(fd, ret);
01341     assert(fd->type <= dbField::tpReference);
01342     fd->appType = fd->type += dbField::tpMethodBool;
01343     fd->method = new dbMethodTrampoline<T,R>(fd, p);
01344     return fd;
01345 }
01346 
01347 END_GIGABASE_NAMESPACE
01348 
01349 #endif
01350 
01351 

Generated on Mon Oct 23 13:22:58 2006 for GigaBASE by doxygen1.2.18