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     *GB_NS::dbDescribeField(new GB_NS::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     *GB_NS::dbDescribeRawField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00094                                                             sizeof(x), index), (GB_NS::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     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00114                                                          sizeof(x), 0, STRLITERAL(#inverse)), x)
00115 
00121 #define INDEXED_RELATION(x,inverse) \
00122     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00123                                                          sizeof(x), GB_NS::INDEXED, STRLITERAL(#inverse)), x)
00124  
00130 #define OWNER(x,member) \
00131     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00132                                                          sizeof(x), GB_NS::DB_FIELD_CASCADE_DELETE, \
00133                                                          STRLITERAL(#member)), x)
00134 
00138 #define METHOD(x) \
00139     *GB_NS::dbDescribeMethod(new GB_NS::dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00140 
00147 #define BLOB(x) \
00148     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00149                                                          sizeof(x), GB_NS::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     GB_NS::dbFieldDescriptor* dbDescribeComponents(GB_NS::dbFieldDescriptor*) { \
00162         return &fields; \
00163     } \
00164     static GB_NS::dbTableDescriptor dbDescriptor
00165 
00171 #define CLASS_DESCRIPTOR(name, fields) \
00172     typedef name self; \
00173     GB_NS::dbFieldDescriptor* dbDescribeComponents(GB_NS::dbFieldDescriptor*) { \
00174         return &fields; \
00175     } \
00176     static GB_NS::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 GB_NS::dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00189       { return &table::dbDescriptor; }              \
00190     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00191      { return ((table*)0)->dbDescribeComponents(NULL); }     \
00192     GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00193                                                  &dbDescribeComponentsOf##table)
00194 
00195 #define REGISTER_TEMPLATE_IN(table, database) \
00196     TEMPLATE_SPEC GB_NS::dbTableDescriptor* dbGetTableDescriptor<table>(table*) \
00197       { return &table::dbDescriptor; }              \
00198     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00199      { return ((table*)0)->dbDescribeComponents(NULL); }     \
00200     template<> GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00201                                                             &dbDescribeComponentsOf##table)
00202 #else
00203 
00206 #define REGISTER_IN(table, database) \
00207     GB_NS::dbTableDescriptor* dbGetTableDescriptor(table*) \
00208       { return &table::dbDescriptor; }              \
00209     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00210       { return ((table*)0)->dbDescribeComponents(NULL); }     \
00211     GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00212                                                  &dbDescribeComponentsOf##table)
00213 #define REGISTER_TEMPLATE_IN(table, database) \
00214     GB_NS::dbTableDescriptor* dbGetTableDescriptor(table*) \
00215       { return &table::dbDescriptor; }              \
00216     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00217       { return ((table*)0)->dbDescribeComponents(NULL); }     \
00218     template<> GB_NS::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 ((GB_NS::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     dbTableDescriptor*  collisionChain;
00748 
00752     size_t              totalNamesLength();
00753 
00765     int calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00766                                   char_t const* prefix, int offs,
00767                                   int indexMask, int& attr);
00768 
00777     dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00778                                        int prefixLen, int& attr);
00782     dbTableDescriptor* clone();
00783 
00784   public:
00788     static int initialAutoincrementCount;
00789 
00790 
00794     dbTableDescriptor* getNextTable() { 
00795         return nextDbTable;
00796     }
00797 
00801     dbFieldDescriptor* findSymbol(char_t const* name);
00802 
00806     dbFieldDescriptor* find(char_t const* name);
00807 
00812      dbFieldDescriptor* getFirstField() { 
00813         return columns;
00814     }
00815 
00820     int getLastValueOfAutoincrementCount() const { 
00821         return autoincrementCount;
00822     }
00823 
00829     dbFieldDescriptor* getNextField(dbFieldDescriptor* field) { 
00830         if (field != NULL) { 
00831             field = field->next;
00832             if (field == columns) { 
00833                 return NULL;
00834             }
00835         }
00836         return field;
00837     }
00838 
00842     char_t* getName() { 
00843         return name;
00844     }
00845 
00849     size_t size() { 
00850         return appSize;
00851     }
00852 
00859      bool equal(dbTable* table);
00860 
00869     bool match(dbTable* table, bool confirmDeleteColumns);
00870 
00876     void checkRelationship();
00877 
00882     dbDatabase* getDatabase() { return db; }
00883 
00888     void storeInDatabase(dbTable* table);
00889 
00894     void setFlags();
00895 
00896 
00900     static void cleanup();
00901 
00902 
00907     dbTableDescriptor(dbTable* table);
00908 
00917     dbTableDescriptor(char_t const*      tableName, 
00918                       dbDatabase*        db, 
00919                       size_t             objSize,
00920                       describeFunc       func,
00921                       dbTableDescriptor* original = NULL);
00922 
00926      ~dbTableDescriptor();
00927 };
00928 
00932 struct dbVarying {
00933     nat4 size; // number of elements in the array
00934     int4 offs; // offset from the beginning of the record
00935 };
00936 
00940 struct dbField {
00941     enum FieldTypes {
00942         tpBool,
00943         tpInt1,
00944         tpInt2,
00945         tpInt4,
00946         tpInt8,
00947         tpReal4,
00948         tpReal8,
00949         tpString,
00950         tpReference,
00951         tpArray,
00952         tpMethodBool,
00953         tpMethodInt1,
00954         tpMethodInt2,
00955         tpMethodInt4,
00956         tpMethodInt8,
00957         tpMethodReal4,
00958         tpMethodReal8,
00959         tpMethodString,
00960         tpMethodReference,
00961         tpStructure,
00962         tpRawBinary,
00963         tpStdString,
00964         tpMfcString,
00965         tpRectangle,
00966         tpUnknown
00967     };
00968 
00972     dbVarying name;
00973 
00977     dbVarying tableName; // only for references: name of referenced table
00978 
00982     dbVarying inverse;   // only for relations: name of inverse reference field
00983     
00987 #ifdef OLD_FIELD_DESCRIPTOR_FORMAT
00988     int4      type;
00989 #else 
00990 #if BYTE_ORDER == BIG_ENDIAN
00991     int4      flags : 24;
00992     int4      type  : 8;
00993 #else
00994     int4      type  : 8;
00995     int4      flags : 24;
00996 #endif
00997 #endif
00998 
01002     int4      offset;
01003 
01007     nat4      size;
01008 
01012     oid_t     hashTable;
01013 
01017     oid_t     bTree;
01018 };
01019 
01020 
01024 class dbRecord {
01025   public:
01029     nat4   size;
01030 
01034     oid_t  next;
01035 
01039     oid_t  prev;
01040 };
01041 
01042 
01046 class dbTable : public dbRecord {
01047   public:
01051     dbVarying name;
01052     
01056     dbVarying fields;
01057 
01061     nat4      fixedSize;
01062 
01066     nat4      nRows;
01067 
01071     nat4      nColumns;
01072     
01076     oid_t     firstRow;
01077 
01081     oid_t     lastRow;
01082 #ifdef AUTOINCREMENT_SUPPORT
01083 
01086     nat4      count;
01087 #endif
01088 };
01089 
01090 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01091 {
01092     fd->type = fd->appType = dbField::tpRawBinary;
01093     fd->alignment = 1;
01094     fd->comparator = comparator;
01095     return fd;
01096 }
01097 
01098 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
01099 {
01100     fd->type = fd->appType = dbField::tpInt1;
01101     return fd;
01102 }
01103 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
01104 {
01105     fd->type = fd->appType = dbField::tpInt2;
01106     return fd;
01107 }
01108 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
01109 {
01110     fd->type = fd->appType = dbField::tpInt4;
01111     return fd;
01112 }
01113 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
01114 {
01115     fd->type = fd->appType = dbField::tpInt8;
01116     return fd;
01117 }
01118 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
01119 {
01120     fd->type = fd->appType = dbField::tpInt1;
01121     return fd;
01122 }
01123 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
01124 {
01125     fd->type = fd->appType = dbField::tpInt2;
01126     return fd;
01127 }
01128 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
01129 {
01130     fd->type = fd->appType = dbField::tpInt4;
01131     return fd;
01132 }
01133 #if SIZEOF_LONG != 8
01134 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01135 {
01136     fd->type = fd->appType = dbField::tpInt4;
01137     return fd;
01138 }
01139 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01140 {
01141     fd->type = fd->appType = dbField::tpInt4;
01142     return fd;
01143 }
01144 #endif
01145 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
01146 {
01147     fd->type = fd->appType = dbField::tpInt8;
01148     return fd;
01149 }
01150 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
01151 {
01152     fd->type = fd->appType = dbField::tpBool;
01153     return fd;
01154 }
01155 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
01156 {
01157     fd->type = fd->appType = dbField::tpReal4;
01158     return fd;
01159 }
01160 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
01161 {
01162     fd->type = fd->appType = dbField::tpReal8;
01163     return fd;
01164 }
01165 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01166 {
01167     fd->type = fd->appType = dbField::tpRectangle;
01168     fd->alignment = sizeof(coord_t);
01169     return fd;
01170 }
01171 
01172 #ifdef USE_STD_STRING
01173 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01174 {
01175     fd->type = dbField::tpString;
01176     fd->appType = dbField::tpStdString;
01177     fd->dbsSize = sizeof(dbVarying);
01178     fd->alignment = 4;
01179     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01180     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01181     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01182     return fd;
01183 }
01184 #endif
01185 #ifdef USE_MFC_STRING
01186 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01187 {
01188     fd->type = dbField::tpString;
01189     fd->appType = dbField::tpMfcString;
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 #endif
01198 
01199 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01200 {
01201     fd->type = fd->appType = dbField::tpString;
01202     fd->dbsSize = sizeof(dbVarying);
01203     fd->alignment = 4;
01204     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01205     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01206     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01207     return fd;
01208 }
01209 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01210 {
01211     fd->type = fd->appType = dbField::tpString;
01212     fd->dbsSize = sizeof(dbVarying);
01213     fd->alignment = 4;
01214     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01215     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01216     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01217     return fd;
01218 }
01219 
01220 
01221 template<class T>
01222 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01223 {
01224     fd->type = fd->appType = dbField::tpStructure;
01225     fd->components = x.dbDescribeComponents(fd);
01226     return fd;
01227 }
01228 
01229 
01233 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01234   public:
01235     dbFieldDescriptor* cls;
01236 
01242     virtual void invoke(byte* data, void* result) = 0;
01243 
01250     virtual dbAnyMethodTrampoline* optimize() = 0;
01251 
01256     dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01257     
01261     virtual~dbAnyMethodTrampoline();
01262 
01263     void* operator new(size_t size);
01264     void  operator delete(void* p);
01265 };
01266 
01267 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510 && __SUNPRO_CC_COMPAT == 5)
01268 
01271 template<class T, class R>
01272 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01273   public:
01274     typedef R (T::*mfunc)();
01275 
01276     mfunc              method;
01277     dbFieldDescriptor* cls;
01278     bool               optimized;
01279 
01280     void invoke(byte* data, void* result) {
01281         if (optimized) { 
01282             *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01283         } else { 
01284             T rec;
01285             this->cls->components->fetchRecordFields((byte*)&rec, data);
01286             *(R*)result = (rec.*method)();
01287         }
01288     }
01289     dbAnyMethodTrampoline* optimize() { 
01290         optimized = true;
01291         return this;
01292     }
01293 
01294     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01295     : dbAnyMethodTrampoline(fd)
01296     {
01297         this->method = f;
01298         this->cls = fd;
01299         this->optimized = false;
01300     }
01301 };
01302 
01303 #else
01304 
01308 template<class T, class R>
01309 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01310   public:
01311     typedef R (T::*mfunc)();
01312     mfunc method;
01313 
01314     void invoke(byte* data, void* result) {
01315         T rec;
01316         this->cls->components->fetchRecordFields((byte*)&rec, data);
01317         *(R*)result = (rec.*method)();
01318     }
01319     dbAnyMethodTrampoline* optimize();
01320 
01321     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01322     : dbAnyMethodTrampoline(fd), method(f) {}
01323 };
01324 
01325 template<class T, class R>
01326 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01327     typedef R (T::*mfunc)();
01328     mfunc method;
01329   public:
01330     dbAnyMethodTrampoline* optimize() { 
01331         return this;
01332     }
01333     void invoke(byte* data, void* result) {
01334         *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01335     }
01336     dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
01337     : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01338         delete mt;
01339     }
01340 };
01341 
01342 template<class T, class R>
01343 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01344     return new dbMethodFastTrampoline<T,R>(this);
01345 }
01346 
01347 #endif
01348 template<class T, class R>
01349 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01350 {
01351     R ret;
01352     dbDescribeField(fd, ret);
01353     assert(fd->type <= dbField::tpReference);
01354     fd->appType = fd->type += dbField::tpMethodBool;
01355     fd->method = new dbMethodTrampoline<T,R>(fd, p);
01356     return fd;
01357 }
01358 
01359 END_GIGABASE_NAMESPACE
01360 
01361 #endif
01362 
01363 

Generated on Thu Feb 14 21:46:03 2008 for GigaBASE by doxygen1.2.18