Main Page | Class Hierarchy | Class List | File List | Class 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 EXTRA_DEBUG_NEW_PARAMS);
00490     void  operator delete(void* p EXTRA_DEBUG_NEW_PARAMS);
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     friend class dbSelection;
00540   protected:
00544     dbTableDescriptor*  next;
00545     static dbTableDescriptor* chain;
00546 
00550     dbTableDescriptor*  nextDbTable; // next table in the database
00551 
00555     char*               name;
00556 
00560     oid_t               tableId;
00561 
00565     dbFieldDescriptor*  columns; 
00566     
00570     dbFieldDescriptor*  hashedFields;
00571 
00575     dbFieldDescriptor*  indexedFields;
00576 
00580     dbFieldDescriptor*  inverseFields;
00581 
00585     dbFieldDescriptor*  firstField;
00586 
00590     dbFieldDescriptor** nextFieldLink;
00591 
00595     dbDatabase*         db;
00596     
00600     bool                fixedDatabase;
00601 
00605     bool                isStatic;
00606 
00610     size_t              appSize;
00611 
00615     size_t              fixedSize;
00616 
00620     size_t              nFields;
00621 
00625     size_t              nColumns;
00626 
00630     int4                autoincrementCount;
00631 
00632 
00638     dbTableDescriptor*  cloneOf;
00639 
00640 
00644     typedef dbFieldDescriptor* (*describeFunc)();
00645     describeFunc        describeComponentsFunc;
00646 
00650     dbTableDescriptor*  clone();
00651 
00655     size_t              totalNamesLength();
00656 
00668     int calculateFieldsAttributes(dbFieldDescriptor* fieldsList, 
00669                                   char const* prefix, int offs, 
00670                                   int indexMask, int& attr);
00671 
00680     dbFieldDescriptor* buildFieldsList(dbTable* table, char const* prefix, int prefixLen, int& attr);
00681 
00682   public:
00686     static int initialAutoincrementCount;
00687 
00691     dbTableDescriptor* getNextTable() { 
00692         return nextDbTable;
00693     }
00694 
00698     dbFieldDescriptor* findSymbol(char const* name);
00699 
00700 
00704     dbFieldDescriptor* find(char const* name);
00705 
00706 
00711     dbFieldDescriptor* getFirstField() { 
00712         return columns;
00713     }
00714 
00720     dbFieldDescriptor* getNextField(dbFieldDescriptor* field) { 
00721         if (field != NULL) { 
00722             field = field->next;
00723             if (field == columns) { 
00724                 return NULL;
00725             }
00726         }
00727         return field;
00728     }
00729 
00733     char* getName() { 
00734         return name;
00735     }
00736 
00741     void setFlags();
00742 
00749     bool equal(dbTable* table);
00750 
00759     bool match(dbTable* table, bool confirmDeleteColumns);
00760 
00766     void checkRelationship();
00767 
00772     dbDatabase* getDatabase() { 
00773         assert(db != DETACHED_TABLE);
00774         return db; 
00775     }
00776 
00781     void storeInDatabase(dbTable* table);
00782 
00786     static void cleanup();
00787 
00792     dbTableDescriptor(dbTable* table);
00793 
00802     dbTableDescriptor(char* tableName, dbDatabase* db, size_t objSize, 
00803                       describeFunc func, dbTableDescriptor* original = NULL);
00804 
00808     ~dbTableDescriptor();
00809 };
00810 
00814 struct dbVarying { 
00815     nat4 size; // number of elements in the array
00816     int4 offs; // offset from the beginning of the record
00817 };
00818 
00822 struct dbField { 
00823     enum FieldTypes { 
00824         tpBool,
00825         tpInt1,
00826         tpInt2,
00827         tpInt4,
00828         tpInt8,
00829         tpReal4, 
00830         tpReal8, 
00831         tpString,
00832         tpReference,
00833         tpArray,
00834         tpMethodBool,
00835         tpMethodInt1,
00836         tpMethodInt2,
00837         tpMethodInt4,
00838         tpMethodInt8,
00839         tpMethodReal4,
00840         tpMethodReal8,
00841         tpMethodString,
00842         tpMethodReference,
00843         tpStructure,
00844         tpRawBinary, 
00845         tpStdString,
00846         tpUnknown
00847     };
00848         
00852     dbVarying name;    
00853 
00857     dbVarying tableName; 
00858 
00862     dbVarying inverse; 
00863     
00867     int4      type;
00868 
00872     int4      offset; 
00873 
00877     nat4      size;
00878 
00882     oid_t     hashTable;
00883 
00887     oid_t     tTree;
00888 };     
00889 
00890 
00894 class dbRecord { 
00895   public:
00899     nat4   size;
00900 
00904     oid_t  next;
00905 
00909     oid_t  prev;
00910 };
00911 
00912 
00916 class dbTable : public dbRecord { 
00917   public:
00921     dbVarying name;
00922     
00926     dbVarying fields;
00927 
00931     nat4      fixedSize;
00932 
00936     nat4      nRows;
00937 
00941     nat4      nColumns;
00942     
00946     oid_t     firstRow;
00947 
00951     oid_t     lastRow;
00952 #ifdef AUTOINCREMENT_SUPPORT
00953 
00956     nat4      count;
00957 #endif
00958 };
00959 
00960 inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
00961 {
00962     fd->type = fd->appType = dbField::tpRawBinary;
00963     fd->alignment = 1;
00964     fd->comparator = comparator;
00965     return fd;
00966 }
00967 
00968 
00969 template<class T>
00970 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x) 
00971 { 
00972     fd->type = fd->appType = dbField::tpStructure;
00973     fd->components = x.dbDescribeComponents(fd);
00974     return fd;
00975 }
00976 
00977 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&) 
00978 { 
00979     fd->type = fd->appType = dbField::tpInt1; 
00980     return fd;
00981 }
00982 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&) 
00983 { 
00984     fd->type = fd->appType = dbField::tpInt2; 
00985     return fd;
00986 }
00987 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&) 
00988 { 
00989     fd->type = fd->appType = dbField::tpInt4; 
00990     return fd;
00991 }
00992 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&) 
00993 { 
00994     fd->type = fd->appType = dbField::tpInt8; 
00995     return fd;
00996 }
00997 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&) 
00998 { 
00999     fd->type = fd->appType = dbField::tpInt1; 
01000     return fd;
01001 }
01002 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&) 
01003 { 
01004     fd->type = fd->appType = dbField::tpInt2; 
01005     return fd;
01006 }
01007 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&) 
01008 { 
01009     fd->type = fd->appType = dbField::tpInt4; 
01010     return fd;
01011 }
01012 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&) 
01013 { 
01014     fd->type = fd->appType = dbField::tpInt8; 
01015     return fd;
01016 }
01017 #if SIZEOF_LONG != 8
01018 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
01019 {
01020     fd->type = fd->appType = dbField::tpInt4;
01021     return fd;
01022 }
01023 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
01024 {
01025     fd->type = fd->appType = dbField::tpInt4;
01026     return fd;
01027 }
01028 #endif
01029 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&) 
01030 { 
01031     fd->type = fd->appType = dbField::tpBool; 
01032     return fd;
01033 }
01034 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&) 
01035 { 
01036     fd->type = fd->appType = dbField::tpReal4; 
01037     return fd;
01038 }
01039 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&) 
01040 { 
01041     fd->type = fd->appType = dbField::tpReal8; 
01042     return fd;
01043 }
01044 #ifdef USE_STD_STRING
01045 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, std::string&)
01046 {
01047     fd->type = dbField::tpString;
01048     fd->appType = dbField::tpStdString;
01049     fd->dbsSize = sizeof(dbVarying);
01050     fd->alignment = 4;
01051     fd->components = new dbFieldDescriptor("[]");
01052     fd->components->type = fd->components->appType = dbField::tpInt1;
01053     fd->components->dbsSize = fd->components->appSize = fd->components->alignment = 1; 
01054     return fd;
01055 }
01056 #endif
01057 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char const*&) 
01058 { 
01059     fd->type = fd->appType = dbField::tpString; 
01060     fd->dbsSize = sizeof(dbVarying); 
01061     fd->alignment = 4;
01062     fd->components = new dbFieldDescriptor("[]");
01063     fd->components->type = fd->components->appType = dbField::tpInt1;
01064     fd->components->dbsSize = fd->components->appSize = 1;
01065     fd->components->alignment = 1; 
01066     return fd;
01067 }
01068 inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char*&) 
01069 { 
01070     fd->type = fd->appType = dbField::tpString; 
01071     fd->dbsSize = sizeof(dbVarying); 
01072     fd->alignment = 4;
01073     fd->components = new dbFieldDescriptor("[]");
01074     fd->components->type = fd->components->appType = dbField::tpInt1;
01075     fd->components->dbsSize = fd->components->appSize = 1;
01076     fd->components->alignment = 1; 
01077     return fd;
01078 }
01079 
01080 
01084 class FASTDB_DLL_ENTRY dbAnyMethodTrampoline { 
01085   public:
01086     dbFieldDescriptor* cls;
01087 
01093     virtual void invoke(byte* data, void* result) = 0;
01094 
01101     virtual dbAnyMethodTrampoline* optimize() = 0;
01102 
01107     dbAnyMethodTrampoline(dbFieldDescriptor* fd) { cls = fd; }
01108     
01109     void* operator new(size_t size EXTRA_DEBUG_NEW_PARAMS);
01110     void  operator delete(void* p EXTRA_DEBUG_NEW_PARAMS);
01111 
01115     virtual~dbAnyMethodTrampoline();
01116 };
01117     
01118 
01119 #if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || \
01120     (__SUNPRO_CC >= 0x520 && __SUNPRO_CC_COMPAT == 5)
01121 
01124 template<class T, class R>
01125 class dbMethodTrampoline : public dbAnyMethodTrampoline {
01126   public:
01127     typedef R (T::*mfunc)();
01128 
01129     mfunc              method;
01130     dbFieldDescriptor* cls;
01131     bool               optimized;
01132 
01133     void invoke(byte* data, void* result) {
01134         if (optimized) { 
01135             *(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
01136         } else { 
01137             T rec;
01138             cls->components->fetchRecordFields((byte*)&rec, data);
01139             *(R*)result = (rec.*method)();
01140         }
01141     }
01142     dbAnyMethodTrampoline* optimize() { 
01143         optimized = true;
01144         return this;
01145     }
01146 
01147     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
01148     : dbAnyMethodTrampoline(fd), method(f), cls(fd), optimized(false) {}
01149 };
01150 
01151 #else
01152 
01156 template<class T, class R>
01157 class dbMethodTrampoline : public dbAnyMethodTrampoline { 
01158   public:
01159     typedef R (T::*mfunc)();
01160     mfunc method;
01161 
01162     void invoke(byte* data, void* result) {
01163         T rec;
01164         cls->components->fetchRecordFields((byte*)&rec, data);
01165         *(R*)result = (rec.*method)();
01166     }
01167     dbAnyMethodTrampoline* optimize();
01168  
01169     dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f) 
01170     : dbAnyMethodTrampoline(fd), method(f) {} 
01171 };
01172 
01173 
01178 template<class T, class R>
01179 class dbMethodFastTrampoline : public dbMethodTrampoline<T,R> { 
01180   public:
01181     void invoke(byte* data, void* result) {
01182         *(R*)result = (((T*)(data + cls->dbsOffs))->*method)();
01183     }
01184     dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt) 
01185     : dbMethodTrampoline<T,R>(mt->cls, mt->method) { 
01186         delete mt;
01187     }
01188 };
01189 
01190 template<class T, class R>
01191 inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize() { 
01192     return new dbMethodFastTrampoline<T,R>(this);
01193 }
01194     
01195 #endif
01196 
01197 template<class T, class R>
01198 inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)()) 
01199 { 
01200     R ret;
01201     dbDescribeField(fd, ret);
01202     assert(fd->type <= dbField::tpReference);
01203     fd->appType = fd->type += dbField::tpMethodBool;
01204     fd->method = new dbMethodTrampoline<T,R>(fd, p);
01205     return fd;
01206 }
01207 
01208 #endif
01209 
01210 

Generated on Thu Feb 12 13:04:48 2004 for FastDB by doxygen 1.3.5