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

📄 server.cpp

📁 FastDb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    memcpy(old_data, rec, rec->size);    for (cb = stmt->columns; cb != NULL; cb = cb->next) {         if (cb->fd->attr & dbFieldDescriptor::Updated) {                        if (cb->fd->indexType & HASHED) {                 dbHashTable::remove(db, cb->fd->hashTable,                                     stmt->cursor->currId,                                    cb->fd->type, cb->fd->dbsSize, cb->fd->dbsOffs);            }            if (cb->fd->indexType & INDEXED) {                 if (cb->fd->type == dbField::tpRectangle) {                     dbRtree::remove(db, cb->fd->tTree, stmt->cursor->currId,                                    cb->fd->dbsOffs);                } else {                     dbTtree::remove(db, cb->fd->tTree, stmt->cursor->currId,                                     cb->fd->type, cb->fd->dbsSize, cb->fd->comparator, cb->fd->dbsOffs);                }            }        }    }        db->modified = true;    new_data = (char*)db->putRow(stmt->cursor->currId, offs);        fd = first;    offs = table->fixedSize;    do {         if (fd->type == dbField::tpArray|| fd->type == dbField::tpString)         {             int len = ((dbVarying*)(old_data + fd->dbsOffs))->size;            offs = DOALIGN(offs, fd->components->alignment);            for (cb = stmt->columns; cb != NULL; cb = cb->next) {                 if (cb->fd == fd) {                     len = cb->unpackArray(new_data, offs);                    break;                }            }            if (cb == NULL) {                 memcpy(new_data + offs,                        old_data + ((dbVarying*)(old_data + fd->dbsOffs))->offs,                       len*fd->components->dbsSize);            }            ((dbVarying*)(new_data + fd->dbsOffs))->size = len;            ((dbVarying*)(new_data + fd->dbsOffs))->offs = offs;            offs += len*fd->components->dbsSize;        } else {                         for (cb = stmt->columns; cb != NULL; cb = cb->next) {                 if (cb->fd == fd) {                     cb->unpackScalar(new_data);                    break;                }            }            if (cb == NULL) {                 memcpy(new_data + fd->dbsOffs, old_data + fd->dbsOffs,                        fd->dbsSize);            }        }    } while ((fd = fd->next) != first);    delete[] old_data;    for (cb = stmt->columns; cb != NULL; cb = cb->next) {         if (cb->fd->attr & dbFieldDescriptor::Updated) {                        cb->fd->attr &= ~dbFieldDescriptor::Updated;            if (cb->fd->indexType & HASHED) {                 dbHashTable::insert(db, cb->fd->hashTable,                                     stmt->cursor->currId,                                    cb->fd->type, cb->fd->dbsSize, cb->fd->dbsOffs, 0);            }            if (cb->fd->indexType & INDEXED) {                 if (cb->fd->type == dbField::tpRectangle) {                     dbRtree::insert(db, cb->fd->tTree, stmt->cursor->currId,                                    cb->fd->dbsOffs);                } else {                     dbTtree::insert(db, cb->fd->tTree, stmt->cursor->currId,                                     cb->fd->type, cb->fd->dbsSize, cb->fd->comparator, cb->fd->dbsOffs);                }            }        }    }    response = cli_ok;    pack4(response);    return session->sock->write(&response, sizeof response);}                char* dbServer::checkColumns(dbStatement* stmt, int n_columns,                              dbTableDescriptor* desc, char* data,                              int4& response){    dbColumnBinding** cpp = &stmt->columns;    response = cli_ok;    while (--n_columns >= 0) {        int cliType = *data++;        char* columnName = data;        dbSymbolTable::add(columnName, tkn_ident, true);            dbFieldDescriptor* fd = desc->findSymbol(columnName);        data += strlen(data) + 1;        if (fd != NULL) {             if ((cliType == cli_oid                  && fd->type == dbField::tpReference)                || (cliType == cli_rectangle                    && fd->type == dbField::tpRectangle)                || (cliType >= cli_bool && cliType <= cli_int8                    && fd->type >= dbField::tpBool                     && fd->type <= dbField::tpInt8)                || (cliType >= cli_real4 && cliType <= cli_real8                     && fd->type >= dbField::tpReal4                    && fd->type <= dbField::tpReal8)                || ((cliType == cli_asciiz || cliType == cli_pasciiz)                     && fd->type == dbField::tpString)                || (cliType == cli_array_of_oid &&                     fd->type == dbField::tpArray &&                     fd->components->type == dbField::tpReference)                || (cliType >= cli_array_of_bool                    && fd->type  == dbField::tpArray                    && cliType-cli_array_of_bool                     == fd->components->type-dbField::tpBool))            {                dbColumnBinding* cb = new dbColumnBinding(fd, cliType);                *cpp = cb;                cpp = &cb->next;            } else {                 response = cli_incompatible_type;                break;            }        } else {             TRACE_MSG(("Field '%s' not found\n", columnName));            response = cli_column_not_found;            break;        }    }    return data;}bool dbServer::insert(dbSession* session, int stmt_id, char* data, bool prepare){    dbStatement* stmt = findStatement(session, stmt_id);    dbTableDescriptor* desc = NULL;    dbColumnBinding* cb;    int4   response;    char   reply_buf[sizeof(cli_oid_t) + 8];    char*  dst;    oid_t  oid = 0;    size_t offs;    int    n_columns;    if (stmt == NULL) {         if (!prepare) {             response = cli_bad_statement;            goto return_response;        }        stmt = new dbStatement(stmt_id);        stmt->next = session->stmts;        session->stmts = stmt;    } else {        if (prepare) {             stmt->reset();        } else if ((desc = stmt->table) == NULL) {            response = cli_bad_descriptor;            goto return_response;        }    }    if (prepare) {         session->scanner.reset(data);        if (session->scanner.get() != tkn_insert             || session->scanner.get() != tkn_into            || session->scanner.get() != tkn_ident)         {            response = cli_bad_statement;            goto return_response;        }        desc = db->findTable(session->scanner.ident);        if (desc == NULL) {                 response = cli_table_not_found;            goto return_response;        }        data += strlen(data)+1;        n_columns = *data++ & 0xFF;        data = checkColumns(stmt, n_columns, desc, data, response);        if (response != cli_ok) {             goto return_response;        }        stmt->table = desc;    }     offs = desc->fixedSize;    for (cb = stmt->columns; cb != NULL; cb = cb->next) {         cb->ptr = data;        if (cb->cliType == cli_autoincrement) {            ;        } else if (cb->cliType >= cli_asciiz) {             cb->len = unpack4(data);            data += 4 + cb->len*cb->fd->components->dbsSize;            offs = DOALIGN(offs, cb->fd->components->alignment)                 + cb->len*cb->fd->components->dbsSize;        } else {             data += sizeof_type[cb->cliType];        }    }    db->beginTransaction(dbDatabase::dbExclusiveLock);    db->modified = true;    oid = db->allocateRow(desc->tableId, offs);    dst = (char*)db->getRow(oid);            offs = desc->fixedSize;    for (cb = stmt->columns; cb != NULL; cb = cb->next) {         dbFieldDescriptor* fd = cb->fd;        if (fd->type == dbField::tpArray || fd->type == dbField::tpString) {            offs = DOALIGN(offs, fd->components->alignment);            ((dbVarying*)(dst + fd->dbsOffs))->offs = offs;            ((dbVarying*)(dst + fd->dbsOffs))->size = cb->len;            offs += cb->unpackArray(dst, offs)*fd->components->dbsSize;        } else {             cb->unpackScalar(dst);        }    }    for (cb = stmt->columns; cb != NULL; cb = cb->next) {         if (cb->fd->indexType & HASHED) {             dbHashTable::insert(db, cb->fd->hashTable, oid,                                cb->fd->type, cb->fd->dbsSize, cb->fd->dbsOffs, 0);        }        if (cb->fd->indexType & INDEXED) {             if (cb->fd->type == dbField::tpRectangle) {                 dbRtree::insert(db, cb->fd->tTree, oid, cb->fd->dbsOffs);            } else {                 dbTtree::insert(db, cb->fd->tTree, oid,                                 cb->fd->type, cb->fd->dbsSize, cb->fd->comparator, cb->fd->dbsOffs);            }        }    }    response = cli_ok;  return_response:    pack4(reply_buf, response);    if (desc == NULL) {         pack4(reply_buf+4, 0);    } else { #ifdef AUTOINCREMENT_SUPPORT        pack4(reply_buf+4, desc->autoincrementCount);#else        pack4(reply_buf+4, ((dbTable*)db->getRow(desc->tableId))->nRows);#endif    }    pack_oid(reply_buf+8, oid);    return session->sock->write(reply_buf, sizeof reply_buf);}    bool dbServer::describe_table(dbSession* session, char const* table){    dbTableDescriptor* desc = db->findTableByName(table);    if (desc == NULL) {        char response[8];        pack4(response, 0);        pack4(response+4, -1);        return session->sock->write(response, sizeof response);    } else {         int i, length = 0;        dbFieldDescriptor* fd = desc->columns;         for (i = desc->nColumns; --i >= 0;) {             length += strlen(fd->name)+2+3;            if (fd->refTableName != NULL) {                  length += strlen(fd->refTableName);            } else if (fd->type == dbField::tpArray && fd->components->refTableName != NULL) {                length += strlen(fd->components->refTableName);            }            if (fd->inverseRefName != NULL) {                 length += strlen(fd->inverseRefName);            }            fd = fd->next;        }        dbSmallBuffer response(length+8);        char* p = (char*)response;        pack4(p, length);        pack4(p+4, desc->nColumns);        p += 8;        for (i = desc->nColumns, fd = desc->columns; --i >= 0;) {             int flags = 0;            *p++ = map_type(fd);            if (fd->tTree != 0) {                 flags |= cli_indexed;            }            if (fd->hashTable != 0) {                 flags |= cli_hashed;            }            *p++ = (char)flags;            strcpy(p, fd->name);            p += strlen(fd->name)+1;            if (fd->refTableName != NULL) {                strcpy(p, fd->refTableName);                p += strlen(p) + 1;            } else if (fd->type == dbField::tpArray && fd->components->refTableName != NULL) {                strcpy(p, fd->components->refTableName);                p += strlen(p) + 1;            } else {                 *p++ = '\0';            }            if (fd->inverseRefName != NULL) {                strcpy(p, fd->inverseRefName);                p += strlen(p) + 1;            } else {                 *p++ = '\0';            }            fd = fd->next;        }        return session->sock->write(response, length+8);    }}bool dbServer::show_tables(dbSession* session){    dbTableDescriptor* desc=db->tables;    if (desc == NULL) {        char response[8];        pack4(response, 0);        pack4(response+4, -1);        return session->sock->write(response, sizeof response);    } else {        int length = 0, n = 0;        for (desc=db->tables; desc != NULL; desc=desc->nextDbTable) {            if (strcmp(desc->name, "Metatable")) {                length += strlen(desc->name)+1;                n++;            }        }        dbSmallBuffer response(length+8);        char* p = (char*)response;        pack4(p, length);        pack4(p+4, n);        p += 8;        for (desc=db->tables; desc != NULL; desc=desc->nextDbTable) {            if (strcmp(desc->name, "Metatable")) {                strcpy(p, desc->name);                p += strlen(desc->name)+1;            }        }        return session->sock->write(response, length+8);    }}bool dbServer::create_table(dbSession* session, char* data, bool create){    db->beginTransaction(dbDatabase::dbExclusiveLock);    db->modified = true;    char* tableName = data;    data += strlen(data) + 1;    int nColumns = *data++ & 0xFF;    cli_field_descriptor* columns = new cli_field_descriptor[nColumns];        for (int i = 0; i < nColumns; i++) {        columns[i].type = (cli_var_type)*data++;        columns[i].flags = *data++ & 0xFF;        columns[i].name = data;        data += strlen(data) + 1;        if (*data != 0) {             columns[i].refTableName = data;            data += strlen(data) + 1;        } else {             columns[i].refTableName = NULL;            data += 1;        }        if (*data != 0) {             columns[i].inverseRefFieldName = data;            data += strlen(data) + 1;        } else {             columns[i].inverseRefFieldName = NULL;            data += 1;        }    }    if (session->existed_tables == NULL) {         session->existed_tables = db->tables;    }    int4 response;    if (create) {        if (session->existed_tables == NULL) {             session->existed_tables = db->tables;        }        response = dbCLI::create_table(db, tableName, nColumns, columns);    } else {         response = dbCLI::alter_table(db, tableName, nColumns, columns);    }    pack4(response);    return session->sock->write(&response, sizeof response);}bool dbServer::drop_table(dbSession* session, char* tableName){    db->beginTransaction(dbDatabase::dbExclusiveLock);    dbTableDescriptor* desc = db->findTableByName(tableName);    int4 response = cli_ok;    if (desc != NULL) {        db->dropTable(desc);        if (desc == session->existed_tables) {             session->existed_tables = desc->nextDbTable;        }        db->unlinkTable(desc);        desc->nextDbTable = session->dropped_tables;        session->dropped_tables = desc;    } else {         response = cli_table_not_found;    }    pack4(response);    return session->sock->write(&response, sizeof response);}bool dbServer::alter_index(dbSession* session, char* data){    char* tableName = data;    data += strlen(data) + 1;    char* fieldName = data;    data += strlen(data) + 1;    int newFlags = *data++ & 0xFF;    int4 response = dbCLI::alter_index(db, tableName, fieldName, newFlags);

⌨️ 快捷键说明

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