• Main Page
  • Classes
  • Files
  • File List

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 typedef db_int8 soffs_t;
00047 #else
00048 typedef nat4 offs_t;
00049 typedef int4 soffs_t;
00050 #endif
00051 
00052 #include "selection.h"
00053 
00057 enum dbIndexType {
00058     HASHED  = 1,                   // hash table
00059     INDEXED = 2,                   // B-tree
00060     CASE_INSENSITIVE = 4,          // Index is case insensitive
00061 
00062     DB_FIELD_CASCADE_DELETE = 8,   // Used by OWNER macro, do not set it explicitly
00063     UNIQUE = 16,                   // should be used in conjunction with HASHED or INDEXED - unique constraint 
00064 
00065     AUTOINCREMENT = 32,            // field is assigned automaticall incremented value
00066     OPTIMIZE_DUPLICATES = 64,      // index with lot of duplicate key values
00067     DB_BLOB_CASCADE_DELETE = 128,  // Used by BLOB macro to mark BLOB fields which should be deleted together with 
00068                                    // containing them record
00069     DB_TIMESTAMP = 256,            // field is used as timestamp (this flag is used by CLI to perfrom proper mapping,
00070                                    // it is not used by C++ API)
00071     DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00072 };
00073 
00077 #define KEY(x, index) \
00078     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00079                                                          sizeof(x), index), x)
00080 
00081 #define KEY_WITH_DEFAULT(x, index, defaultValue) \
00082         *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00083         sizeof(x), index), x, defaultValue)
00084 
00088 #define FIELD(x) KEY(x, 0)
00089 
00090 #define FIELD_WITH_DEFAULT(x, defaultValue) KEY_WITH_DEF(x, 0, defaultValue)
00091 
00092 
00096 typedef int (*dbUDTComparator)(void*, void*, size_t);
00097 
00101 #define UDT(x, index, comparator) \
00102     *GB_NS::dbDescribeRawField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00103                                                             sizeof(x), index), (GB_NS::dbUDTComparator)comparator)
00104 
00108 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00109 
00113 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00114 
00115 
00121 #define RELATION(x,inverse) \
00122     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00123                                                          sizeof(x), 0, STRLITERAL(#inverse)), x)
00124 
00130 #define INDEXED_RELATION(x,inverse) \
00131     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00132                                                          sizeof(x), GB_NS::INDEXED, STRLITERAL(#inverse)), x)
00133  
00139 #define OWNER(x,member) \
00140     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00141                                                          sizeof(x), GB_NS::DB_FIELD_CASCADE_DELETE, \
00142                                                          STRLITERAL(#member)), x)
00143 
00147 #define METHOD(x) \
00148     *GB_NS::dbDescribeMethod(new GB_NS::dbFieldDescriptor(STRLITERAL(#x)), &self::x)
00149 
00156 #define BLOB(x) \
00157     *GB_NS::dbDescribeField(new GB_NS::dbFieldDescriptor(STRLITERAL(#x), (char*)&x-(char*)this, \
00158                                                          sizeof(x), GB_NS::DB_BLOB_CASCADE_DELETE), x)
00159 
00162 #define SUPERCLASS(x) \
00163     x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00164 
00169 #define TYPE_DESCRIPTOR(fields) \
00170     GB_NS::dbFieldDescriptor* dbDescribeComponents(GB_NS::dbFieldDescriptor*) { \
00171         return &fields; \
00172     } \
00173     static GB_NS::dbTableDescriptor dbDescriptor
00174 
00180 #define CLASS_DESCRIPTOR(name, fields) \
00181     typedef name self; \
00182     GB_NS::dbFieldDescriptor* dbDescribeComponents(GB_NS::dbFieldDescriptor*) { \
00183         return &fields; \
00184     } \
00185     static GB_NS::dbTableDescriptor dbDescriptor
00186 
00190 #if (defined(_MSC_VER) && _MSC_VER+0 < 1200) || defined(__MWERKS__)
00191     #if defined(_MSC_VER)
00192         #define GET_TABLE_DESC_PREFIX
00193     #else
00194         #define GET_TABLE_DESC_PREFIX template<>
00195     #endif
00196     #define GET_TABLE_DESC_PARAM(T) <T>(T*)
00197 #else
00198     #define GET_TABLE_DESC_PREFIX
00199     #define GET_TABLE_DESC_PARAM(T) (T*)
00200 #endif
00201 
00202 #if defined(_MSC_VER) && _MSC_VER+0 <= 1300
00203     #define TABLE_DESC_PREFIX 
00204 #else
00205     #define TABLE_DESC_PREFIX template<>
00206 #endif
00207 
00208 #define REGISTER_IN(table, database) \
00209     GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(table) \
00210       { return &table::dbDescriptor; }              \
00211     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00212      { return ((table*)0)->dbDescribeComponents(NULL); }     \
00213     GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00214                                                  &dbDescribeComponentsOf##table)
00215 
00216 #define REGISTER_TEMPLATE_IN(table, database) \
00217     GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(table) \
00218       { return &table::dbDescriptor; }              \
00219     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
00220      { return ((table*)0)->dbDescribeComponents(NULL); }     \
00221     TABLE_DESC_PREFIX GB_NS::dbTableDescriptor table::dbDescriptor(_T(#table), database, sizeof(table), \
00222                                                             &dbDescribeComponentsOf##table)
00223 
00224 #define REGISTER_IN_NS(ns, table, database)                              \
00225     GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(ns::table) \
00226     { return &ns::table::dbDescriptor; }                                \
00227     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##ns##__##table() \
00228     { return ((ns::table*)0)->dbDescribeComponents(NULL); }             \
00229     GB_NS::dbTableDescriptor ns::table::dbDescriptor(_T(ns##__##table), database, sizeof(ns::table), \
00230                                                      &dbDescribeComponentsOf##ns##__##table)
00231 
00232 #define REGISTER_TEMPLATE_IN_NS(ns, table, database)                              \
00233     GET_TABLE_DESC_PREFIX GB_NS::dbTableDescriptor* dbGetTableDescriptor GET_TABLE_DESC_PARAM(ns::table) \
00234     { return &ns::table::dbDescriptor; }                                \
00235     static GB_NS::dbFieldDescriptor* dbDescribeComponentsOf##ns##__##table() \
00236     { return ((ns::table*)0)->dbDescribeComponents(NULL); }             \
00237     TABLE_DESC_PREFIX GB_NS::dbTableDescriptor ns::table::dbDescriptor(_T(ns##__##table), database, sizeof(ns::table), \
00238                                                                 &dbDescribeComponentsOf##ns##__##table)
00239 
00240 
00245 #define REGISTER(table) REGISTER_IN(table, NULL)
00246 #define REGISTER_TEMPLATE(table) REGISTER_TEMPLATE_IN(table, NULL)
00247 #define REGISTER_NS(ns, table) REGISTER_IN_NS(ns, table, NULL)
00248 #define REGISTER_TEMPLATE_NS(ns, table) REGISTER_TEMPLATE_IN_NS(ns, table, NULL)
00249 
00254 #define DETACHED_TABLE ((GB_NS::dbDatabase*)-1)
00255 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00256 #define REGISTER_TEMPLATE_UNASSIGNED(table) REGISTER_TEMPLATE_IN(table, DETACHED_TABLE)
00257 #define REGISTER_UNASSIGNED_NS(ns, table) REGISTER_IN_NS(ns, table, DETACHED_TABLE)
00258 #define REGISTER_TEMPLATE_UNASSIGNED_NS(ns, table) REGISTER_TEMPLATE_IN_NS(ns, table, DETACHED_TABLE)
00259 
00260 
00261 class dbDatabase;
00262 class dbSession;
00263 class dbAnyArray;
00264 class dbTableDescriptor;
00265 class dbAnyMethodTrampoline;
00266 class dbTable;
00267 
00271 class GIGABASE_DLL_ENTRY dbFieldDescriptor {
00272   public:
00276     dbFieldDescriptor* next;
00277 
00281     dbFieldDescriptor* prev;
00282 
00286     dbFieldDescriptor* nextField;
00287 
00291     dbFieldDescriptor* nextHashedField;
00292 
00296     dbFieldDescriptor* nextIndexedField;
00297 
00301     dbFieldDescriptor* nextInverseField;
00302 
00306     int                fieldNo;
00307     
00311     char_t*            name;
00312 
00316     char_t*            longName;
00317 
00321     char_t*            refTableName;
00322 
00326     dbTableDescriptor* refTable;
00327 
00331     dbTableDescriptor* defTable;
00332 
00336     dbFieldDescriptor* inverseRef;
00337 
00341     char_t*            inverseRefName;
00342 
00346     int                type;
00347 
00351     int                appType;
00352 
00356     int                indexType;
00357 
00361     union {             
00362         bool Bool;              
00363         int1 Int1;              int2 Int2;              int4 Int4;              db_int8 Db_Int8;
00364         real4 Real4;    real8 Real8;
00365     } defaultValue;
00366     
00370     int                dbsOffs;
00371 
00375     int                appOffs;
00376 
00380     dbFieldDescriptor* components;
00381 
00385     oid_t              hashTable;
00386 
00390     oid_t              bTree;
00391 
00395     size_t             dbsSize;
00396     
00400     size_t             appSize;
00401 
00406     size_t             alignment;
00407 
00411     dbUDTComparator    comparator;
00412 
00416     enum FieldAttributes {
00417         ComponentOfArray   = 0x01,
00418         HasArrayComponents = 0x02,
00419         OneToOneMapping    = 0x04,
00420         Updated            = 0x08,
00421         HasArrayOfArrayComponents = 0x10
00422     };
00423     int                attr;
00424 
00428     int                oldDbsType;
00432     int                oldDbsOffs;
00436     int                oldDbsSize;
00437 
00438 
00442     dbAnyMethodTrampoline* method;
00443 
00447     void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00448 
00459     size_t calculateRecordSize(byte* base, size_t offs);
00460 
00470     size_t calculateNewRecordSize(byte* base, size_t offs);
00471     
00481     size_t convertRecord(byte* dst, byte* src, size_t offs);
00482 
00493     int    sizeWithoutOneField(dbFieldDescriptor* field,
00494                                byte* base, size_t& size);
00495 
00505     size_t copyRecordExceptOneField(dbFieldDescriptor* field,
00506                                     byte* dst, byte* src, size_t offs);
00507 
00508     
00509     enum StoreMode {
00510         Insert,
00511         Update,
00512         Import
00513     };
00514 
00525     size_t storeRecordFields(byte* dst, byte* src, size_t offs, StoreMode mode);
00526 
00534     void markUpdatedFields(byte* dst, byte* src);
00535 
00543     void markUpdatedFields2(byte* dst, byte* src);
00544 
00552      void fetchRecordFields(byte* dst, byte* src);
00553 
00559     dbFieldDescriptor* findSymbol(const char_t* name);
00560 
00566     dbFieldDescriptor* find(const char_t* name);
00567 
00572     dbFieldDescriptor* getFirstComponent() { 
00573         return components;
00574     }
00575 
00580     dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) { 
00581         if (field != NULL) { 
00582             field = field->next;
00583             if (field == components) { 
00584                 return NULL;
00585             }
00586         }
00587         return field;
00588     }
00589 
00593     dbFieldDescriptor& operator, (dbFieldDescriptor& field) {
00594         dbFieldDescriptor* tail = field.prev;
00595         tail->next = this;
00596         prev->next = &field;
00597         field.prev = prev;
00598         prev = tail;
00599         return *this;
00600     }
00601 
00602     void* operator new(size_t size);
00603     void  operator delete(void* p);
00604 
00608     dbFieldDescriptor& adjustOffsets(size_t offs);
00609 
00619     dbFieldDescriptor(char_t const* name, size_t offs, size_t size, int indexType,
00620                       char_t const* inverse = NULL,
00621                       dbFieldDescriptor* components = NULL);
00622 
00627     dbFieldDescriptor(char_t const* name);
00628 
00632     ~dbFieldDescriptor();
00633 };
00634 
00635 
00639 class GIGABASE_DLL_ENTRY dbTableDescriptor {
00640     friend class dbCompiler;
00641     friend class dbDatabase;
00642     friend class dbReplicatedDatabase;
00643     friend class dbTable;
00644     friend class dbAnyCursor;
00645     friend class dbSubSql;
00646     friend class dbParallelQueryContext;
00647     friend class dbServer;
00648     friend class dbSession;
00649     friend class dbAnyContainer;
00650     friend class dbColumnBinding;
00651     friend class dbFieldDescriptor;
00652     friend class dbSelection;
00653     friend class dbTableIterator;
00654     friend class dbCLI;
00655     friend class dbFileTransactionLogger;
00656 
00657   protected:
00661     dbTableDescriptor*  next;
00662     static dbTableDescriptor* chain;
00663     static dbMutex*           chainMutex;
00664 
00668     dbTableDescriptor*  nextDbTable; // next table in the database
00669 
00673     char_t*             name;
00674 
00678     oid_t               tableId;
00679 
00683     dbFieldDescriptor*  columns;
00684     
00688     dbFieldDescriptor*  hashedFields;
00689 
00693     dbFieldDescriptor*  indexedFields;
00694 
00698     dbFieldDescriptor*  inverseFields;
00699 
00703     dbFieldDescriptor*  firstField;
00704 
00708     dbFieldDescriptor** nextFieldLink;
00709 
00713     dbDatabase*         db;
00714     
00718     bool                fixedDatabase;
00719 
00723     bool                isStatic;
00724     
00730     dbTableDescriptor*  cloneOf;
00731 
00735     size_t              appSize;
00736 
00740     size_t              fixedSize;
00741 
00745     size_t              nFields;
00746 
00750     size_t              nColumns;
00751 
00755     oid_t               firstRow;
00756 
00760     oid_t               lastRow;
00761     
00765     size_t              nRows;
00766 
00770     int4                autoincrementCount;
00771 
00775     dbTableDescriptor*        nextBatch;
00776 
00780     bool                      isInBatch;
00781 
00785     dbSelection               batch;
00786 
00790     int                       transactionId;
00791 
00792 
00796     int                       attr;
00797 
00801     typedef dbFieldDescriptor* (*describeFunc)();
00802     describeFunc        describeComponentsFunc;
00803 
00807     dbTableDescriptor*  collisionChain;
00808 
00812     size_t              totalNamesLength();
00813 
00827      void calculateFieldsAttributes(dbFieldDescriptor* fieldsList,
00828                                   char_t const* prefix, int offs,
00829                                   int indexMask, int& attr,
00830                                   size_t& dbsAlignment, size_t& appAlignment);
00831 
00840     dbFieldDescriptor* buildFieldsList(dbTable* table, char_t const* prefix,
00841                                        int prefixLen, int& attr);
00845     dbTableDescriptor* clone();
00846 
00847   public:
00851     static int initialAutoincrementCount;
00852 
00853 
00857     dbTableDescriptor* getNextTable() { 
00858         return nextDbTable;
00859     }
00860 
00864     dbFieldDescriptor* findSymbol(char_t const* name);
00865 
00869     dbFieldDescriptor* find(char_t const* name);
00870 
00875      dbFieldDescriptor* getFirstField() { 
00876         return columns;
00877     }
00878 
00883     int getLastValueOfAutoincrementCount() const { 
00884         return autoincrementCount;
00885     }
00886 
00892     dbFieldDescriptor* getNextField(dbFieldDescriptor* field) { 
00893         if (field != NULL) { 
00894             field = field->next;
00895             if (field == columns) { 
00896                 return NULL;
00897             }
00898         }
00899         return field;
00900     }
00901 
00905     char_t* getName() { 
00906         return name;
00907     }
00908 
00912     size_t size() { 
00913         return appSize;
00914     }
00915 
00919     oid_t getId() { 
00920         return tableId;
00921     }
00922 
00930     bool equal(dbTable* table, bool ignoreIndices = false);
00931 
00942     bool match(dbTable* table, bool confirmDeleteColumns, bool preserveExistedIndices, bool isEmpty);
00943 
00949     bool checkRelationship();
00950 
00955     dbDatabase* getDatabase() { return db; }
00956 
00961     void storeInDatabase(dbTable* table);
00962 
00967     void setFlags();
00968 
00969     static dbMutex& getChainMutex();
00970     void link();
00971     void unlink();
00972 
00976     static void cleanup();
00977 
00978 
00983     dbTableDescriptor(dbTable* table);
00984 
00993     dbTableDescriptor(char_t const*      tableName, 
00994                       dbDatabase*        db, 
00995                       size_t             objSize,
00996                       describeFunc       func,
00997                       dbTableDescriptor* original = NULL);
00998 
01002      ~dbTableDescriptor();
01003 };
01004 
01008 struct dbVarying {
01009     nat4 size; // number of elements in the array
01010     int4 offs; // offset from the beginning of the record
01011 };
01012 
01016 struct dbField {
01017     enum FieldTypes {
01018         tpBool,
01019         tpInt1,
01020         tpInt2,
01021         tpInt4,
01022         tpInt8,
01023         tpReal4,
01024         tpReal8,
01025         tpString,
01026         tpReference,
01027         tpArray,
01028         tpMethodBool,
01029         tpMethodInt1,
01030         tpMethodInt2,
01031         tpMethodInt4,
01032         tpMethodInt8,
01033         tpMethodReal4,
01034         tpMethodReal8,
01035         tpMethodString,
01036         tpMethodReference,
01037         tpStructure,
01038         tpRawBinary,
01039         tpStdString,
01040         tpMfcString,
01041         tpRectangle,
01042         tpUnknown
01043     };
01044 
01048     dbVarying name;
01049 
01053     dbVarying tableName; // only for references: name of referenced table
01054 
01058     dbVarying inverse;   // only for relations: name of inverse reference field
01059     
01063 #ifdef OLD_FIELD_DESCRIPTOR_FORMAT
01064     int4      type;
01065 #else 
01066 #if BYTE_ORDER == BIG_ENDIAN
01067     int4      flags : 24;
01068     int4      type  : 8;
01069 #else
01070     int4      type  : 8;
01071     int4      flags : 24;
01072 #endif
01073 #endif
01074 
01078     int4      offset;
01079 
01083     nat4      size;
01084 
01088     oid_t     hashTable;
01089 
01093     oid_t     bTree;
01094 };
01095 
01096 
01100 class dbRecord {
01101   public:
01105     nat4   size;
01106 
01110     oid_t  next;
01111 
01115     oid_t  prev;
01116 };
01117 
01118 
01122 class dbTable : public dbRecord {
01123   public:
01127     dbVarying name;
01128     
01132     dbVarying fields;
01133 
01137     nat4      fixedSize;
01138 
01142     nat4      nRows;
01143 
01147     nat4      nColumns;
01148     
01152     oid_t     firstRow;
01153 
01157     oid_t     lastRow;
01158 #ifdef AUTOINCREMENT_SUPPORT
01159 
01162     nat4      count;
01163 #endif
01164 };
01165 
01166 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
01167 {
01168     fd->type = fd->appType = dbField::tpRawBinary;
01169     fd->alignment = 1;
01170     fd->comparator = comparator;
01171     return fd;
01172 }
01173 
01174 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&, int1 defaultValue = 0)
01175 {
01176     fd->type = fd->appType = dbField::tpInt1;
01177         fd->defaultValue.Int1 = defaultValue;
01178     return fd;
01179 }
01180 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&, int2 defaultValue = 0)
01181 {
01182     fd->type = fd->appType = dbField::tpInt2;
01183         fd->defaultValue.Int2 = defaultValue;
01184     return fd;
01185 }
01186 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&, int4 defaultValue = 0)
01187 {
01188     fd->type = fd->appType = dbField::tpInt4;
01189         fd->defaultValue.Int4 = defaultValue;
01190     return fd;
01191 }
01192 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&, db_int8 defaultValue = 0)
01193 {
01194     fd->type = fd->appType = dbField::tpInt8;
01195         fd->defaultValue.Db_Int8 = defaultValue;
01196     return fd;
01197 }
01198 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&, nat1 defaultValue = 0)
01199 {
01200     fd->type = fd->appType = dbField::tpInt1;
01201         fd->defaultValue.Int1 = defaultValue;
01202     return fd;
01203 }
01204 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&, nat2 defaultValue = 0)
01205 {
01206     fd->type = fd->appType = dbField::tpInt2;
01207         fd->defaultValue.Int2 = defaultValue;
01208     return fd;
01209 }
01210 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&, nat4 defaultValue = 0)
01211 {
01212         fd->type = fd->appType = dbField::tpInt4;
01213         fd->defaultValue.Int4 = defaultValue;
01214         return fd;
01215 }
01216 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&, nat8 defaultValue = 0)
01217 {
01218     fd->type = fd->appType = dbField::tpInt8;
01219         fd->defaultValue.Db_Int8 = defaultValue;
01220     return fd;
01221 }
01222 
01223 #if SIZEOF_LONG != 8 
01224 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&, long defaultValue = 0)
01225 {
01226     fd->type = fd->appType = sizeof(long) == 4 ? dbField::tpInt4 : dbField::tpInt8;
01227     if (sizeof(long) == 4) fd->defaultValue.Int4 = defaultValue;
01228     else fd->defaultValue.Db_Int8 = defaultValue;
01229     return fd;
01230 }
01231 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&, unsigned long defaultValue = 0)
01232 {
01233     fd->type = fd->appType = sizeof(long) == 4 ? dbField::tpInt4 : dbField::tpInt8;
01234     if (sizeof(long) == 4) fd->defaultValue.Int4 = defaultValue;
01235     else fd->defaultValue.Db_Int8 = defaultValue;
01236     return fd;
01237 }
01238 #endif
01239 
01240 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&, bool defaultValue = false)
01241 {
01242     fd->type = fd->appType = dbField::tpBool;
01243         fd->defaultValue.Bool = defaultValue;
01244     return fd;
01245 }
01246 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&, real4 defaultValue = 0.0)
01247 {
01248     fd->type = fd->appType = dbField::tpReal4;
01249         fd->defaultValue.Real4 = defaultValue;
01250     return fd;
01251 }
01252 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&, real8 defaultValue = 0.0)
01253 {
01254     fd->type = fd->appType = dbField::tpReal8;
01255         fd->defaultValue.Real8 = defaultValue;
01256     return fd;
01257 }
01258 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, rectangle&)
01259 {
01260     fd->type = fd->appType = dbField::tpRectangle;
01261     fd->alignment = sizeof(coord_t);
01262     return fd;
01263 }
01264 
01265 #ifdef USE_STD_STRING
01266 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, STD_STRING&)
01267 {
01268     fd->type = dbField::tpString;
01269     fd->appType = dbField::tpStdString;
01270     fd->dbsSize = sizeof(dbVarying);
01271     fd->alignment = 4;
01272     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01273     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01274     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01275     return fd;
01276 }
01277 #endif
01278 #ifdef USE_MFC_STRING
01279 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, MFC_STRING&)
01280 {
01281     fd->type = dbField::tpString;
01282     fd->appType = dbField::tpMfcString;
01283     fd->dbsSize = sizeof(dbVarying);
01284     fd->alignment = 4;
01285     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01286     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01287     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01288     return fd;
01289 }
01290 #endif
01291 
01292 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t const*&)
01293 {
01294     fd->type = fd->appType = dbField::tpString;
01295     fd->dbsSize = sizeof(dbVarying);
01296     fd->alignment = 4;
01297     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01298     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01299     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t); 
01300     return fd;
01301 }
01302 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char_t*&)
01303 {
01304     fd->type = fd->appType = dbField::tpString;
01305     fd->dbsSize = sizeof(dbVarying);
01306     fd->alignment = 4;
01307     fd->components = new dbFieldDescriptor(STRLITERAL("[]"));
01308     fd->components->type = fd->components->appType = dbField::tpInt1 + (sizeof(char_t) - 1);
01309     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = sizeof(char_t);
01310     return fd;
01311 }
01312 
01313 
01314 template<class T>
01315 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
01316 {
01317     fd->type = fd->appType = dbField::tpStructure;
01318     fd->components = x.dbDescribeComponents(fd);        
01319     return fd;
01320 }
01321 
01322 
01326 class GIGABASE_DLL_ENTRY dbAnyMethodTrampoline {
01327   public:
01328     dbFieldDescriptor* cls;
01329 
01335     virtual void invoke(byte* data, void* result) = 0;
01336 
01343     virtual dbAnyMethodTrampoline* optimize() = 0;
01344 
01349     dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01350     
01354     virtual~dbAnyMethodTrampoline();
01355 
01356     void* operator new(size_t size);
01357     void  operator delete(void* p);
01358 };
01359 
01360 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || defined(__HP_aCC) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x510 && __SUNPRO_CC_COMPAT == 5)
01361 
01364 template<class T, class R>
01365 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01366   public:
01367     typedef R (T::*mfunc)();
01368 
01369     mfunc              method;
01370     dbFieldDescriptor* cls;
01371     bool               optimized;
01372 
01373     void invoke(byte* data, void* result) {
01374         if (optimized) { 
01375             *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01376         } else { 
01377             T rec;
01378             this->cls->components->fetchRecordFields((byte*)&rec, data);
01379             *(R*)result = (rec.*method)();
01380         }
01381     }
01382     dbAnyMethodTrampoline* optimize() { 
01383         optimized = true;
01384         return this;
01385     }
01386 
01387     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01388     : dbAnyMethodTrampoline(fd)
01389     {
01390         this->method = f;
01391         this->cls = fd;
01392         this->optimized = false;
01393     }
01394 };
01395 
01396 #else
01397 
01401 template<class T, class R>
01402 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01403   public:
01404     typedef R (T::*mfunc)();
01405     mfunc method;
01406 
01407     void invoke(byte* data, void* result) {
01408         T rec;
01409         this->cls->components->fetchRecordFields((byte*)&rec, data);
01410         *(R*)result = (rec.*method)();
01411     }
01412     dbAnyMethodTrampoline* optimize();
01413 
01414     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01415     : dbAnyMethodTrampoline(fd), method(f) {}
01416 };
01417 
01418 template<class T, class R>
01419 class dbMethodFastTrampoline : public dbAnyMethodTrampoline {
01420     typedef R (T::*mfunc)();
01421     mfunc method;
01422   public:
01423     dbAnyMethodTrampoline* optimize() { 
01424         return this;
01425     }
01426     void invoke(byte* data, void* result) {
01427         *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01428     }
01429     dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
01430     : dbAnyMethodTrampoline(mt->cls), method(mt->method) {
01431         delete mt;
01432     }
01433 };
01434 
01435 template<class T, class R>
01436 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() {
01437     return new dbMethodFastTrampoline<T,R>(this);
01438 }
01439 
01440 #endif
01441 template<class T, class R>
01442 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
01443 {
01444     R ret;
01445     dbDescribeField(fd, ret);
01446     assert(fd->type <= dbField::tpReference);
01447     fd->appType = fd->type += dbField::tpMethodBool;
01448     fd->method = new dbMethodTrampoline<T,R>(fd, p);
01449     return fd;
01450 }
01451 
01452 END_GIGABASE_NAMESPACE
01453 
01454 #endif
01455 
01456 

Generated on Mon Aug 23 2010 00:04:01 for GigaBASE by  doxygen 1.7.1