void test_remove_attributes(BFile& file, int32 start, int32 count, int32 removeAt, int32 removeIndex1, int32 removeIndex2) { int fd = file.Dup(); if (fd < 0) return; int32 index = 0; bool seen[4096] = {0}; if (gVerbose) printf("test removeAt %ld\n", removeAt); DIR* dir = fs_fopen_attr_dir(fd); while (struct dirent* entry = fs_read_attr_dir(dir)) { if (gVerbose) printf(" %ld. %s\n", index, entry->d_name); if (index == removeAt) { if (removeIndex1 > 0) remove_marker_attribute(file, removeIndex1); if (removeIndex2 > 0) remove_marker_attribute(file, removeIndex2); } index++; if (is_marker(entry->d_name)) continue; int32 attributeIndex = attribute_index(entry->d_name); if (attributeIndex > 0) { if (seen[attributeIndex]) { printf("attribute index %ld already listed!\n", attributeIndex); exit(1); } else seen[attributeIndex] = true; } } fs_close_attr_dir(dir); close(fd); for (int32 i = start; i < start + count; i++) { if (!seen[i]) { printf("attribute index %ld not listed, saw only %ld/%ld!\n", i, index, count); exit(1); } } }
Info API::DeleteFrom(SqlCommandDeleteFrom* command){ CatalogManager catalog_manager; IndexManager index_manager; RecordManager record_manager; bool delete_all_records = command->delete_all_records(); std::string table_name = command->table_name(); std::vector<WhereClause> where_clause = command->where_clause(); if (!catalog_manager.HasTable(table_name)){ std::string error_info; error_info = "Table \"" + table_name + "\" not exists."; return Info(error_info); } auto table = catalog_manager.GetTableInfo(table_name); for (auto it: where_clause){ if(!table.HasAttribute(it.kColumnName)){ std::string error_info; error_info = "attribute \"" + it.kColumnName + "\"in where clause \""+ it.kColumnName + it.kOperator + it.kCondition +"\" not exists."; return Info(error_info); } } if (delete_all_records){ if(record_manager.DeleteAllRecords(table)){ //update index for (auto it : table.index_names()){ IndexInfo index_info = catalog_manager.GetIndexInfo(it); index_manager.EmptyIndex(index_info); } return Info(); } else{ return Info("Delete records failed"); } } else{ std::vector<WhereClause> where_clause_with_index; std::vector<WhereClause> where_clause_without_index; for (auto it : where_clause){ if (!table.attribute(it.kColumnName).index_names().empty() && it.kOperator != "!="){ where_clause_with_index.push_back(it); } else{ where_clause_without_index.push_back(it); } } std::vector<std::pair<int,int>> results; if (!where_clause_with_index.empty()) //条件里有属性有 index { for (auto it : where_clause_with_index){ std::string index_name = table.attribute(it.kColumnName).index_names().at(0); IndexInfo index = catalog_manager.GetIndexInfo(index_name); std::vector<int> offsets_of_a_clause = index_manager.FindRecords(table,index, it); if(offsets_of_a_clause.empty()){ std::string error_info; error_info = "record not found with index, deletion failed"; return Info(error_info); } std::sort(offsets_of_a_clause.begin(), offsets_of_a_clause.end()); offsets_of_a_clause.erase(std::unique(offsets_of_a_clause.begin(), offsets_of_a_clause.end()), offsets_of_a_clause.end()); std::vector<std::pair<int,int>> results_of_a_clause = record_manager.FindRecordsWithIndex(offsets_of_a_clause, table, it); if (results.empty()){ results = results_of_a_clause; } else{ std::vector<std::pair<int,int> > results_temp; std::set_intersection(results.begin(),results.end(), results_of_a_clause.begin(),results_of_a_clause.end(), std::back_inserter(results_temp)); results = results_temp; } } for(auto it : where_clause_without_index){ if(results.empty()){ std::string error_info; error_info = "record not found with index, deletion failed"; return Info(error_info); } results = record_manager.RecordsFilter(results, table, it); } } else{ //条件里属性都没有 index for (auto it: where_clause_without_index){ if (results.empty()){ results = record_manager.FindRecordsWithNoIndex(table, it); } else{ results = record_manager.RecordsFilter(results,table, it); } } if(results.empty()){ std::string error_info; error_info = "record not found with no index, deletion failed"; return Info(error_info); } } if(results.empty()){ std::string error_info; error_info = "record not found, deletion failed"; return Info(error_info); } auto records = record_manager.SelectRecords(results, table); int ret = record_manager.DeleteRecords(results, table); if(!ret){ return Info("Delete records failed."); } else{ auto index_names = table.index_names(); int pair_index = 0; for (auto it : records){ for (auto i : index_names){ IndexInfo index_info = catalog_manager.GetIndexInfo(i); auto index = table.attribute_index(index_info.attribute_name()); std::string value = it.at(index); int offset_i = results.at(pair_index).first; bool ret = index_manager.DeleteRecord(table, index_info, value, offset_i); if(!ret){ return Info("Delete record in index \"" + index_info.name() + "on attribute \"" + index_info.attribute_name() +"\" of table \"" + index_info.table_name() + "\"failed."); } } pair_index++; } return Info(); } } }