⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.h

📁 最新版本!fastdb是高效的内存数据库系统
💻 H
📖 第 1 页 / 共 3 页
字号:
//-< CLASS.H >-------------------------------------------------------*--------*
// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
// (Main Memory Database Management System)                          *   /\|  *
//                                                                   *  /  \  *
//                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
//                          Last update: 10-Dec-98    K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// Metaclass information
//-------------------------------------------------------------------*--------*

#ifndef __CLASS_H__
#define __CLASS_H__

#include "stdtp.h"
#include "sync.h"
#include "rectangle.h"

#ifdef USE_STD_STRING
#include <string>
#endif

BEGIN_FASTDB_NAMESPACE

#ifndef dbDatabaseOffsetBits 
#define dbDatabaseOffsetBits 32
#endif

#ifndef dbDatabaseOidBits 
#define dbDatabaseOidBits 32
#endif

/**
 * Object indentifier type
 */
#if dbDatabaseOidBits > 32
typedef size_t oid_t;  // It will work only for 64-bit OS
#else
typedef nat4 oid_t;
#endif

/**
 * Object offset in the file type
 */
#if dbDatabaseOffsetBits > 32
typedef size_t offs_t; // It will work only for 64-bit OS
#else
typedef nat4 offs_t;
#endif

/**
 * Types of field index
 */
enum dbIndexType { 
    HASHED  = 1,                   // hash table
    INDEXED = 2,                   // T-tree

    DB_FIELD_CASCADE_DELETE = 8,   // Used by OWNER macro, do not set it explicitly

    AUTOINCREMENT = 16,            // field is assigned automaticall incremented value

    DB_TIMESTAMP = 256,            // field is used as timestamp (this flag is used by CLI to perfrom proper mapping,
                                   // it is not used by C++ API)
    DB_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
};


/**
 * Macro for describing indexed fields
 */
#define KEY(x, index) \
    *FASTDB_NS::dbDescribeField(new FASTDB_NS::dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                                                 sizeof(x), index), x)

/**
 * Macro for describing non-indexed fields
 */
#define FIELD(x) KEY(x, 0)

/**
 * Comparator for user defined raw binary fields
 */
typedef int (*dbUDTComparator)(void*, void*, size_t);

/**
 * Macro used to describe indexed raw binary fields with user-defined comparator
 */
#define UDT(x, index, comparator) \
    *FASTDB_NS::dbDescribeRawField(new FASTDB_NS::dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                                                    sizeof(x), index), (dbUDTComparator)comparator)

/**
 * Macro used to describe raw binary field
 */
#define RAWFIELD(x) UDT(x, 0, &memcmp)

/**
 * Macro used to describe indexed raw binary field
 */
#define RAWKEY(x, index) UDT(x, index, &memcmp)

/**
 * Macro for describing relations between two tables. 
 * <code>x</code> should specify name of reference or array of reference field in this table, 
 * and <code>inverse</code> - field in the referenced table contining inverse reference.
 */
#define RELATION(x,inverse) \
    *FASTDB_NS::dbDescribeField(new FASTDB_NS::dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                                                 sizeof(x), 0, #inverse), x)

/**
 * Macro for describing relations between two tables.  
 * <code>x</code> should specify name of reference field in this table for which index will be created, 
 * and <code>inverse</code> - field in the referenced table contining inverse reference.
 */
#define INDEXED_RELATION(x,inverse) \
    *FASTDB_NS::dbDescribeField(new FASTDB_NS::dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                                                 sizeof(x), FASTDB_NS::INDEXED, #inverse), x)
 

/**
 * Macro used to define relation owner (when owner is deleted, all referenced
 * members are also deleted). Members of of this relation should use 
 * <code>RELATION</code> macro to describe relation with owner.  
 */
#define OWNER(x,member) \
    *FASTDB_NS::dbDescribeField(new FASTDB_NS::dbFieldDescriptor(#x, (char*)&x-(char*)this, \
                                           sizeof(x), FASTDB_NS::DB_FIELD_CASCADE_DELETE, \
                                           #member), x)
/**
 * Macro used to describe method of the class which can be invoked from SubSQL
 */
#define METHOD(x) \
    *FASTDB_NS::dbDescribeMethod(new FASTDB_NS::dbFieldDescriptor(#x), &self::x)

/**
 * Macro used to describe superclass for this class
 */
#define SUPERCLASS(x) \
    x::dbDescribeComponents(NULL)->adjustOffsets((char*)((x*)this)-(char*)this)

/**
 * Macro used to describe fields of the record. Use <code>FIELD, KEY</code>...
 * macros separated by comma inside this macro to describe all fields of the record
 */
#define TYPE_DESCRIPTOR(fields) \
    FASTDB_NS::dbFieldDescriptor* dbDescribeComponents(FASTDB_NS::dbFieldDescriptor*) { \
        return &fields; \
    } \
    static FASTDB_NS::dbTableDescriptor dbDescriptor 


/**
 * Macro used to describe class, the only difference from <code>TYPE_DESCRIPTOR</code>
 * is that name of the class should be specified. This name is needed if you want
 * to describe methods.
 */
#define CLASS_DESCRIPTOR(name, fields) \
    typedef name self; \
    FASTDB_NS::dbFieldDescriptor* dbDescribeComponents(FASTDB_NS::dbFieldDescriptor*) { \
        return &fields; \
    } \
    static FASTDB_NS::dbTableDescriptor dbDescriptor 

/**
 * Register table descriptor and assign it to specified database
 */
#define REGISTER_IN(table, database) \
    FASTDB_NS::dbTableDescriptor* dbGetTableDescriptor(table*) \
      { return &table::dbDescriptor; }            \
    static FASTDB_NS::dbFieldDescriptor* dbDescribeComponentsOf##table() \
      { return ((table*)0)->dbDescribeComponents(NULL); }     \
    FASTDB_NS::dbTableDescriptor table::dbDescriptor(#table, database, sizeof(table), \
                                          &dbDescribeComponentsOf##table)
#define REGISTER_IN_NS(ns, table, database)                     \
    FASTDB_NS::dbTableDescriptor* dbGetTableDescriptor(ns::table*)      \
    { return &ns::table::dbDescriptor; }                                \
    static FASTDB_NS::dbFieldDescriptor* dbDescribeComponentsOf##ns##__##table() \
    { return ((ns::table*)0)->dbDescribeComponents(NULL); }             \
    FASTDB_NS::dbTableDescriptor ns::table::dbDescriptor(ns##__##table, database, sizeof(ns::table), \
                                                         &dbDescribeComponentsOf##ns##__##table)

/**
 * Register table descripttor. It will be assigned to the database when database will be 
 * opened
 */
#define REGISTER(table) REGISTER_IN(table, NULL)
#define REGISTER_NS(ns, table) REGISTER_IN_NS(ns, table, NULL)

/**
 * Register database and mark it as unsigned. Programmer should explicitly
 * specify database in all operations.
 */
#define DETACHED_TABLE ((FASTDB_NS::dbDatabase*)-1)
#define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
#define REGISTER_UNASSIGNED_NS(ns, table) REGISTER_IN_NS(ns, table, DETACHED_TABLE)


class dbTable;
class dbDatabase;
class dbAnyArray;
class dbTableDescriptor;
class dbAnyMethodTrampoline;

/**
 * Descriptor of table field
 */
class FASTDB_DLL_ENTRY dbFieldDescriptor { 
  public:
    /**
     * Next file within scope
     */
    dbFieldDescriptor* next;
    /**
     * Previous field within scope
     */
    dbFieldDescriptor* prev;

    /**
     * Next field in the list of all fields in the table
     */
    dbFieldDescriptor* nextField;
    
    /**
     * Next field in the list of all hashed fields in the table
     */
    dbFieldDescriptor* nextHashedField;

    /**
     * Next field in the list of all indexed fields in the table
     */
    dbFieldDescriptor* nextIndexedField;

    /**
     * Next field in the list of all relation fields in the table
     */
    dbFieldDescriptor* nextInverseField;

    /**
     * Column number
     */
    int                fieldNo;
    
    /**
     * Name of the field
     */
    char*              name;

    /**
     * Compound name of field, for example "coord.x"
     */
    char*              longName;

    /**
     * Name of referenced table (for reference fields only)
     */
    char*              refTableName;

    /**
     * Referenced table (for reference fields only)
     */
    dbTableDescriptor* refTable;

    /**
     * Definition of the table to which this field belongs
     */
    dbTableDescriptor* defTable;

    /**
     * Inverse reference (for reference fields only)
     */
    dbFieldDescriptor* inverseRef;

    /**
     * Inverse reference name (for reference fields only)
     */
    char*              inverseRefName;  

    /**
     * Type of the field in the database (dbField::FieldTypes)
     */
    int                type;

    /**
     * Type of the field in application
     */
    int                appType;

    /**
     * Type of field index (bit combination of constants defined in dbIndexType)
     */
    int                indexType;

    /** 
     * Offset to the field in database
     */
    int                dbsOffs;

    /** 
     * Offset to the field in application
     */    
    int                appOffs;

    /**
     * Subcomponents of the field (for structures and arrays)
     */
    dbFieldDescriptor* components;
    
    /**
     * Hash table (for fields which are indexed by means of hash table)
     */
    oid_t              hashTable;

    /**
     * T-Tree (for fields which are indexed by means of T-Ttree)
     */
    oid_t              tTree;

    /**
     * Size of the record in database
     */
    size_t             dbsSize;
    
    /**
     * Size of the object in application
     */
    size_t             appSize;

    /**
     * Alignment of the field (for structures it is equal to the maximum required alignment 
     * of it's components
     */
    size_t             alignment;

    /**
     * Comparator for user defined types
     */
    dbUDTComparator    comparator;

    /**
     * Attributes of the field
     */
    enum FieldAttributes { 
        ComponentOfArray   = 0x01,
        HasArrayComponents = 0x02,
        OneToOneMapping    = 0x04,
        Updated            = 0x08
    };
    int                attr;

    /**
     * Old type of the field in database (before schema evaluation)
     */
    int                oldDbsType;
    /**
     * Old offset of the field in database (before schema evaluation)
     */
    int                oldDbsOffs;
    /**
     * Old size of the field in database (before schema evaluation)
     */
    int                oldDbsSize;

    /**
     * Trampoline used to invoke class method from SubSQL (for method components only)
     */
    dbAnyMethodTrampoline* method;

    /**
     * Allocator of array components
     */
    void (*arrayAllocator)(dbAnyArray* array, void* data, size_t length);
    

    /**
     * Calculate record size in the database.
     * This method performs interation through all components in one scope
     * and recursively invokes itself for structure and array components. 
     * First time this method is invoked by table descriptor with <code>offs</code>
     * equal to size of fixed part of the record.
     * @param base address of the application object 
     * @param offs offset of the end of varying part of the record
     * @return size of the record
     */
    size_t calculateRecordSize(byte* base, size_t offs);

    /**
     * Calculate record size after reformatting record according
     * to the new definition of the application class.
     * This method performs interation thtough all components in one scope
     * and recursively invoke itself for structure and array components. 
     * @param base address of the application object 
     * @param offs offset of the end of varying part of the record
     * @return size of the record
     */
    size_t calculateNewRecordSize(byte* base, size_t offs);
    
    /**
     * Convert of the feild to new format.
     * This method is recursively invoked for array and structure components.     
     * @param dst destination for converted field
     * @param src original field
     * @param offs offset of varying part
     * @param offs offset of the end of varying part of the record
     * @return size of the record
     */
    size_t convertRecord(byte* dst, byte* src, size_t offs);

    /**
     * Size of the record without one field. This method is used to implement 
     * automatically updated inverse references.
     * This method performs interation thtough all components in one scope
     * and recursively invoke itself for structure and array components.      
     * @param field list of the fields in one scope
     * @param base pointer inside database
     * @param size [in/out] size of the record
     * @return offset of last field
     */
    int    sizeWithoutOneField(dbFieldDescriptor* field, 
                               byte* base, size_t& size);
    
    /**
     * Recursively copy record to new location except one field. This method
     * is used for updating inverse references.
     * @param field list of the fields in one scope
     * @param dst destination where record should be copied
     * @param src source of the copy
     * @param offs offset to the end of varying part
     * @return size of the record
     */
    size_t copyRecordExceptOneField(dbFieldDescriptor* field, 
                                    byte* dst, byte* src, size_t offs); 

    enum StoreMode {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -