Main Page   Class Hierarchy   Compound List   File List   Compound Members  

class.h

00001 //-< CLASS.H >-------------------------------------------------------*--------*
00002 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Main Memory Database Management System)                          *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 10-Dec-98    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 
00017 #ifdef USE_STD_STRING
00018 #include <string>
00019 #endif
00020 
00021 #ifndef dbDatabaseOffsetBits 
00022 #define dbDatabaseOffsetBits 32
00023 #endif
00024 
00025 #ifndef dbDatabaseOidBits 
00026 #define dbDatabaseOidBits 32
00027 #endif
00028 
00032 #if dbDatabaseOidBits > 32
00033 typedef nat8 oid_t;  // It will work only for 64-bit OS
00034 #else
00035 typedef nat4 oid_t;
00036 #endif
00037 
00041 #if dbDatabaseOffsetBits > 32
00042 typedef nat8 offs_t; // It will work only for 64-bit OS
00043 #else
00044 typedef nat4 offs_t;
00045 #endif
00046 
00050 enum dbIndexType { 
00051     HASHED  = 1, // hash table
00052     INDEXED = 2, // T-tree
00053 
00054     DB_FIELD_CASCADE_DELETE = 8,   // Used by OWNER macro, do not set it explicitly
00055 
00056     AUTOINCREMENT = 16, // field is assigned automaticall incremented value
00057 
00058     DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
00059 };
00060 
00061 
00065 #define KEY(x, index) \
00066     *dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
00067                                            sizeof(x), index), x)
00068 
00072 #define FIELD(x) KEY(x, 0)
00073 
00077 typedef int (*dbUDTComparator)(void*, void*, size_t);
00078 
00082 #define UDT(x, index, comparator) \
00083     *dbDescribeRawField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
00084                                               sizeof(x), index), (dbUDTComparator)comparator)
00085 
00089 #define RAWFIELD(x) UDT(x, 0, &memcmp)
00090 
00094 #define RAWKEY(x, index) UDT(x, index, &memcmp)
00095 
00101 #define RELATION(x,inverse) \
00102     *dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
00103                                            sizeof(x), 0, #inverse), x)
00104 
00110 #define OWNER(x,member) \
00111     *dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
00112                                            sizeof(x), DB_FIELD_CASCADE_DELETE, \
00113                                            #member), x)
00114 
00117 #define METHOD(x) \
00118     *dbDescribeMethod(new dbFieldDescriptor(#x), &self::x)
00119 
00123 #define SUPERCLASS(x) \
00124     x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)
00125 
00130 #define TYPE_DESCRIPTOR(fields) \
00131     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00132         return &fields; \
00133     } \
00134     static dbTableDescriptor dbDescriptor 
00135 
00136 
00142 #define CLASS_DESCRIPTOR(name, fields) \
00143     typedef name self; \
00144     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
00145         return &fields; \
00146     } \
00147     static dbTableDescriptor dbDescriptor 
00148 
00152 #define REGISTER_IN(table, database) \
00153     dbTableDescriptor* dbGetTableDescriptor(table*) \
00154       { return &table::dbDescriptor; }            \
00155     static dbFieldDescriptor* dbDescribeComponentsOf##table() \
00156       { return ((table*)0)->dbDescribeComponents(NULL); }     \
00157     dbTableDescriptor table::dbDescriptor(#table, database, sizeof(table), \
00158                                           &dbDescribeComponentsOf##table)
00159 
00164 #define REGISTER(table) REGISTER_IN(table, NULL)
00165 
00170 #define DETACHED_TABLE ((dbDatabase*)-1)
00171 #define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
00172 
00173 
00174 class dbDatabase;
00175 class dbAnyArray;
00176 class dbTableDescriptor;
00177 class dbAnyMethodTrampoline;
00178 
00182 class FASTDB_DLL_ENTRY dbFieldDescriptor { 
00183   public:
00187     dbFieldDescriptor* next;
00191     dbFieldDescriptor* prev;
00192 
00196     dbFieldDescriptor* nextField;
00197     
00201     dbFieldDescriptor* nextHashedField;
00202 
00206     dbFieldDescriptor* nextIndexedField;
00207 
00211     dbFieldDescriptor* nextInverseField;
00212 
00216     int                fieldNo;
00217     
00221     char*              name;
00222 
00226     char*              longName;
00227 
00231     char*              refTableName;
00232 
00236     dbTableDescriptor* refTable;
00237 
00241     dbTableDescriptor* defTable;
00242 
00246     dbFieldDescriptor* inverseRef;
00247 
00251     char*              inverseRefName;  
00252 
00256     int                type;
00257 
00261     int                appType;
00262 
00266     int                indexType;
00267 
00271     int                dbsOffs;
00272 
00276     int                appOffs;
00277 
00281     dbFieldDescriptor* components;
00282     
00286     oid_t              hashTable;
00287 
00291     oid_t              tTree;
00292 
00296     size_t             dbsSize;
00297     
00301     size_t             appSize;
00302 
00307     size_t             alignment;
00308 
00312     dbUDTComparator    comparator;
00313 
00317     enum FieldAttributes { 
00318         ComponentOfArray   = 0x01,
00319         HasArrayComponents = 0x02,
00320         OneToOneMapping    = 0x04,
00321         Updated            = 0x08
00322     };
00323     int                attr;
00324 
00328     int                oldDbsType;
00332     int                oldDbsOffs;
00336     int                oldDbsSize;
00337 
00341     dbAnyMethodTrampoline* method;
00342 
00346     void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
00347     
00348 
00359     size_t calculateRecordSize(byte* base, size_t offs);
00360 
00370     size_t calculateNewRecordSize(byte* base, size_t offs);
00371     
00381     size_t convertRecord(byte* dst, byte* src, size_t offs);
00382 
00393     int    sizeWithoutOneField(dbFieldDescriptor* field, 
00394                                byte* base, size_t& size);
00395     
00405     size_t copyRecordExceptOneField(dbFieldDescriptor* field, 
00406                                     byte* dst, byte* src, size_t offs); 
00407 
00418     size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
00419 
00427     void markUpdatedFields(byte* dst, byte* src);
00428 
00436     void fetchRecordFields(byte* dst, byte* src);
00437 
00446     void adjustReferences(byte* record, size_t base, size_t size, long shift);
00447 
00453     dbFieldDescriptor* find(const char* name);
00454 
00459     dbFieldDescriptor* getFirstComponent() { 
00460         return components;
00461     }
00462 
00467     dbFieldDescriptor* getNextComponent(dbFieldDescriptor* field) { 
00468         if (field != NULL) { 
00469             field = field->next;
00470             if (field == components) { 
00471                 return NULL;
00472             }
00473         }
00474         return field;
00475     }
00476         
00480     dbFieldDescriptor& operator, (dbFieldDescriptor& field) { 
00481         dbFieldDescriptor* tail = field.prev;
00482         tail->next = this;
00483         prev->next = &field;
00484         field.prev = prev;
00485         prev = tail;
00486         return *this;
00487     }
00488 
00489     void* operator new(size_t size);
00490     void  operator delete(void* p);
00491 
00495     dbFieldDescriptor& adjustOffsets(long offs);
00496 
00506     dbFieldDescriptor(char* name, int offs, int size, int indexType, 
00507                       char* inverse = NULL,
00508                       dbFieldDescriptor* components = NULL);
00509 
00514     dbFieldDescriptor(char* name);
00515 
00519     ~dbFieldDescriptor();
00520 };
00521 
00522 
00526 class FASTDB_DLL_ENTRY dbTableDescriptor { 
00527     friend class dbCompiler;
00528     friend class dbDatabase;
00529     friend class dbTable;
00530     friend class dbAnyCursor;
00531     friend class dbSubSql;
00532     friend class dbHashTable;
00533     friend class dbTtreeNode;
00534     friend class dbServer;
00535     friend class dbColumnBinding;
00536     friend class dbFieldDescriptor;
00537     friend class dbAnyContainer;
00538     friend class dbCLI;
00539   protected:
00543     dbTableDescriptor*  next;
00544     static dbTableDescriptor* chain;
00545 
00549     dbTableDescriptor*  nextDbTable; // next table in the database
00550 
00554     char*               name;
00555 
00559     oid_t               tableId;
00560 
00564     dbFieldDescriptor*  columns; 
00565     
00569     dbFieldDescriptor*  hashedFields;
00570 
00574     dbFieldDescriptor*  indexedFields;
00575 
00579     dbFieldDescriptor*  inverseFields;
00580 
00584     dbFieldDescriptor*  firstField;
00585 
00589     dbFieldDescriptor** nextFieldLink;
00590 
00594     dbDatabase*         db;
00595     
00599     bool                fixedDatabase;
00600 
00604     bool                isStatic;
00605 
00609     size_t              appSize;
00610 
00614     size_t              fixedSize;
00615 
00619     size_t              nFields;
00620 
00624     size_t              nColumns;
00625 
00629     int4                autoincrementCount;
00630 
00631 
00637     dbTableDescriptor*  cloneOf;
00638 
00639 
00643     typedef dbFieldDescriptor* (*describeFunc)();
00644     describeFunc        describeComponentsFunc;
00645 
00649     dbTableDescriptor*  clone();
00650 
00654     size_t              totalNamesLength();
00655 
00667     int calculateFieldsAttributes(dbFieldDescriptor* fieldsList, 
00668                                   char const* prefix, int offs, 
00669                                   int indexMask, int& attr);
00670 
00679     dbFieldDescriptor* buildFieldsList(dbTable* table, char const* prefix, int prefixLen, int& attr);
00680 
00681   public:
00685     static int initialAutoincrementCount;
00686 
00690     dbFieldDescriptor* findSymbol(char const* name);
00691 
00692 
00696     dbFieldDescriptor* find(char const* name);
00697 
00698 
00703     dbFieldDescriptor* getFirstField() { 
00704         return columns;
00705     }
00706 
00712     dbFieldDescriptor* getNextField(dbFieldDescriptor* field) { 
00713         if (field != NULL) { 
00714             field = field->next;
00715             if (field == columns) { 
00716                 return NULL;
00717             }
00718         }
00719         return field;
00720     }
00721 
00725     char* getName() { 
00726         return name;
00727     }
00728 
00733     void setFlags();
00734 
00741     bool equal(dbTable* table);
00742 
00750     bool match(dbTable* table);
00751 
00757     void checkRelationship();
00758 
00763     dbDatabase* getDatabase() { return db; }
00764 
00769     void storeInDatabase(dbTable* table);
00770 
00774     static void cleanup();
00775 
00780     dbTableDescriptor(dbTable* table);
00781 
00790     dbTableDescriptor(char* tableName, dbDatabase* db, size_t objSize, 
00791                       describeFunc func, dbTableDescriptor* original = NULL);
00792 
00796     ~dbTableDescriptor();
00797 };
00798 
00802 struct dbVarying { 
00803     nat4 size; // number of elements in the array
00804     int4 offs; // offset from the beginning of the record
00805 };
00806 
00810 struct dbField { 
00811     enum FieldTypes { 
00812         tpBool,
00813         tpInt1,
00814         tpInt2,
00815         tpInt4,
00816         tpInt8,
00817         tpReal4, 
00818         tpReal8, 
00819         tpString,
00820         tpReference,
00821         tpArray,
00822         tpMethodBool,
00823         tpMethodInt1,
00824         tpMethodInt2,
00825         tpMethodInt4,
00826         tpMethodInt8,
00827         tpMethodReal4,
00828         tpMethodReal8,
00829         tpMethodString,
00830         tpMethodReference,
00831         tpStructure,
00832         tpRawBinary, 
00833         tpStdString,
00834         tpUnknown
00835     };
00836         
00840     dbVarying name;    
00841 
00845     dbVarying tableName; 
00846 
00850     dbVarying inverse; 
00851     
00855     int4      type;
00856 
00860     int4      offset; 
00861 
00865     nat4      size;
00866 
00870     oid_t     hashTable;
00871 
00875     oid_t     tTree;
00876 };     
00877 
00878 
00882 class dbRecord { 
00883   public:
00887     nat4   size;
00888 
00892     oid_t  next;
00893 
00897     oid_t  prev;
00898 };
00899 
00900 
00904 class dbTable : public dbRecord { 
00905   public:
00909     dbVarying name;
00910     
00914     dbVarying fields;
00915 
00919     nat4      fixedSize;
00920 
00924     nat4      nRows;
00925 
00929     nat4      nColumns;
00930     
00934     oid_t     firstRow;
00935 
00939     oid_t     lastRow;
00940 #ifdef AUTOINCREMENT_SUPPORT
00941 
00944     nat4      count;
00945 #endif
00946 };
00947 
00948 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
00949 {
00950     fd->type = fd->appType = dbField::tpRawBinary;
00951     fd->alignment = 1;
00952     fd->comparator = comparator;
00953     return fd;
00954 }
00955 
00956 
00957 template<class T>
00958 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x) 
00959 { 
00960     fd->type = fd->appType = dbField::tpStructure;
00961     fd->components = x.dbDescribeComponents(fd);
00962     return fd;
00963 }
00964 
00965 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&) 
00966 { 
00967     fd->type = fd->appType = dbField::tpInt1; 
00968     return fd;
00969 }
00970 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&) 
00971 { 
00972     fd->type = fd->appType = dbField::tpInt2; 
00973     return fd;
00974 }
00975 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&) 
00976 { 
00977     fd->type = fd->appType = dbField::tpInt4; 
00978     return fd;
00979 }
00980 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&) 
00981 { 
00982     fd->type = fd->appType = dbField::tpInt8; 
00983     return fd;
00984 }
00985 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&) 
00986 { 
00987     fd->type = fd->appType = dbField::tpInt1; 
00988     return fd;
00989 }
00990 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&) 
00991 { 
00992     fd->type = fd->appType = dbField::tpInt2; 
00993     return fd;
00994 }
00995 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&) 
00996 { 
00997     fd->type = fd->appType = dbField::tpInt4; 
00998     return fd;
00999 }
01000 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&) 
01001 { 
01002     fd->type = fd->appType = dbField::tpInt8; 
01003     return fd;
01004 }
01005 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&) 
01006 { 
01007     fd->type = fd->appType = dbField::tpBool; 
01008     return fd;
01009 }
01010 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&) 
01011 { 
01012     fd->type = fd->appType = dbField::tpReal4; 
01013     return fd;
01014 }
01015 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&) 
01016 { 
01017     fd->type = fd->appType = dbField::tpReal8; 
01018     return fd;
01019 }
01020 #ifdef USE_STD_STRING
01021 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, std::string&)
01022 {
01023     fd->type = dbField::tpString;
01024     fd->appType = dbField::tpStdString;
01025     fd->dbsSize = sizeof(dbVarying);
01026     fd->alignment = 4;
01027     fd->components = new dbFieldDescriptor("[]");
01028     fd->components->type = fd->components->appType = dbField::tpInt1;
01029     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = 1; 
01030     return fd;
01031 }
01032 #endif
01033 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char const*&) 
01034 { 
01035     fd->type = fd->appType = dbField::tpString; 
01036     fd->dbsSize = sizeof(dbVarying); 
01037     fd->alignment = 4;
01038     fd->components = new dbFieldDescriptor("[]");
01039     fd->components->type = fd->components->appType = dbField::tpInt1;
01040     fd->components->dbsSize = fd->components->appSize = 1;
01041     fd->components->alignment = 1; 
01042     return fd;
01043 }
01044 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char*&) 
01045 { 
01046     fd->type = fd->appType = dbField::tpString; 
01047     fd->dbsSize = sizeof(dbVarying); 
01048     fd->alignment = 4;
01049     fd->components = new dbFieldDescriptor("[]");
01050     fd->components->type = fd->components->appType = dbField::tpInt1;
01051     fd->components->dbsSize = fd->components->appSize = 1;
01052     fd->components->alignment = 1; 
01053     return fd;
01054 }
01055 
01056 
01060 class FASTDB_DLL_ENTRY dbAnyMethodTrampoline { 
01061   public:
01062     dbFieldDescriptor* cls;
01063 
01069     virtual void invoke(byte* data, void* result) = 0;
01070 
01077     virtual dbAnyMethodTrampoline* optimize() = 0;
01078 
01083     dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01084     
01088     virtual~dbAnyMethodTrampoline();
01089 };
01090     
01091 
01092 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || \
01093     (__SUNPRO_CC >= 0x520 && __SUNPRO_CC_COMPAT == 5)
01094 
01097 template<class T, class R>
01098 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01099   public:
01100     typedef R (T::*mfunc)();
01101 
01102     mfunc              method;
01103     dbFieldDescriptor* cls;
01104     bool               optimized;
01105 
01106     void invoke(byte* data, void* result) {
01107         if (optimized) { 
01108             *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01109         } else { 
01110             T rec;
01111             cls->components->fetchRecordFields((byte*)&rec, data);
01112             *(R*)result = (rec.*method)();
01113         }
01114     }
01115     dbAnyMethodTrampoline* optimize() { 
01116         optimized = true;
01117         return this;
01118     }
01119 
01120     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01121     : dbAnyMethodTrampoline(fd), method(f), cls(fd), optimized(false) {}
01122 };
01123 
01124 #else
01125 
01129 template<class T, class R>
01130 class dbMethodTrampoline : public dbAnyMethodTrampoline { 
01131   public:
01132     typedef R (T::*mfunc)();
01133     mfunc method;
01134 
01135     void invoke(byte* data, void* result) {
01136         T rec;
01137         cls->components->fetchRecordFields((byte*)&rec, data);
01138         *(R*)result = (rec.*method)();
01139     }
01140     dbAnyMethodTrampoline* optimize();
01141  
01142     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f) 
01143     : dbAnyMethodTrampoline(fd), method(f) {} 
01144 };
01145 
01146 
01151 template<class T, class R>
01152 class dbMethodFastTrampoline : public dbMethodTrampoline<T,R> { 
01153   public:
01154     void invoke(byte* data, void* result) {
01155         *(R*)result = (((T*)(data + cls->dbsOffs))->*method)();
01156     }
01157     dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
01158     : dbMethodTrampoline<T,R>(mt->cls, mt->method) { 
01159         delete mt;
01160     }
01161 };
01162 
01163 template<class T, class R>
01164 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() { 
01165     return new dbMethodFastTrampoline<T,R>(this);
01166 }
01167     
01168 #endif
01169 
01170 template<class T, class R>
01171 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)()) 
01172 { 
01173     R ret;
01174     dbDescribeField(fd, ret);
01175     assert(fd->type <= dbField::tpReference);
01176     fd->appType = fd->type += dbField::tpMethodBool;
01177     fd->method = new dbMethodTrampoline<T,R>(fd, p);
01178     return fd;
01179 }
01180 
01181 #endif
01182 
01183 

Generated on Fri Nov 15 21:06:28 2002 for FastDB by doxygen1.2.15