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);
		}
	}
}
Ejemplo n.º 2
0
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();
    }
  }
}