📄 class.cpp
字号:
for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) {
if (strcmp(fd->longName, (char*)field + field->name.offs) != 0
|| (!fd->refTable && *((char*)field+field->tableName.offs) != '\0')
|| (fd->refTable && strcmp((char*)field + field->tableName.offs,
fd->refTable->name) != 0)
|| (fd->inverseRefName == NULL
&& *((char*)field + field->inverse.offs) != '\0')
|| (fd->inverseRefName != NULL
&& strcmp((char*)field + field->inverse.offs,
fd->inverseRefName) != 0)
|| fd->dbsOffs != field->offset
#ifndef OLD_FIELD_DESCRIPTOR_FORMAT
|| fd->indexType != (int)field->flags
#endif
|| fd->type != field->type)
{
return false;
}
fd->tTree = field->tTree;
fd->hashTable = field->hashTable;
field += 1;
}
return true;
}
dbTableDescriptor::dbTableDescriptor(dbTable* table)
{
cloneOf = NULL;
isStatic = false;
name = (char*)table + table->name.offs;
dbSymbolTable::add(name, tkn_ident, true);
nextFieldLink = &firstField;
hashedFields = NULL;
indexedFields = NULL;
inverseFields = NULL;
nFields = 0;
nColumns = 0;
fixedSize = table->fixedSize;
int attr = 0;
appSize = 0;
columns = buildFieldsList(table, "", 0, attr);
*nextFieldLink = NULL;
db = NULL;
fixedDatabase = false;
tableId = 0;
#ifdef AUTOINCREMENT_SUPPORT
autoincrementCount = table->count;
#endif
}
struct _abool { char n; bool v; };
struct _aint1 { char n; int1 v; };
struct _aint2 { char n; int2 v; };
struct _aint4 { char n; int4 v; };
struct _aint8 { char n; db_int8 v; };
struct _areal4 { char n; real4 v; };
struct _areal8 { char n; real8 v; };
struct _astring { char n; char *v; };
struct _arawbinary { char n; char v[1]; };
struct _areference { char n; oid_t v; };
struct _aarray { char n; void* v; };
struct _arectangle { char n; rectangle v; };
#define COMPUTE_ALIGNED_SIZE(type) offsetof(_a##type, v)
dbFieldDescriptor* dbTableDescriptor::buildFieldsList(dbTable* table,
char const* prefix,
int prefixLen,
int& attr)
{
dbFieldDescriptor* components = NULL;
dbField* field = (dbField*)((char*)table+table->fields.offs) + nFields;
while (nFields < table->fields.size
&& strncmp((char*)field + field->name.offs, prefix, prefixLen) == 0)
{
char* longName = (char*)field + field->name.offs;
char* name = longName + prefixLen;
if (*name == '.') {
name += 1;
} else if (prefixLen != 0 && *name != '[') {
break;
}
dbSymbolTable::add(name, tkn_ident, true);
dbFieldDescriptor* fd = new dbFieldDescriptor(name);
fd->dbsOffs = field->offset;
fd->alignment = fd->dbsSize = field->size;
fd->longName = new char[strlen(longName)+1];
strcpy(fd->longName, longName);
fd->type = fd->appType = field->type;
fd->indexType = field->flags;
int appFieldSize, appAlignedFieldSize;
switch (field->type) {
case dbField::tpBool:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(bool);
appFieldSize = sizeof(bool);
break;
case dbField::tpInt1:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int1);
appFieldSize = sizeof(int1);
break;
case dbField::tpInt2:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int2);
appFieldSize = sizeof(int2);
break;
case dbField::tpInt4:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int4);
appFieldSize = sizeof(int4);
break;
case dbField::tpInt8:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(int8);
appFieldSize = sizeof(db_int8);
break;
case dbField::tpReal4:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real4);
appFieldSize = sizeof(real4);
break;
case dbField::tpReal8:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(real8);
appFieldSize = sizeof(real8);
break;
case dbField::tpString:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(string);
appFieldSize = sizeof(char *);
break;
case dbField::tpRawBinary:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(rawbinary);
appFieldSize = field->size;
break;
case dbField::tpReference:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(reference);
appFieldSize = sizeof(dbAnyReference);
break;
case dbField::tpArray:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(array);
appFieldSize = sizeof(dbArray<byte>);
break;
case dbField::tpRectangle:
appAlignedFieldSize = COMPUTE_ALIGNED_SIZE(rectangle);
appFieldSize = sizeof(rectangle);
break;
default:
appAlignedFieldSize = 1;
appFieldSize = 0;
}
fd->appOffs = appSize = DOALIGN(appSize, appAlignedFieldSize);
appSize += fd->appSize = appFieldSize;
if ((fd->hashTable = field->hashTable) != 0) {
fd->nextHashedField = hashedFields;
hashedFields = fd;
}
if ((fd->tTree = field->tTree) != 0) {
fd->nextIndexedField = indexedFields;
indexedFields = fd;
}
fd->fieldNo = nFields++;
fd->defTable = this;
fd->refTable = NULL;
fd->refTableName = NULL;
if (field->hashTable != 0) {
fd->indexType |= HASHED;
}
if (field->tTree != 0) {
fd->indexType |= INDEXED;
}
if (field->tableName.size > 1) {
fd->refTableName = (char*)field + field->tableName.offs;
dbSymbolTable::add(fd->refTableName, tkn_ident, true);
}
fd->inverseRefName = NULL;
if (field->inverse.size > 1) {
fd->nextInverseField = inverseFields;
inverseFields = fd;
fd->inverseRefName = (char*)field + field->inverse.offs;
dbSymbolTable::add(fd->inverseRefName, tkn_ident, true);
}
fd->attr = (attr & dbFieldDescriptor::ComponentOfArray) | dbFieldDescriptor::OneToOneMapping;
*nextFieldLink = fd;
nextFieldLink = &fd->nextField;
if (prefixLen == 0) {
nColumns += 1;
}
if (components == NULL) {
components = fd;
} else {
fd->next = components;
fd->prev = components->prev;
components->prev->next = fd;
components->prev = fd;
}
if (fd->type == dbField::tpArray || fd->type == dbField::tpString) {
attr = (attr | dbFieldDescriptor::HasArrayComponents)
& ~dbFieldDescriptor::OneToOneMapping;
fd->attr |= dbFieldDescriptor::ComponentOfArray;
fd->alignment = 4;
}
if (fd->type == dbField::tpArray || fd->type == dbField::tpStructure) {
int saveAppSize = appSize;
appSize = 0;
fd->components =
buildFieldsList(table, longName, strlen(longName), fd->attr);
attr |= fd->attr & dbFieldDescriptor::HasArrayComponents;
attr &= fd->attr | ~dbFieldDescriptor::OneToOneMapping;
field = (dbField*)((char*)table + table->fields.offs) + nFields;
if (fd->type == dbField::tpStructure) {
size_t alignment = 1;
dbFieldDescriptor* component = fd->components;
do {
if (component->alignment > alignment) {
alignment = component->alignment;
}
} while ((component = component->next) != fd->components);
fd->alignment = alignment;
fd->appSize = appSize = DOALIGN(appSize, alignment);
fd->appOffs = saveAppSize = DOALIGN(saveAppSize, alignment);
appSize += saveAppSize;
} else {
appSize = saveAppSize;
switch (fd->components->type) {
case dbField::tpString:
fd->arrayAllocator = &dbArray<char*>::arrayAllocator;
fd->attr &= ~dbFieldDescriptor::OneToOneMapping;
break;
case dbField::tpBool:
fd->arrayAllocator = &dbArray<bool>::arrayAllocator;
break;
case dbField::tpInt1:
fd->arrayAllocator = &dbArray<int1>::arrayAllocator;
break;
case dbField::tpInt2:
fd->arrayAllocator = &dbArray<int2>::arrayAllocator;
break;
case dbField::tpInt4:
fd->arrayAllocator = &dbArray<int4>::arrayAllocator;
break;
case dbField::tpInt8:
fd->arrayAllocator = &dbArray<int8>::arrayAllocator;
break;
case dbField::tpReal4:
fd->arrayAllocator = &dbArray<real4>::arrayAllocator;
break;
case dbField::tpReal8:
fd->arrayAllocator = &dbArray<real8>::arrayAllocator;
break;
case dbField::tpReference:
fd->arrayAllocator = &dbArray<dbAnyReference>::arrayAllocator;
break;
default:
fd->arrayAllocator = &dbAnyArray::arrayAllocator;
break;
}
}
} else {
if (fd->type == dbField::tpString) {
fd->components = new dbFieldDescriptor("[]");
fd->components->type = fd->components->appType = dbField::tpInt1;
fd->components->dbsSize = fd->components->appSize = 1;
fd->components->alignment = 1;
}
field += 1;
}
}
return components;
}
size_t dbTableDescriptor::totalNamesLength()
{
dbFieldDescriptor* fd;
size_t len = strlen(name) + 1;
for (fd = firstField; fd != NULL; fd = fd->nextField) {
if (fd->name != NULL) {
len += strlen(fd->longName) + 3;
if (fd->inverseRefName != NULL) {
len += strlen(fd->inverseRefName);
}
if (fd->refTable != NULL) {
len += strlen(fd->refTable->name);
}
}
}
return len;
}
dbTableDescriptor* dbTableDescriptor::clone()
{
return new dbTableDescriptor(name,
DETACHED_TABLE,
appSize,
describeComponentsFunc,
this);
}
dbTableDescriptor::~dbTableDescriptor()
{
if (isStatic) {
unlink();
}
dbFieldDescriptor* last = columns->prev;
while (last->method != NULL) {
dbFieldDescriptor* prev = last->prev;
delete last->method;
delete last;
if (last == columns) {
break;
}
last = prev;
}
dbFieldDescriptor *field, *nextField;
for (field = firstField; field != NULL; field = nextField) {
nextField = field->nextField;
delete field;
}
}
void dbTableDescriptor::cleanup()
{
delete chainMutex;
chainMutex = NULL;
}
void dbTableDescriptor::storeInDatabase(dbTable* table)
{
int offs = sizeof(dbTable) + sizeof(dbField)*nFields;
table->name.offs = offs;
table->name.size = strlen(name)+1;
strcpy((char*)table + offs, name);
offs += table->name.size;
table->fields.offs = sizeof(dbTable);
table->fields.size = nFields;
table->nRows = 0;
table->nColumns = nColumns;
table->fixedSize = fixedSize;
table->firstRow = 0;
table->lastRow = 0;
#ifdef AUTOINCREMENT_SUPPORT
if (autoincrementCount < initialAutoincrementCount) {
autoincrementCount = initialAutoincrementCount;
}
table->count = autoincrementCount;
#endif
dbFieldDescriptor* fd;
dbField* field = (dbField*)((char*)table + table->fields.offs);
offs -= sizeof(dbTable);
for (fd = firstField; fd != NULL; fd = fd->nextField) {
field->name.offs = offs;
field->name.size = strlen(fd->longName) + 1;
strcpy((char*)field + offs, fd->longName);
offs += field->name.size;
field->tableName.offs = offs;
if (fd->refTable != NULL) {
field->tableName.size = strlen(fd->refTable->name) + 1;
strcpy((char*)field + offs, fd->refTable->name);
} else if (fd->refTableName != NULL) {
field->tableName.size = strlen(fd->refTableName) + 1;
strcpy((char*)field + offs, fd->refTableName);
} else {
field->tableName.size = 1;
*((char*)field + offs) = '\0';
}
offs += field->tableName.size;
field->inverse.offs = offs;
if (fd->inverseRefName != NULL) {
field->inverse.size = strlen(fd->inverseRefName) + 1;
strcpy((char*)field + offs, fd->inverseRefName);
} else {
field->inverse.size = 1;
*((char*)field + offs) = '\0';
}
offs += field->inverse.size;
field->tTree = fd->tTree;
field->hashTable = fd->hashTable;
field->type = fd->type;
field->size = fd->dbsSize;
field->offset = fd->dbsOffs;
field->flags = fd->indexType;
field += 1;
offs -= sizeof(dbField);
}
}
void* dbAnyMethodTrampoline::operator new(size_t size EXTRA_DEBUG_NEW_PARAMS)
{
return dbMalloc(size);
}
void dbAnyMethodTrampoline::operator delete(void* p EXTRA_DEBUG_NEW_PARAMS)
{
dbFree(p);
}
dbAnyMethodTrampoline::~dbAnyMethodTrampoline() {}
END_FASTDB_NAMESPACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -