📄 class.cpp
字号:
{ cloneOf = original; isStatic = true; if (original == NULL) { next = chain; chain = this; } name = tableName; dbSymbolTable::add(name, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER); describeComponentsFunc = func; columns = (*func)(); nextFieldLink = &firstField; hashedFields = NULL; indexedFields = NULL; inverseFields = NULL; tableId = 0; nFields = 0; nColumns = 0; db = database; fixedDatabase = database != NULL; fixedSize = sizeof(dbRecord); int attr = dbFieldDescriptor::OneToOneMapping; appSize = 0; autoincrementCount = initialAutoincrementCount; size_t maxAlignment = calculateFieldsAttributes(columns, "", sizeof(dbRecord), HASHED|INDEXED, attr);#if CHECK_RECORD_SIZE appSize = DOALIGN(appSize, maxAlignment); if (appSize < objSize) { fprintf(stderr, "Warning: may be not all fields of the class '%s' " "were described\n", name); }#endif *nextFieldLink = NULL;}int dbTableDescriptor::calculateFieldsAttributes(dbFieldDescriptor* first, char const* prefix, int offs, int indexMask, int& attr){ dbFieldDescriptor *field = first; size_t alignment = 1; do { if (field->method) { assert(((void)"Not empty record", field != first)); do { assert(((void)"Methods should be specified after variables", field->method != NULL)); field->dbsOffs = first->dbsOffs; field->components = first; if (attr & dbFieldDescriptor::OneToOneMapping) { field->method = field->method->optimize(); } } while ((field = field->next) != first); break; } if (*prefix != '\0') { char* p = new char[strlen(prefix)+strlen(field->name)+1]; sprintf(p, "%s%s", prefix, field->name); field->longName = p; } else { nColumns += 1; field->longName = new char[strlen(field->name)+1]; strcpy(field->longName, field->name); } field->defTable = this; field->indexType &= indexMask|DB_FIELD_INHERITED_MASK; field->attr = (attr & dbFieldDescriptor::ComponentOfArray) | dbFieldDescriptor::OneToOneMapping; if (field->inverseRefName) { assert(!(attr & dbFieldDescriptor::ComponentOfArray) && (field->type == dbField::tpReference || (field->type == dbField::tpArray && field->components->type==dbField::tpReference))); field->nextInverseField = inverseFields; inverseFields = field; } *nextFieldLink = field; nextFieldLink = &field->nextField; field->fieldNo = nFields++; switch (field->type) { case dbField::tpArray: { size_t saveOffs = fixedSize; size_t saveAppSize = appSize; fixedSize = 0; attr = (attr | dbFieldDescriptor::HasArrayComponents) & ~dbFieldDescriptor::OneToOneMapping; field->attr |= dbFieldDescriptor::ComponentOfArray; calculateFieldsAttributes(field->components, field->longName, 0, 0, field->attr); if (field->components->dbsSize != field->components->appSize) { field->attr &= ~dbFieldDescriptor::OneToOneMapping; } fixedSize = saveOffs; appSize = DOALIGN(saveAppSize, sizeof(void*)) + sizeof(void*)*3; break; } case dbField::tpStructure: { char* aggregateName = new char[strlen(field->longName) + 2]; sprintf(aggregateName, "%s.", field->longName); size_t saveOffs = fixedSize; size_t saveAppSize = appSize; appSize = 0; size_t struct_alignment = calculateFieldsAttributes(field->components, aggregateName, offs + field->appOffs, field->indexType, field->attr); field->alignment = struct_alignment; field->dbsOffs = field->components->dbsOffs; attr |= field->attr & dbFieldDescriptor::HasArrayComponents; attr &= field->attr | ~dbFieldDescriptor::OneToOneMapping; field->dbsSize = DOALIGN(fixedSize-saveOffs, struct_alignment); if ((field->attr & dbFieldDescriptor::HasArrayComponents) && struct_alignment < sizeof(void*)) { struct_alignment = sizeof(void*); } appSize = DOALIGN(appSize, struct_alignment) + DOALIGN(saveAppSize, struct_alignment); delete[] aggregateName; break; } case dbField::tpString: attr = (attr | dbFieldDescriptor::HasArrayComponents) & ~dbFieldDescriptor::OneToOneMapping; // no break default: appSize = DOALIGN(appSize, field->appSize) + field->appSize; } if (alignment < field->alignment) { alignment = field->alignment; } if (field->type != dbField::tpStructure) { field->dbsOffs = fixedSize = DOALIGN(fixedSize, field->alignment); fixedSize += field->dbsSize; if (field->dbsOffs != offs + field->appOffs) { attr &= ~dbFieldDescriptor::OneToOneMapping; } if (field->indexType & (HASHED|INDEXED)) { assert(!(field->attr & dbFieldDescriptor::ComponentOfArray)); if (field->indexType & HASHED) { field->nextHashedField = hashedFields; hashedFields = field; } if (field->indexType & INDEXED) { field->nextIndexedField = indexedFields; indexedFields = field; } } } } while ((field = field->next) != first); return alignment;}int dbFieldDescriptor::sizeWithoutOneField(dbFieldDescriptor* field, byte* base, size_t& size){ dbFieldDescriptor* fd = this; int offs, last = 0; do { if (fd != field) { if (fd->type == dbField::tpArray || fd->type == dbField::tpString){ dbVarying* arr = (dbVarying*)(base + fd->dbsOffs); if (arr->offs > last) { last = arr->offs; } int n = arr->size; size = DOALIGN(size, fd->components->alignment) + fd->components->dbsSize * n; if (fd->attr & HasArrayComponents) { byte* elem = base + arr->offs; while (--n >= 0) { offs = fd->components->sizeWithoutOneField(field, elem, size); if (arr->offs + offs > last) { last = arr->offs + offs; } elem += fd->components->dbsSize; } } } else if (fd->attr & HasArrayComponents) { offs = fd->components->sizeWithoutOneField(field, base, size); if (offs > last) { last = offs; } } } } while ((fd = fd->next) != this); return last;}size_t dbFieldDescriptor::copyRecordExceptOneField(dbFieldDescriptor* field, byte* dst, byte* src, size_t offs){ dbFieldDescriptor* fd = this; do { if (fd != field) { if (fd->type == dbField::tpArray || fd->type == dbField::tpString){ dbVarying* srcArr = (dbVarying*)(src + fd->dbsOffs); dbVarying* dstArr = (dbVarying*)(dst + fd->dbsOffs); int n = srcArr->size; byte* srcElem = src + srcArr->offs; offs = DOALIGN(offs, fd->components->alignment); byte* dstElem = dst + offs; dstArr->offs = offs; dstArr->size = n; size_t sizeElem = fd->components->dbsSize; size_t offsElem = sizeElem * n; offs += offsElem; if (fd->attr & HasArrayComponents) { while (--n >= 0) { offsElem = fd->components-> copyRecordExceptOneField(field, dstElem, srcElem, offsElem); offsElem -= sizeElem; dstElem += sizeElem; srcElem += sizeElem; } offs += offsElem; } else { memcpy(dstElem, srcElem, offsElem); } } else if (fd->attr & HasArrayComponents) { offs = fd->components->copyRecordExceptOneField(field, dst, src, offs); } else if (fd->method == NULL) { memcpy(dst+fd->dbsOffs, src+fd->dbsOffs, fd->dbsSize); } } } while ((fd = fd->next) != this); 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); if (fd->inverseRef == NULL || fd->inverseRef->inverseRefName != fd->name) { char msg[256]; if (fd->inverseRef == NULL) { sprintf(msg, "Failed to locate inverse reference field %s.%s for field %s.%s", refTable->name, fd->inverseRefName, fd->defTable->name, fd->longName); } else { sprintf(msg, "Inverse references for field %s.%s is %s.%s, but its inverse reference is %s", fd->defTable->name, fd->longName, refTable->name, fd->inverseRefName, fd->inverseRef->inverseRefName); } db->handleError(dbDatabase::InconsistentInverseReference, msg); } }}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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -