?? class.cpp
字號:
//-< CLASS.CPP >-----------------------------------------------------*--------*
// FastDB Version 1.0 (c) 1999 GARRET * ? *
// (Main Memory Database Management System) * /\| *
// * / \ *
// Created: 20-Nov-98 K.A. Knizhnik * / [] \ *
// Last update: 1-Jan-99 K.A. Knizhnik * GARRET *
//-------------------------------------------------------------------*--------*
// Metaclass information
//-------------------------------------------------------------------*--------*
#define INSIDE_FASTDB
#include "fastdb.h"
#include "compiler.h"
#include "symtab.h"
#ifndef CHECK_RECORD_SIZE
#define CHECK_RECORD_SIZE 1
#endif
dbTableDescriptor* dbTableDescriptor::chain;
void* dbFieldDescriptor::operator new(size_t size EXTRA_DEBUG_NEW_PARAMS)
{
return dbMalloc(size);
}
void dbFieldDescriptor::operator delete(void* p EXTRA_DEBUG_NEW_PARAMS)
{
dbFree(p);
}
dbFieldDescriptor::dbFieldDescriptor(char* name)
{
next = prev = this;
this->name = name;
longName = NULL;
dbSymbolTable::add
(this->name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER);
appOffs = dbsOffs = 0;
defTable = refTable = NULL;
refTableName = NULL;
components = NULL;
inverseRefName = NULL;
indexType = 0;
method = NULL;
attr = OneToOneMapping;
tTree = 0;
hashTable = 0;
comparator = (dbUDTComparator)&memcmp;
}
dbFieldDescriptor::dbFieldDescriptor(char* fieldName,
int offs,
int size,
int index,
char* inverse,
dbFieldDescriptor* fieldComponents)
{
next = prev = this;
name = fieldName;
longName = NULL;
dbSymbolTable::add
(name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER);
appOffs = offs;
dbsOffs = 0;
alignment = appSize = dbsSize = size;
defTable = refTable = NULL;
indexType = index;
type = appType = dbField::tpStructure;
inverseRefName = inverse;
if (inverseRefName != NULL)
{
dbSymbolTable::add
(inverseRefName, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER);
}
inverseRef = NULL;
components = fieldComponents;
method = NULL;
attr = 0;
tTree = 0;
hashTable = 0;
comparator = (dbUDTComparator)&memcmp;
}
dbFieldDescriptor::~dbFieldDescriptor()
{
if (type == dbField::tpString)
{
delete components;
}
else if (type == dbField::tpStructure)
{
dbFieldDescriptor* last = components->prev;
while (last->method != NULL)
{
dbFieldDescriptor* prev = last->prev;
delete last->method;
delete last;
if (last == components)
{
break;
}
last = prev;
}
}
delete[] longName;
}
dbFieldDescriptor* dbFieldDescriptor::find(const char* name)
{
dbFieldDescriptor* field = components;
do
{
if (field->name == name)
{
return field;
}
}
while ((field = field->next) != components);
return NULL;
}
void dbFieldDescriptor::adjustReferences(byte* record,
size_t base, size_t size, long shift)
{
dbFieldDescriptor* fd = this;
do
{
if (fd->type == dbField::tpArray)
{
byte** ptr = (byte**)((dbAnyArray*)(record + fd->appOffs) + 1);
if ((unsigned long)*ptr - base <= size)
{
*ptr += shift;
}
else
{
if (fd->attr & HasArrayComponents)
{
int nElems = ((dbAnyArray*)(record+fd->appOffs))->length();
byte* arrBase = *ptr;
while (--nElems >= 0)
{
fd->components->adjustReferences(arrBase,
base, size, shift);
arrBase += fd->components->appSize;
}
}
}
}
else if (fd->type == dbField::tpString)
{
char** str = (char**)(record + fd->appOffs);
if ((unsigned long)*str - base <= size)
{
*str += shift;
}
}
else if (fd->attr & HasArrayComponents)
{
fd->components->adjustReferences(record + fd->appOffs,
base, size, shift);
}
}
while ((fd = fd->next) != this);
}
size_t dbFieldDescriptor::calculateRecordSize(byte* base, size_t offs)
{
dbFieldDescriptor* fd = this;
do
{
switch (fd->appType)
{
case dbField::tpArray:
{
int nElems = ((dbAnyArray*)(base + fd->appOffs))->length();
offs = DOALIGN(offs, fd->components->alignment)
+ nElems*fd->components->dbsSize;
if (fd->attr & HasArrayComponents)
{
byte* elem = (byte*)((dbAnyArray*)(base+fd->appOffs))->base();
dbFieldDescriptor* component = fd->components;
size_t elemSize = component->appSize;
while (--nElems >= 0)
{
offs = component->calculateRecordSize(elem, offs);
elem += elemSize;
}
}
continue;
}
case dbField::tpString:
{
char* str = *(char**)(base + fd->appOffs);
if (str != NULL)
{
offs += strlen(str) + 1;
}
else
{
offs += 1;
}
continue;
}
#ifdef USE_STD_STRING
case dbField::tpStdString:
offs += ((std::string*)(base + fd->appOffs))->length() + 1;
continue;
#endif
default:
if (fd->attr & HasArrayComponents)
{
offs = fd->components->calculateRecordSize(base+fd->appOffs, offs);
}
}
}
while ((fd = fd->next) != this);
return offs;
}
size_t dbFieldDescriptor::calculateNewRecordSize(byte* base, size_t offs)
{
dbFieldDescriptor* fd = this;
do
{
if (fd->type == dbField::tpArray)
{
if (fd->oldDbsType == dbField::tpUnknown)
{
continue;
}
int nElems = ((dbVarying*)(base + fd->oldDbsOffs))->size;
offs = DOALIGN(offs, fd->components->alignment)
+ nElems*fd->components->dbsSize;
if (fd->attr & HasArrayComponents)
{
byte* elem = base + ((dbVarying*)(base+fd->oldDbsOffs))->offs;
while (--nElems >= 0)
{
offs = fd->components->calculateNewRecordSize(elem, offs);
elem += fd->components->oldDbsSize;
}
}
}
else if (fd->type == dbField::tpString)
{
if (fd->oldDbsType == dbField::tpUnknown)
{
offs += 1;
}
else
{
offs += ((dbVarying*)(base + fd->oldDbsOffs))->size;
}
}
else if (fd->attr & HasArrayComponents)
{
offs = fd->components->calculateNewRecordSize(base, offs);
}
}
while ((fd = fd->next) != this);
return offs;
}
void dbFieldDescriptor::fetchRecordFields(byte* dst, byte* src)
{
dbFieldDescriptor* fd = this;
do
{
switch (fd->appType)
{
case dbField::tpBool:
*(bool*)(dst+fd->appOffs) = *(bool*)(src+fd->dbsOffs);
break;
case dbField::tpInt1:
*(int1*)(dst+fd->appOffs) = *(int1*)(src+fd->dbsOffs);
break;
case dbField::tpInt2:
*(int2*)(dst+fd->appOffs) = *(int2*)(src+fd->dbsOffs);
break;
case dbField::tpInt4:
*(int4*)(dst+fd->appOffs) = *(int4*)(src+fd->dbsOffs);
break;
case dbField::tpInt8:
*(db_int8*)(dst+fd->appOffs) = *(db_int8*)(src+fd->dbsOffs);
break;
case dbField::tpReal4:
*(real4*)(dst+fd->appOffs) = *(real4*)(src+fd->dbsOffs);
break;
case dbField::tpReal8:
*(real8*)(dst+fd->appOffs) = *(real8*)(src+fd->dbsOffs);
break;
case dbField::tpRawBinary:
memcpy(dst+fd->appOffs, src+fd->dbsOffs, fd->dbsSize);
break;
case dbField::tpString:
*(char**)(dst+fd->appOffs) =
(char*)(src + ((dbVarying*)(src+fd->dbsOffs))->offs);
break;
#ifdef USE_STD_STRING
case dbField::tpStdString:
((std::string*)(dst + fd->appOffs))->assign((char*)(src + ((dbVarying*)(src+fd->dbsOffs))->offs),
((dbVarying*)(src+fd->dbsOffs))->size - 1);
break;
#endif
case dbField::tpArray:
{
int nElems = ((dbVarying*)(src+fd->dbsOffs))->size;
byte* srcElem = src + ((dbVarying*)(src+fd->dbsOffs))->offs;
dbAnyArray* array = (dbAnyArray*)(dst+fd->appOffs);
if (fd->attr & dbFieldDescriptor::OneToOneMapping)
{
fd->arrayAllocator(array, srcElem, nElems);
}
else
{
fd->arrayAllocator(array, NULL, nElems);
byte* dstElem = (byte*)array->base();
dbFieldDescriptor* component = fd->components;
while (--nElems >= 0)
{
component->fetchRecordFields(dstElem, srcElem);
dstElem += component->appSize;
srcElem += component->dbsSize;
}
}
}
break;
case dbField::tpReference:
((dbAnyReference*)(dst+fd->appOffs))->oid =
*(oid_t*)(src+fd->dbsOffs);
break;
case dbField::tpStructure:
fd->components->fetchRecordFields(dst + fd->appOffs, src);
break;
default:
return;
}
}
while ((fd = fd->next) != this);
}
size_t dbFieldDescriptor::storeRecordFields(byte* dst, byte* src, size_t offs, bool insert)
{
dbFieldDescriptor* fd = this;
do
{
#ifdef AUTOINCREMENT_SUPPORT
if (insert && (fd->indexType & AUTOINCREMENT) != 0)
{
assert (fd->appType == dbField::tpInt4);
*(int4*)(dst+fd->dbsOffs) = *(int4*)(src+fd->appOffs) = fd->defTable->autoincrementCount;
continue;
}
#endif
switch (fd->appType)
{
case dbField::tpBool:
*(bool*)(dst+fd->dbsOffs) = *(bool*)(src+fd->appOffs);
break;
case dbField::tpInt1:
*(int1*)(dst+fd->dbsOffs) = *(int1*)(src+fd->appOffs);
break;
case dbField::tpInt2:
*(int2*)(dst+fd->dbsOffs) = *(int2*)(src+fd->appOffs);
break;
case dbField::tpInt4:
*(int4*)(dst+fd->dbsOffs) = *(int4*)(src+fd->appOffs);
break;
case dbField::tpInt8:
*(db_int8*)(dst+fd->dbsOffs) = *(db_int8*)(src+fd->appOffs);
break;
case dbField::tpReal4:
*(real4*)(dst+fd->dbsOffs) = *(real4*)(src+fd->appOffs);
break;
case dbField::tpReal8:
*(real8*)(dst+fd->dbsOffs) = *(real8*)(src+fd->appOffs);
break;
case dbField::tpRawBinary:
memcpy(dst+fd->dbsOffs, src+fd->appOffs, fd->dbsSize);
break;
#ifdef USE_STD_STRING
case dbField::tpStdString:
{
((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
std::string* str = (std::string*)(src + fd->appOffs);
int len = str->length();
str->copy((char*)dst + offs, len);
dst[offs + len] = '\0';
((dbVarying*)(dst+fd->dbsOffs))->size = len+1;
offs += (len+1);
}
break;
#endif
case dbField::tpString:
{
((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
char* str = *(char**)(src + fd->appOffs);
if (str != NULL)
{
strcpy((char*)dst + offs, str);
offs += ((dbVarying*)(dst+fd->dbsOffs))->size
= strlen(*(char**)(src + fd->appOffs)) + 1;
}
else
{
*((char*)dst + offs) = '\0';
offs += 1;
}
}
break;
case dbField::tpArray:
{
int nElems = ((dbAnyArray*)(src + fd->appOffs))->length();
byte* srcElem=(byte*)((dbAnyArray*)(src+fd->appOffs))->base();
offs = DOALIGN(offs, fd->components->alignment);
byte* dstElem = dst+offs;
((dbVarying*)(dst+fd->dbsOffs))->size = nElems;
((dbVarying*)(dst+fd->dbsOffs))->offs = offs;
size_t sizeElem = fd->components->dbsSize;
size_t offsElem = nElems*sizeElem;
offs += offsElem;
if (srcElem != NULL)
{
if (fd->attr & dbFieldDescriptor::OneToOneMapping)
{
memcpy(dstElem, srcElem, offsElem);
}
else
{
dbFieldDescriptor* component = fd->components;
while (--nElems >= 0)
{
offsElem =
component->storeRecordFields(dstElem,
srcElem, offsElem, insert);
offsElem -= sizeElem;
dstElem += sizeElem;
srcElem += component->appSize;
}
offs += offsElem;
}
}
}
break;
case dbField::tpReference:
*(oid_t*)(dst+fd->dbsOffs) =
((dbAnyReference*)(src+fd->appOffs))->oid;
break;
case dbField::tpStructure:
offs = fd->components->storeRecordFields(dst, src+fd->appOffs, offs, insert);
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -