📄 server.cpp
字号:
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 + -