📄 class.h
字号:
tpMethodInt1,
tpMethodInt2,
tpMethodInt4,
tpMethodInt8,
tpMethodReal4,
tpMethodReal8,
tpMethodString,
tpMethodReference,
tpStructure,
tpRawBinary,
tpStdString,
tpUnknown
};
/**
* Full name of the field (for example "x.y.z")
*/
dbVarying name;
/**
* Name of referenced table( only for references)
*/
dbVarying tableName;
/**
* Name of inverse reference field (only for refereces)
*/
dbVarying inverse;
/**
* Field type: one of <code>dbField::FieldTypes</code> constants
*/
int4 type;
/**
* Offset of the field in the record
*/
int4 offset;
/**
* Size of the field
*/
nat4 size;
/**
* Hash table for hashed field
*/
oid_t hashTable;
/**
* T-Tree for field indexed by means of T-Ttree
*/
oid_t tTree;
};
/**
* Header of any database record
*/
class dbRecord
{
public:
/**
* Size of the record (including header
*/
nat4 size;
/**
* Next record in the table (0 if it is last record)
*/
oid_t next;
/**
* Previous record in the table (0 if it is first record)
*/
oid_t prev;
};
/**
* Database recod for storing table descriptor
*/
class dbTable : public dbRecord
{
public:
/**
* Name of the table
*/
dbVarying name;
/**
* Array with field descriptors
*/
dbVarying fields;
/**
* Size of fixed part of the record (without string and arrays bodies)
*/
nat4 fixedSize;
/**
* Number of rows in the table
*/
nat4 nRows;
/**
* Number of columns in the table
*/
nat4 nColumns;
/**
* Identifier of first row in the table
*/
oid_t firstRow;
/**
* Identifier of last row in the table
*/
oid_t lastRow;
#ifdef AUTOINCREMENT_SUPPORT
/**
* Autoincremented counter
*/
nat4 count;
#endif
};
inline dbFieldDescriptor* dbDescribeRawField(dbFieldDescriptor* fd, dbUDTComparator comparator)
{
fd->type = fd->appType = dbField::tpRawBinary;
fd->alignment = 1;
fd->comparator = comparator;
return fd;
}
template<class T>
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, T& x)
{
fd->type = fd->appType = dbField::tpStructure;
fd->components = x.dbDescribeComponents(fd);
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int1&)
{
fd->type = fd->appType = dbField::tpInt1;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int2&)
{
fd->type = fd->appType = dbField::tpInt2;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, int4&)
{
fd->type = fd->appType = dbField::tpInt4;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, db_int8&)
{
fd->type = fd->appType = dbField::tpInt8;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat1&)
{
fd->type = fd->appType = dbField::tpInt1;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat2&)
{
fd->type = fd->appType = dbField::tpInt2;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat4&)
{
fd->type = fd->appType = dbField::tpInt4;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, nat8&)
{
fd->type = fd->appType = dbField::tpInt8;
return fd;
}
#if SIZEOF_LONG != 8
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, long&)
{
fd->type = fd->appType = dbField::tpInt4;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, unsigned long&)
{
fd->type = fd->appType = dbField::tpInt4;
return fd;
}
#endif
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, bool&)
{
fd->type = fd->appType = dbField::tpBool;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real4&)
{
fd->type = fd->appType = dbField::tpReal4;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, real8&)
{
fd->type = fd->appType = dbField::tpReal8;
return fd;
}
#ifdef USE_STD_STRING
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, std::string&)
{
fd->type = dbField::tpString;
fd->appType = dbField::tpStdString;
fd->dbsSize = sizeof(dbVarying);
fd->alignment = 4;
fd->components = new dbFieldDescriptor("[]");
fd->components->type = fd->components->appType = dbField::tpInt1;
fd->components->dbsSize = fd->components->appSize = fd->components->alignment = 1;
return fd;
}
#endif
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char const*&)
{
fd->type = fd->appType = dbField::tpString;
fd->dbsSize = sizeof(dbVarying);
fd->alignment = 4;
fd->components = new dbFieldDescriptor("[]");
fd->components->type = fd->components->appType = dbField::tpInt1;
fd->components->dbsSize = fd->components->appSize = 1;
fd->components->alignment = 1;
return fd;
}
inline dbFieldDescriptor* dbDescribeField(dbFieldDescriptor* fd, char*&)
{
fd->type = fd->appType = dbField::tpString;
fd->dbsSize = sizeof(dbVarying);
fd->alignment = 4;
fd->components = new dbFieldDescriptor("[]");
fd->components->type = fd->components->appType = dbField::tpInt1;
fd->components->dbsSize = fd->components->appSize = 1;
fd->components->alignment = 1;
return fd;
}
/**
* Trampolinefor invocation of methods from SubSQL
*/
class FASTDB_DLL_ENTRY dbAnyMethodTrampoline
{
public:
dbFieldDescriptor* cls;
/**
* Invoke method
* @param data pointer to the record insode database
* @param result pointer to place result in
*/
virtual void invoke(byte* data, void* result) = 0;
/**
* Get optimize trampoline. Optimized trampoline can be used for records
* which format in the database is the same as in application. In this case
* there is no need to fetch record and pointer insode database can be used intead
* @return optimized nethod trampoline
*/
virtual dbAnyMethodTrampoline* optimize() = 0;
/**
* Method tramopile constructor
* @param fd method descriptor
*/
dbAnyMethodTrampoline(dbFieldDescriptor* fd)
{
cls = fd;
}
void* operator new(size_t size EXTRA_DEBUG_NEW_PARAMS);
void operator delete(void* p EXTRA_DEBUG_NEW_PARAMS);
/**
* Trampoline desctructor
*/
virtual~dbAnyMethodTrampoline();
};
#if defined(__APPLE__) || defined(__VACPP_MULTI__) || defined(__IBMCPP__) || \
(__SUNPRO_CC >= 0x520 && __SUNPRO_CC_COMPAT == 5)
/**
* Template for method trampoline implementation
*/
template<class T, class R>
class dbMethodTrampoline : public dbAnyMethodTrampoline
{
public:
typedef R (T::*mfunc)();
mfunc method;
dbFieldDescriptor* cls;
bool optimized;
void invoke(byte* data, void* result)
{
if (optimized)
{
*(R*)result = (((T*)(data + this->cls->dbsOffs))->*method)();
}
else
{
T rec;
cls->components->fetchRecordFields((byte*)&rec, data);
*(R*)result = (rec.*method)();
}
}
dbAnyMethodTrampoline* optimize()
{
optimized = true;
return this;
}
dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
: dbAnyMethodTrampoline(fd), method(f), cls(fd), optimized(false)
{}
}
;
#else
/**
* Template for method trampoline implementation
*/
template<class T, class R>
class dbMethodTrampoline : public dbAnyMethodTrampoline
{
public:
typedef R (T::*mfunc)();
mfunc method;
void invoke(byte* data, void* result)
{
T rec;
cls->components->fetchRecordFields((byte*)&rec, data);
*(R*)result = (rec.*method)();
}
dbAnyMethodTrampoline* optimize();
dbMethodTrampoline(dbFieldDescriptor* fd, mfunc f)
: dbAnyMethodTrampoline(fd), method(f)
{}
}
;
/**
* Optimized method trampoline which doesn't fetch record from the database
* and use direct pointer to the record inside database
*/
template<class T, class R>
class dbMethodFastTrampoline : public dbMethodTrampoline<T,R>
{
public:
void invoke(byte* data, void* result)
{
*(R*)result = (((T*)(data + cls->dbsOffs))->*method)();
}
dbMethodFastTrampoline(dbMethodTrampoline<T,R>* mt)
: dbMethodTrampoline<T,R>(mt->cls, mt->method)
{
delete mt;
}
};
template<class T, class R>
inline dbAnyMethodTrampoline* dbMethodTrampoline<T,R>::optimize()
{
return new dbMethodFastTrampoline<T,R>(this);
}
#endif
template<class T, class R>
inline dbFieldDescriptor* dbDescribeMethod(dbFieldDescriptor* fd, R (T::*p)())
{
R ret;
dbDescribeField(fd, ret);
assert(fd->type <= dbField::tpReference);
fd->appType = fd->type += dbField::tpMethodBool;
fd->method = new dbMethodTrampoline<T,R>(fd, p);
return fd;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -