⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{    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 + -