📄 class.cpp
字号:
return offs;}void dbTableDescriptor::checkRelationship() { dbFieldDescriptor* fd; for (fd = inverseFields; fd != NULL; fd = fd->nextInverseField) { dbTableDescriptor* refTable = fd->refTable ? fd->refTable : fd->components->refTable; fd->inverseRef = refTable->findSymbol(fd->inverseRefName); assert(fd->inverseRef != NULL && fd->inverseRef->inverseRefName == fd->name); }}dbFieldDescriptor* dbTableDescriptor::find(char const* name){ char* symnam = (char*)name; dbSymbolTable::add(symnam, tkn_ident); return findSymbol(symnam);}dbFieldDescriptor* dbTableDescriptor::findSymbol(const char* name){ dbFieldDescriptor* first = columns; dbFieldDescriptor* field = first; do { if (field->name == name) { return field; } } while ((field = field->next) != first); return NULL;}dbFieldDescriptor& dbFieldDescriptor::adjustOffsets(long offs){ if (offs != 0) { dbFieldDescriptor* fd = this; do { fd->appOffs += offs; } while ((fd = fd->next) != this); } return *this;}bool dbTableDescriptor::match(dbTable* table, bool confirmDeleteColumns) { unsigned nFields = table->fields.size; unsigned nMatches = 0; bool formatNotChanged = (nFields == this->nFields); for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) { dbField* field = (dbField*)((char*)table + table->fields.offs); fd->oldDbsType = dbField::tpUnknown; for (int n = nFields; --n >= 0; field++) { if (strcmp(fd->longName, (char*)field + field->name.offs) == 0) { assert(((void)"field can be converted to new format", (fd->type == dbField::tpReference && field->type == dbField::tpReference && strcmp((char*)field + field->tableName.offs, fd->refTable->name) == 0) || (fd->type <= dbField::tpReal8 && field->type <= dbField::tpReal8) || (fd->type == dbField::tpString && field->type == dbField::tpString) || (fd->type >= dbField::tpArray && fd->type == field->type))); fd->oldDbsType = field->type; fd->oldDbsOffs = field->offset; fd->oldDbsSize = field->size; if (field->type != fd->type || field->offset != fd->dbsOffs) { formatNotChanged = false; } nMatches += 1; // // Try to reuse indices // fd->hashTable = 0; fd->tTree = 0; if (field->type == fd->type) { if ((fd->indexType & HASHED) != 0 && field->hashTable != 0) { fd->hashTable = field->hashTable; // reuse index field->hashTable = 0; // prevent index from destruction } if ((fd->indexType & INDEXED) != 0 && field->tTree != 0) { fd->tTree = field->tTree; // reuse index field->tTree = 0; // prevent index from destruction } } break; } } } if (!confirmDeleteColumns) { assert(((void)"field can be removed only from empty table", nFields==nMatches)); } return formatNotChanged;}void dbTableDescriptor::setFlags() { for (dbFieldDescriptor* fd = firstField; fd != NULL; fd = fd->nextField) { if (fd->tTree != 0) { fd->indexType |= INDEXED; } else if (fd->hashTable != 0) { fd->indexType |= HASHED; } }}bool dbTableDescriptor::equal(dbTable* table) {#ifdef AUTOINCREMENT_SUPPORT autoincrementCount = table->count;#endif if (nColumns != table->nColumns || nFields != table->fields.size || fixedSize != table->fixedSize) { return false; } dbField* field = (dbField*)((char*)table + table->fields.offs); 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 || fd->type != field->type) { return false; } fd->tTree = field->tTree; fd->hashTable = field->hashTable; field += 1; } return true;}dbTableDescriptor::dbTableDescriptor(dbTable* table){ next = chain; chain = this; 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; tableId = 0;#ifdef AUTOINCREMENT_SUPPORT autoincrementCount = table->count;#endif}class _AlignArray : public dbAnyArray{ protected: void* data; size_t allocated;};class _AlignReference{ protected: oid_t oid;};union _aligns { struct { char n; bool v; } _abool; struct { char n; int1 v; } _aint1; struct { char n; int2 v; } _aint2; struct { char n; int4 v; } _aint4; struct { char n; db_int8 v; } _aint8; struct { char n; real4 v; } _areal4; struct { char n; real8 v; } _areal8; struct { char n; char *v; } _astring; struct { char n; char v[1]; } _arawbinary; struct { char n; _AlignReference v; } _areference; struct { char n; _AlignArray v; } _aarray;} __aligns;#define COMPUTE_ALIGNED_SIZE(type) \ (((char *)&(((union _aligns *)0)->_a##type.v)) - ((char *)&(((union _aligns *)0)->_a##type.n)))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; 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(_AlignArray); 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 |= dbFieldDescriptor::HasArrayComponents; fd->attr |= dbFieldDescriptor::ComponentOfArray; fd->alignment = 4; } if (fd->type == dbField::tpArray || fd->type == dbField::tpStructure) { int saveAppSize = appSize; if (fd->type == dbField::tpArray) { appSize = 0; } fd->components = buildFieldsList(table, longName, strlen(longName), fd->attr); if (fd->type == dbField::tpArray) { appSize = saveAppSize; } attr |= fd->attr & dbFieldDescriptor::HasArrayComponents; 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; } else { if (fd->components->type == dbField::tpString) { fd->arrayAllocator = &dbArray<char*>::arrayAllocator; fd->attr &= ~dbFieldDescriptor::OneToOneMapping; } else { fd->arrayAllocator = &dbAnyArray::arrayAllocator; } } } 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 (cloneOf == NULL) { dbTableDescriptor **tpp; for (tpp = &chain; *tpp != this; tpp = &(*tpp)->next); *tpp = next; } dbFieldDescriptor *field, *nextField; for (field = firstField; field != NULL; field = nextField) { nextField = field->nextField; delete field; }}void dbTableDescriptor::cleanup(){ dbTableDescriptor* next, *desc; for (desc = chain; desc != NULL; desc = next) { next = desc->next; if (!desc->isStatic) { delete desc; } }}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 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 { 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 += 1; offs -= sizeof(dbField); }} dbAnyMethodTrampoline::~dbAnyMethodTrampoline() {}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -