📄 class.h
字号:
//-< 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"
#ifdef USE_STD_STRING
#include <string>
#endif
#ifndef dbDatabaseOffsetBits
#define dbDatabaseOffsetBits 32
#endif
#ifndef dbDatabaseOidBits
#define dbDatabaseOidBits 32
#endif
/**
* Object indentifier type
*/
#if dbDatabaseOidBits > 32
typedef nat8 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 nat8 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_FIELD_INHERITED_MASK = ~(HASHED|INDEXED)
};
/**
* Macro for describing indexed fields
*/
#define KEY(x, index) \
*dbDescribeField(new 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) \
*dbDescribeRawField(new 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) \
*dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
sizeof(x), 0, #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) \
*dbDescribeField(new dbFieldDescriptor(#x, (char*)&x-(char*)this, \
sizeof(x), DB_FIELD_CASCADE_DELETE, \
#member), x)
/**
* Macro used to describe method of the class which can be invoked from SubSQL
*/
#define METHOD(x) \
*dbDescribeMethod(new 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) \
dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
return &fields; \
} \
static 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; \
dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor*) { \
return &fields; \
} \
static dbTableDescriptor dbDescriptor
/**
* Register table descriptor and assign it to specified database
*/
#define REGISTER_IN(table, database) \
dbTableDescriptor* dbGetTableDescriptor(table*) \
{ return &table::dbDescriptor; } \
static dbFieldDescriptor* dbDescribeComponentsOf##table() \
{ return ((table*)0)->dbDescribeComponents(NULL); } \
dbTableDescriptor table::dbDescriptor(#table, database, sizeof(table), \
&dbDescribeComponentsOf##table)
/**
* Register table descripttor. It will be assigned to the database when database will be
* opened
*/
#define REGISTER(table) REGISTER_IN(table, NULL)
/**
* Register database and mark it as unsigned. Programmer should explicitly
* specify database in all operations.
*/
#define DETACHED_TABLE ((dbDatabase*)-1)
#define REGISTER_UNASSIGNED(table) REGISTER_IN(table, DETACHED_TABLE)
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);
/**
* Store record fields in the databases
* This method performs interation thtough all components in one scope
* and recursively invoke itself for structure and array components.
* @param dst place in the database where record should be stored
* @param src pointer to the application object
* @param offset to the end of varying part
* @param insert flag used to distringuish update fro insert (needed for autoincremented fields)
* @return size of the record
*/
size_t storeRecordFields(byte* dst, byte* src, size_t offs, bool insert);
/**
* Mask updated fields.
* This method performs interation thtough all components in one scope
* and recursively invoke itself for structure and array components.
* @param dst old image of the record in the database
* @param src updated application object
*/
void markUpdatedFields(byte* dst, byte* src);
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -