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

📄 localcli.cpp

📁 用于嵌入式环境的数据库
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

int dbCLI::remove(int statement)
{
    statement_desc* stmt = statements.get(statement);    
    if (stmt == NULL || !stmt->prepared) {
        return cli_bad_descriptor;
    }
    if (!stmt->for_update) {
        return cli_not_update_mode;
    }
    if (stmt->cursor.isEmpty()) { 
        return cli_not_found;
    }
    stmt->cursor.removeAllSelected();
    return cli_ok;
}

int cli_describe(int session, char const* table, cli_field_descriptor** fields)
{
    return dbCLI::instance.describe(session, table, fields);
}

int dbCLI::describe(int session, char const* table, cli_field_descriptor** fields)
{
    session_desc* s = sessions.get(session);
    if (s == NULL) { 
        return cli_bad_descriptor;
    }   
    dbDatabase* db = s->db;
    dbTableDescriptor* desc = db->findTableByName(table);
    if (desc == NULL) {
        return cli_table_not_found;
    } else { 
        int nColumns = desc->nColumns;
        cli_field_descriptor* fp = 
            (cli_field_descriptor*)malloc(nColumns*sizeof(cli_field_descriptor));
        dbFieldDescriptor* fd = desc->columns; 
        *fields = fp;
        for (int i = 0; i < nColumns; i++, fp++) { 
            fp->type = (cli_var_type)map_type(fd);
            fp->name = fd->name;            
            fp->refTableName = (fd->type == dbField::tpArray) ? fd->components->refTableName : fd->refTableName;
            fp->inverseRefFieldName = fd->inverseRefName;
            fp->flags = 0;
            if (fd->tTree != 0) { 
                fp->flags |= cli_indexed;
            }
            if (fd->hashTable != 0) { 
                fp->flags |= cli_hashed;
            }
            fd = fd->next;
        }
        return nColumns;
    }
}


int cli_show_tables(int session, cli_table_descriptor** tables)
{
    return dbCLI::instance.show_tables(session, tables);
}

int dbCLI::show_tables(int session, cli_table_descriptor** tables)
{
    session_desc* s = sessions.get(session);
    if (s == NULL) { 
        return cli_bad_descriptor;
    }   
    dbTableDescriptor* desc;
    int nTables = 0;
    for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable) {
        if (strcmp(desc->name, "Metatable")) {
            nTables += 1;
        }
    }    
    if (nTables != 0) { 
        cli_table_descriptor* td = (cli_table_descriptor*)malloc(nTables*sizeof(cli_table_descriptor));
        *tables = td;
        for (desc = s->db->tables; desc != NULL; desc = desc->nextDbTable) {
            if (strcmp(desc->name, "Metatable")) {
                td->name = desc->name;
                td += 1;
            }
        }
    } else { 
        *tables = NULL;
    }
    return nTables;
}


#define MAX_QUERY_IDENTIFIER_LENGTH 256

int sql_scanner::get()
{
    char buf[MAX_QUERY_IDENTIFIER_LENGTH];
    int i = 0, ch;

    do {
        ch = *p++;
        if (ch == '\0') {
            return tkn_eof;
        }
    } while (ch > 0 && ch <= 32);

    if (ch == '*') {
        return tkn_all;
    } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-') {    
        int const_type = tkn_iconst;
        while (true) {
            ch = *p++;
            if (ch == '.' || ch == 'e' || ch == 'E') { 
                const_type = tkn_fconst;
            } else if (!((ch >= '0' && ch <= '9') || ch == '+' || ch == '-')) { 
                break;
            }
        }
        return const_type;
    } else if (isalnum(ch) || ch == '$' || ch == '_') {
        do {
            buf[i++] = ch;
            if (i == MAX_QUERY_IDENTIFIER_LENGTH) {
                // Identifier too long
                return tkn_error;
            }
            ch = *p++;
        } while (ch != EOF && (isalnum(ch) || ch == '$' || ch == '_'));
        p -= 1;
        buf[i] = '\0';
        ident = buf;
        return dbSymbolTable::add(ident, tkn_ident);
    } else {
        // Invalid symbol
        return tkn_error;
    }
}


int cli_create_table(int session, char const* tableName, int nColumns, 
                     cli_field_descriptor* columns)
{
    return dbCLI::instance.create_table(session, tableName, nColumns, columns);
}


int cli_alter_table(int session, char const* tableName, int nColumns, 
                    cli_field_descriptor* columns)
{
    return dbCLI::instance.alter_table(session, tableName, nColumns, columns);
}

int dbCLI::create_table(int session, char const* tableName, int nColumns, 
                        cli_field_descriptor* columns)
{
    session_desc* s = sessions.get(session);
    if (s == NULL) { 
        return cli_bad_descriptor;
    }       
    s->db->beginTransaction(dbDatabase::dbExclusiveLock);
    if (s->existed_tables == NULL) { 
        s->existed_tables = s->db->tables;
    }
    return create_table(s->db, tableName, nColumns, columns);
}


int dbCLI::alter_table(int session, char const* tableName, int nColumns, 
                        cli_field_descriptor* columns)
{
    session_desc* s = sessions.get(session);
    if (s == NULL) { 
        return cli_bad_descriptor;
    }       
    s->db->beginTransaction(dbDatabase::dbExclusiveLock);
    return alter_table(s->db, tableName, nColumns, columns);
}



int dbCLI::calculate_varying_length(char const* tableName, int& nFields, cli_field_descriptor* columns)
{
    int varyingLength = strlen(tableName) + 1;
    for (int i = 0, n = nFields; i < n; i++) { 
        int type = columns[i].type;
        varyingLength += strlen(columns[i].name) + 3;
        if (type == cli_oid || type == cli_array_of_oid) { 
            varyingLength += strlen(columns[i].refTableName);
            if (columns[i].inverseRefFieldName != NULL) { 
                varyingLength += strlen(columns[i].inverseRefFieldName);
            }
        }
        switch (type) {        
          case cli_oid:
          case cli_bool:
          case cli_int1:
          case cli_int2:
          case cli_int4:
          case cli_autoincrement:
          case cli_int8:
          case cli_real4:
          case cli_real8:
          case cli_asciiz:
          case cli_pasciiz:
            break;
          case cli_array_of_oid:
          case cli_array_of_bool:
          case cli_array_of_int1:
          case cli_array_of_int2:
          case cli_array_of_int4:
          case cli_array_of_int8:
          case cli_array_of_real4:
          case cli_array_of_real8:
          case cli_array_of_string:
            varyingLength += strlen(columns[i].name) + 2 + 3;
            nFields += 1;
            break;
          case cli_unknown:
            return cli_unsupported_type;
        }
    }
    return varyingLength;
}

dbTableDescriptor* dbCLI::create_table_descriptor(dbDatabase*           db, 
                                                  oid_t                 oid, 
                                                  dbTable*              table,
                                                  char const*           tableName, 
                                                  int                   nFields, 
                                                  int                   nColumns, 
                                                  cli_field_descriptor* columns)
{
    int offs = sizeof(dbTable) + sizeof(dbField)*nFields;
    table->name.offs = offs;
    table->name.size = strlen(tableName)+1;
    strcpy((char*)table + offs, tableName);
    offs += table->name.size;
    size_t size = sizeof(dbRecord);
    table->fields.offs = sizeof(dbTable);
    int fieldOffs = table->fields.offs;
    dbField* field = (dbField*)((char*)table + fieldOffs);
    offs -= sizeof(dbTable);

    for (int i = 0; i < nColumns; i++, fieldOffs += sizeof(dbField), field++, offs -= sizeof(dbField)) {
        field->name.offs = offs;
        field->name.size = strlen(columns[i].name) + 1;
        strcpy((char*)field + offs, columns[i].name);
        offs += field->name.size;
        field->tableName.offs = offs;
        int type = columns[i].type;

        if (type == cli_oid || type == cli_array_of_oid) {
            if (type == cli_oid) { 
                field->tableName.size = strlen(columns[i].refTableName) + 1;
                strcpy((char*)field + offs, columns[i].refTableName);
                offs += field->tableName.size;
            } else { 
                field->tableName.size = 1;
                *((char*)field + offs) = '\0';
                offs += 1;
            }
            field->inverse.offs = offs;
            if (columns[i].inverseRefFieldName != NULL) {
                field->inverse.size = strlen(columns[i].inverseRefFieldName) + 1;
                strcpy((char*)field + offs, columns[i].inverseRefFieldName);
                offs += field->inverse.size;
            } else {
                field->inverse.size = 1;
                *((char*)field + offs) = '\0';
                offs += 1;
            }
        } else {
            field->tableName.size = 1;
            *((char*)field + offs) = '\0';
            offs += 1;
            field->inverse.size = 1;
            field->inverse.offs = offs;
            *((char*)field + offs) = '\0';
            offs += 1;

        }
        field->tTree = field->hashTable = 0;

        switch (type) {
          case cli_oid:
            field->type = dbField::tpReference;
            field->size = sizeof(oid_t);
            break;
          case cli_bool:
            field->type = dbField::tpBool;
            field->size = sizeof(bool);
            break;
          case cli_int1:
            field->type = dbField::tpInt1;
            field->size = sizeof(int1);
            break;
          case cli_int2:
            field->type = dbField::tpInt2;
            field->size = sizeof(int2);
            break;
          case cli_int4:
          case cli_autoincrement:
            field->type = dbField::tpInt4;
            field->size = sizeof(int4);
            break;
          case cli_int8:
            field->type = dbField::tpInt8;
            field->size = sizeof(db_int8);
            break;
          case cli_real4:
            field->type = dbField::tpReal4;
            field->size = sizeof(real4);
            break;
          case cli_real8:
            field->type = dbField::tpReal8;
            field->size = sizeof(real8);
            break;
          case cli_asciiz:
          case cli_pasciiz:
            field->type = dbField::tpString;
            field->size = sizeof(dbVarying);
            field->offset = DOALIGN(size, sizeof(int4));
            size = field->offset + sizeof(dbVarying);
            if (db != NULL && (columns[i].flags & cli_hashed)) {
                oid_t hashOid = dbHashTable::allocate(db);
                table = (dbTable*)db->getRow(oid);
                field = (dbField*)((char*)table + fieldOffs);
                field->hashTable = hashOid;
            } else {
                field->hashTable = 0;
            }
            if (db != NULL && (columns[i].flags & cli_indexed)) {
                oid_t treeOid = dbTtree::allocate(db);
                table = (dbTable*)db->getRow(oid);
                field = (dbField*)((char*)table + fieldOffs);
                field->tTree = treeOid;
            } else {
                field->tTree = 0;
            }
            continue;
          case cli_array_of_oid:
          case cli_array_of_bool:
          case cli_array_of_int1:
          case cli_array_of_int2:
          case cli_array_of_int4:
          case cli_array_of_int8:
          case cli_array_of_real4:
          case cli_array_of_real8:
          case cli_array_of_string:
            field->type = dbField::tpArray;
            field->size = sizeof(dbVarying);
            field->offset = DOALIGN(size, sizeof(int4));
            size = field->offset + sizeof(dbVarying);
            field->hashTable = field->tTree = 0;
            field += 1;
            fieldOffs += sizeof(dbField);
            offs -= sizeof(dbField);
            field->name.offs = offs;
            field->name.size = strlen(columns[i].name) + 3;
            sprintf((char*)field + offs, "%s[]", columns[i].name);
            offs += field->name.size;   
            field->tableName.offs = offs;
            if (type == cli_array_of_oid) { 
                field->tableName.size = strlen(columns[i].refTableName) + 1;
                strcpy((char*)field + offs, columns[i].refTableName);
                offs += field->tableName.size;
            } else { 
                field->tableName.size = 1;
                *((char*)field + offs) = '\0';
                offs += 1;
            }
            field->inverse.offs = offs;
            field->inverse.size = 1;
            *((char*)field + offs) = '\0';
            offs += 1;
            field->offset = 0;
            field->hashTable = field->tTree = 0;
            switch (type) { 
              case cli_array_of_oid:
                field->type = dbField::tpReference;
                field->size = sizeof(oid_t);
                break;
 

⌨️ 快捷键说明

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