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

📄 subsql.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }
    return true;
}

    
bool dbSubSql::updateTable(bool create)
{
    int tkn;
    dotIsPartOfIdentifier = true;
    if (!expect("table name", tkn_ident) || !expect("(", tkn_lpar)) { 
        return false;
    }
    char* name = this->name;
    int varyingLength = strlen(name)+1;

    static const struct { 
        int size;
        int alignment;
    } typeDesc[] = { 
        { sizeof(bool), sizeof(bool) }, 
        { sizeof(int1), sizeof(int1) }, 
        { sizeof(int2), sizeof(int2) }, 
        { sizeof(int4), sizeof(int4) }, 
        { sizeof(db_int8), sizeof(db_int8) }, 
        { sizeof(real4), sizeof(real4) }, 
        { sizeof(real8), sizeof(real8) }, 
        { sizeof(dbVarying), 4 }, 
        { sizeof(oid_t), sizeof(oid_t) }, 
        { sizeof(dbVarying), 4 },
        {0}, // tpMethodBool,
        {0}, // tpMethodInt1,
        {0}, // tpMethodInt2,
        {0}, // tpMethodInt4,
        {0}, // tpMethodInt8,
        {0}, // tpMethodReal4,
        {0}, // tpMethodReal8,
        {0}, // tpMethodString,
        {0}, // tpMethodReference,
        {0}, // tpStructure,
        {0}, // tpRawBinary,
        {0}, // tpStdString,
        { sizeof(rectangle), sizeof(coord_t) }, // tpRectangle,
        {0} // tpUnknown
    };

    const int maxFields = 256;
    tableField fields[maxFields];
    int nFields = 0;
    int nColumns = 0;
    tkn = tkn_comma;
    while (tkn == tkn_comma) { 
        if (nFields+1 == maxFields) { 
            error("Too many fields");
            break;
        }
        if (!expect("field name", tkn_ident)) { 
            break;
        }
        int nameLen = strlen(buf)+1;
        fields[nFields].name = new char[nameLen];
        strcpy(fields[nFields].name, buf);
        varyingLength += nameLen + 2;
        char* refTableName;
        char* inverseRefName;
        int type = parseType(refTableName, inverseRefName);
        fields[nFields++].type = type;
        if (type == dbField::tpUnknown) { 
            break;
        }
        nColumns += 1;
        if (type == dbField::tpArray) {
            if (nFields+1 == maxFields) { 
                error("Too many fields");
                break;
            }
            fields[nFields].name = new char[nameLen+2];
            sprintf(fields[nFields].name, "%s[]", fields[nFields-1].name);
            varyingLength += nameLen+2+2;
            type = parseType(refTableName, inverseRefName);
            if (type == dbField::tpUnknown) { 
                break;
            }
            if (type == dbField::tpArray) { 
                error("Arrays of arrays are not supported by CLI");
                break;
            }
            if (type == dbField::tpReference) {
                fields[nFields].refTableName = refTableName;
                varyingLength += strlen(refTableName);
                if (inverseRefName != NULL) { 
                    fields[nFields-1].inverseRefName = inverseRefName;
                    varyingLength += strlen(inverseRefName);
                }                   
            }
            fields[nFields++].type = type;
        } else if (type == dbField::tpReference) { 
            fields[nFields-1].refTableName = refTableName;
            varyingLength += strlen(refTableName);
            if (inverseRefName != NULL) { 
                fields[nFields-1].inverseRefName = inverseRefName;
                varyingLength += strlen(inverseRefName);
            }                   
        }
        tkn = scan(); 
    }
    if (tkn == tkn_rpar) { 
        beginTransaction(dbExclusiveLock);
        dbTableDescriptor* oldDesc = findTable(name);
        if (oldDesc != NULL) {
            if (create) { 
                error("Table already exists");
                return false;
            }
        } else { 
            if (!create) { 
                error("Table not found");
                return false;
            }
        }
        dbTable* table; 
        oid_t oid;
        if (create) { 
            modified = true;
            oid = allocateRow(dbMetaTableId, 
                              sizeof(dbTable) + sizeof(dbField)*nFields + varyingLength);
            table = (dbTable*)getRow(oid);    
        } else { 
            oid = oldDesc->tableId;
            table = (dbTable*)new char[sizeof(dbTable) + sizeof(dbField)*nFields + varyingLength];
        }
        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;
        size_t size = sizeof(dbRecord);
        table->fields.offs = sizeof(dbTable);
        dbField* field = (dbField*)((char*)table + table->fields.offs);
        offs -= sizeof(dbTable);
        bool arrayComponent = false;

        for (int i = 0; i < nFields; i++) { 
            field->name.offs = offs;
            field->name.size = strlen(fields[i].name) + 1;
            strcpy((char*)field + offs, fields[i].name);
            offs += field->name.size;
            
            field->tableName.offs = offs;
            if (fields[i].refTableName) { 
                field->tableName.size = strlen(fields[i].refTableName) + 1;
                strcpy((char*)field + offs, fields[i].refTableName);
                offs += field->tableName.size;
            } else { 
                field->tableName.size = 1;
                *((char*)field + offs++) = '\0';
            }

            field->inverse.offs = offs;
            if (fields[i].inverseRefName) { 
                field->inverse.size = strlen(fields[i].inverseRefName) + 1;
                strcpy((char*)field + offs, fields[i].inverseRefName);
                offs += field->inverse.size;
            } else { 
                field->inverse.size = 1;
                *((char*)field + offs++) = '\0';
            }
    
            field->flags = 0;
            field->type = fields[i].type;
            field->size = typeDesc[fields[i].type].size;
            if (!arrayComponent) { 
                size = DOALIGN(size, typeDesc[fields[i].type].alignment);
                field->offset = size;
                size += field->size;
            } else { 
                field->offset = 0;
            }
            field->hashTable = 0;
            field->tTree = 0;
            arrayComponent = field->type == dbField::tpArray; 
            field += 1;
            offs -= sizeof(dbField);
        }
        table->fields.size = nFields;
        table->fixedSize = size;
        table->nRows = 0;
        table->nColumns = nColumns;
        table->firstRow = 0;
        table->lastRow = 0;

        if (create) { 
            linkTable(new dbTableDescriptor(table), oid);
        } else { 
            dbTableDescriptor* newDesc = new dbTableDescriptor(table);      
            delete[] (char*)table;
            dbTable* oldTable = (dbTable*)getRow(oid);
            if (!newDesc->equal(oldTable)) {
                bool saveConfirmDeleteColumns = confirmDeleteColumns; 
                confirmDeleteColumns = true;
                modified = true;
                schemeVersion += 1;
                unlinkTable(oldDesc);
                if (oldTable->nRows == 0) {
                    updateTableDescriptor(newDesc, oid);
                } else {
                    reformatTable(oid, newDesc);
                }
                delete oldDesc;
                confirmDeleteColumns = saveConfirmDeleteColumns;
            }
        }
        completeDescriptorsInitialization();
    }
    return tkn == tkn_rpar;
}

int dbSubSql::parseType(char*& refTableName, char*& inverseFieldName)
{
    switch (scan()) { 
      case tkn_bool:
        return dbField::tpBool;
      case tkn_int1:
        return dbField::tpInt1;
      case tkn_int2:
        return dbField::tpInt2;
      case tkn_int4:
        return dbField::tpInt4;
      case tkn_int8:
        return dbField::tpInt8;
      case tkn_real4:
        return dbField::tpReal4;
      case tkn_real8:
        return dbField::tpReal8;
      case tkn_array:
        return expect("of", tkn_of) ? dbField::tpArray : dbField::tpUnknown;
      case tkn_string:
        return dbField::tpString;
      case tkn_reference:
        if (expect("to", tkn_to) && expect("referenced table name", tkn_ident)) {
            refTableName = new char[strlen(buf)+1];
            strcpy(refTableName, buf);
            int tkn = scan();
            if (tkn == tkn_inverse) {
                if (!expect("inverse reference field name", tkn_ident)) { 
                    return dbField::tpUnknown;
                }
                inverseFieldName = new char[strlen(buf)+1];
                strcpy(inverseFieldName, buf);
            } else { 
                inverseFieldName = NULL;
                ungetToken = tkn;
            }
            return dbField::tpReference;
        } else { 
            return dbField::tpUnknown;
        }
      case tkn_rectangle:
        return dbField::tpRectangle;
      default:
        error("Field type expected");
    }
    return dbField::tpUnknown;
}

int dbSubSql::readExpression()
{
    int i, ch;
    for (i = 0; (ch = get()) != ';' && ch != ',' && ch != EOF; i++) { 
        if (i+1 >= buflen) { 
            char* newbuf = new char[buflen*2];
            memcpy(newbuf, buf, buflen);
            delete[] buf;
            buf = newbuf;
            buflen *= 2;
        }
        buf[i] = ch;
    }
    buf[i] = '\0';
    return ch;
}

bool dbSubSql::readCondition()
{
    int i, ch;
    for (i = 0; (ch = get()) != ';' && ch !=  EOF; i++) { 
        if (i+1 >= buflen) { 
            char* newbuf = new char[buflen*2];
            memcpy(newbuf, buf, buflen);
            delete[] buf;
            buf = newbuf;
            buflen *= 2;
        }
        buf[i] = ch;
    }
    buf[i] = '\0';
    if (ch != ';') { 
        error("unexpected end of input");
        return false;
    } 
    return true;
}


void dbSubSql::dumpRecord(byte* base, dbFieldDescriptor* first)
{
    int i, n;
    byte* elem;
    dbFieldDescriptor* fd = first;
    do { 
        if (fd != first) { 
            printf(", ");
        }
        switch (fd->type) { 
          case dbField::tpBool:
            printf("%s", *(bool*)(base + fd->dbsOffs) 
                   ? "true" : "false");
            continue;
          case dbField::tpInt1:
            printf("%d", *(int1*)(base + fd->dbsOffs)); 
            continue;       
          case dbField::tpInt2:
            printf("%d", *(int2*)(base + fd->dbsOffs)); 
            continue;
          case dbField::tpInt4:
            printf("%d", *(int4*)(base + fd->dbsOffs)); 
            continue;
          case dbField::tpInt8:
            printf(INT8_FORMAT, *(db_int8*)(base + fd->dbsOffs)); 
            continue;
          case dbField::tpReal4:
            printf("%f", *(real4*)(base + fd->dbsOffs)); 
            continue;
          case dbField::tpReal8:
            printf("%f", *(real8*)(base + fd->dbsOffs)); 
            continue;
          case dbField::tpString:
            printf("'%s'", (char*)base+((dbVarying*)(base+fd->dbsOffs))->offs);
            continue;
          case dbField::tpReference:
            printf("#%lx", (unsigned long)*(oid_t*)(base + fd->dbsOffs)); 
            continue;
          case dbField::tpRectangle:
            {
                int i, sep = '(';
                rectangle& r = *(rectangle*)(base + fd->dbsOffs);
                for (i = 0; i < rectangle::dim*2; i++) { 
                    printf("%c%f", sep, (double)r.boundary[i]);
                    sep = ',';
                }
                printf(")");
            }
            continue;
          case dbField::tpRawBinary:
            n = fd->dbsSize;
            elem = base + fd->dbsOffs;
            printf("(");
            for (i = 0; i < n; i++) { 
                if (i != 0) { 
                    printf(", ");
                }
                printf("%02x", *elem++);
            }
            printf(")");
            continue;
          case dbField::tpArray:
            n = ((dbVarying*)(base + fd->dbsOffs))->size;
            elem = base + ((dbVarying*)(base + fd->dbsOffs))->offs;
            printf("(");
            for (i = 0; i < n; i++) { 
                if (i != 0) { 
                    printf(", ");
                }
                dumpRecord(elem, fd->components);
                elem += fd->components->dbsSize;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -