localcli.cpp
来自「一个功能强大的内存数据库源代码,c++编写,有详细的注释」· C++ 代码 · 共 1,971 行 · 第 1/4 页
CPP
1,971 行
dbTableDescriptor* table = db->tables; db->unlinkTable(table); delete table; } return cli_ok;}int cli_remove(int statement){ return dbCLI::instance.remove(statement);}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->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_INDETIFIER_LENGTH 256int sql_scanner::get(){ char buf[MAX_QUERY_INDETIFIER_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_INDETIFIER_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 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::create_table(dbDatabase* db, char const* tableName, int nColumns, cli_field_descriptor* columns){ int i; db->modified = true; if (db->findTableByName(tableName) != NULL) { return cli_table_already_exists; } int nFields = nColumns; int varyingLength = strlen(tableName) + 1; for (i = 0; i < nColumns; 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; } } db->beginTransaction(dbDatabase::dbExclusiveLock); oid_t oid = db->allocateRow(dbMetaTableId, sizeof(dbTable) + sizeof(dbField)*nFields + varyingLength); dbTable* table = (dbTable*)db->putRow(oid); 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); dbField* field = (dbField*)((char*)table + table->fields.offs); offs -= sizeof(dbTable); for (i = 0; i < nColumns; i++, field += 1, 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) { field->tableName.size = strlen(columns[i].refTableName) + 1; strcpy((char*)field + offs, columns[i].refTableName); offs += field->tableName.size; 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); field->hashTable = (columns[i].flags & cli_hashed) ? dbHashTable::allocate(db) : 0; field->tTree = (columns[i].flags & cli_indexed) ? dbTtree::allocate(db) : 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; 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; 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; case cli_array_of_bool: field->type = dbField::tpBool; field->size = sizeof(bool); break; case cli_array_of_int1: field->type = dbField::tpInt1; field->size = sizeof(int1); break; case cli_array_of_int2: field->type = dbField::tpInt2; field->size = sizeof(int2); break; case cli_array_of_int4: field->type = dbField::tpInt4; field->size = sizeof(int4); break; case cli_array_of_int8: field->type = dbField::tpInt8; field->size = sizeof(db_int8); break; case cli_array_of_real4: field->type = dbField::tpReal4; field->size = sizeof(real4); break; case cli_array_of_real8: field->type = dbField::tpReal8; field->size = sizeof(real8); break; case cli_array_of_string: field->type = dbField::tpString; field->size = sizeof(dbVarying); break; } continue; } field->hashTable = (columns[i].flags & cli_hashed) ? dbHashTable::allocate(db) : 0; field->tTree = (columns[i].flags & cli_indexed) ? dbTtree::allocate(db) : 0; field->offset = DOALIGN(size, field->size); size = field->offset + sizeof(dbVarying); } table->fields.size = nFields; table->fixedSize = size; table->nRows = 0; table->nColumns = nColumns; table->firstRow = 0; table->lastRow = 0; db->linkTable(new dbTableDescriptor(table), oid); if (!db->completeDescriptorsInitialization()) { return cli_table_not_found; } return cli_ok;}int cli_drop_table(int session, char const* tableName){ return dbCLI::instance.drop_table(session, tableName);}int dbCLI::drop_table(int session, char const* tableName){ session_desc* s = sessions.get(session); if (s == NULL) { return cli_bad_descriptor; } dbDatabase* db = s->db; dbTableDescriptor* desc = db->findTableByName(tableName); if (desc == NULL) { return cli_table_not_found; } db->dropTable(desc); if (desc == s->existed_tables) { s->existed_tables = desc->nextDbTable; } db->unlinkTable(desc); desc->nextDbTable = s->dropped_tables; s->dropped_tables = desc; return cli_ok;}int cli_alter_index(int session, char const* tableName, char const* fieldName, int newFlags){ return dbCLI::instance.alter_index(session, tableName, fieldName, newFlags);}int dbCLI::alter_index(int session, char const* tableName, char const* fieldName, int newFlags){ session_desc* s = sessions.get(session); if (s == NULL) { return cli_bad_descriptor; } return alter_index(s->db, tableName, fieldName, newFlags);}int dbCLI::alter_index(dbDatabase* db, char const* tableName, char const* fieldName, int newFlags){ db->beginTransaction(dbDatabase::dbExclusiveLock); dbTableDescriptor* desc = db->findTableByName(tableName); if (desc == NULL) { return cli_table_not_found; } dbFieldDescriptor* fd = desc->find(fieldName); if (fd == NULL) { return cli_column_not_found; } if (fd->tTree != 0 && (newFlags & cli_indexed) == 0) { db->dropIndex(fd); } if (fd->hashTable != 0 && (newFlags & cli_hashed) == 0) { db->dropHashTable(fd); } if (fd->tTree == 0 && (newFlags & cli_indexed) != 0) { db->createIndex(fd); } if (fd->hashTable == 0 && (newFlags & cli_hashed) != 0) { db->createHashTable(fd); } return cli_ok;}cli_error_handler cli_set_error_handler(int session, cli_error_handler new_handler){ return dbCLI::instance.set_error_handler(session, new_handler);}cli_error_handler dbCLI::set_error_handler(int session, cli_error_handler new_handler){ session_desc* s = sessions.get(session); if (s == NULL) { return NULL; } return (cli_error_handler)s->db->setErrorHandler(dbDatabase::dbErrorHandler(new_handler));}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?