| Index: chrome/browser/chromeos/drive/drive_resource_metadata.cc
|
| diff --git a/chrome/browser/chromeos/drive/drive_resource_metadata.cc b/chrome/browser/chromeos/drive/drive_resource_metadata.cc
|
| index 8571a6e6471168a22358a1fbc9a3137e43f5acfb..08976314724e1cd06cd55f923e715f94558c5b00 100644
|
| --- a/chrome/browser/chromeos/drive/drive_resource_metadata.cc
|
| +++ b/chrome/browser/chromeos/drive/drive_resource_metadata.cc
|
| @@ -222,7 +222,7 @@ void DriveResourceMetadata::SetUpDefaultEntries() {
|
| storage_->PutEntry(CreateEntryWithProperBaseName(root));
|
| }
|
| if (!storage_->GetEntry(util::kDriveOtherDirSpecialResourceId)) {
|
| - AddEntryToDirectory(util::CreateOtherDirEntry());
|
| + PutEntryUnderDirectory(util::CreateOtherDirEntry());
|
| }
|
| }
|
|
|
| @@ -547,7 +547,9 @@ DriveResourceMetadata::RemoveEntryOnBlockingPool(
|
| if (!entry)
|
| return FileMoveResult(FILE_ERROR_NOT_FOUND);
|
|
|
| - RemoveDirectoryChild(entry->resource_id());
|
| + if (!RemoveEntryRecursively(entry->resource_id()))
|
| + return FileMoveResult(FILE_ERROR_FAILED);
|
| +
|
| return FileMoveResult(FILE_ERROR_OK,
|
| GetFilePath(entry->parent_resource_id()));
|
| }
|
| @@ -679,8 +681,8 @@ FileError DriveResourceMetadata::RefreshEntryOnBlockingPool(
|
| return FILE_ERROR_NOT_FOUND;
|
|
|
| // Remove from the old parent and add it to the new parent with the new data.
|
| - DetachEntryFromDirectory(old_entry->resource_id());
|
| - AddEntryToDirectory(CreateEntryWithProperBaseName(entry));
|
| + if (!PutEntryUnderDirectory(CreateEntryWithProperBaseName(entry)))
|
| + return FILE_ERROR_FAILED;
|
|
|
| if (out_file_path)
|
| *out_file_path = GetFilePath(entry.resource_id());
|
| @@ -739,12 +741,8 @@ DriveResourceMetadata::RefreshDirectoryOnBlockingPool(
|
| continue;
|
| }
|
|
|
| - scoped_ptr<DriveEntryProto> existing_entry =
|
| - storage_->GetEntry(entry_proto.resource_id());
|
| - if (existing_entry)
|
| - DetachEntryFromDirectory(entry_proto.resource_id());
|
| -
|
| - AddEntryToDirectory(CreateEntryWithProperBaseName(entry_proto));
|
| + if (!PutEntryUnderDirectory(CreateEntryWithProperBaseName(entry_proto)))
|
| + return FileMoveResult(FILE_ERROR_FAILED);
|
| }
|
|
|
| // Go through the existing entries and remove deleted entries.
|
| @@ -755,8 +753,10 @@ DriveResourceMetadata::RefreshDirectoryOnBlockingPool(
|
| return FileMoveResult(FILE_ERROR_NO_SPACE);
|
|
|
| const DriveEntryProto& entry_proto = entries->at(i);
|
| - if (entry_proto_map.count(entry_proto.resource_id()) == 0)
|
| - RemoveDirectoryChild(entry_proto.resource_id());
|
| + if (entry_proto_map.count(entry_proto.resource_id()) == 0) {
|
| + if (!RemoveEntryRecursively(entry_proto.resource_id()))
|
| + return FileMoveResult(FILE_ERROR_FAILED);
|
| + }
|
| }
|
|
|
| return FileMoveResult(FILE_ERROR_OK, GetFilePath(directory->resource_id()));
|
| @@ -780,7 +780,9 @@ DriveResourceMetadata::AddEntryOnBlockingPool(
|
| if (!parent)
|
| return FileMoveResult(FILE_ERROR_NOT_FOUND);
|
|
|
| - AddEntryToDirectory(entry_proto);
|
| + if (!PutEntryUnderDirectory(entry_proto))
|
| + return FileMoveResult(FILE_ERROR_FAILED);
|
| +
|
| return FileMoveResult(FILE_ERROR_OK, GetFilePath(entry_proto.resource_id()));
|
| }
|
|
|
| @@ -847,7 +849,7 @@ void DriveResourceMetadata::RemoveAllOnBlockingPool() {
|
| return;
|
| }
|
|
|
| - RemoveDirectoryChildren(util::kDriveGrandRootSpecialResourceId);
|
| + RemoveEntryRecursively(util::kDriveGrandRootSpecialResourceId);
|
| SetUpDefaultEntries();
|
| }
|
|
|
| @@ -906,7 +908,8 @@ void DriveResourceMetadata::GetEntryInfoPairByPathsAfterGetSecond(
|
| callback.Run(result.Pass());
|
| }
|
|
|
| -void DriveResourceMetadata::AddEntryToDirectory(const DriveEntryProto& entry) {
|
| +bool DriveResourceMetadata::PutEntryUnderDirectory(
|
| + const DriveEntryProto& entry) {
|
| DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
|
|
|
| DriveEntryProto updated_entry(entry);
|
| @@ -916,12 +919,16 @@ void DriveResourceMetadata::AddEntryToDirectory(const DriveEntryProto& entry) {
|
| // through name de-duplication again when it is added to another directory.
|
| SetBaseNameFromTitle(&updated_entry);
|
|
|
| - // Do file name de-duplication - find files with the same name and
|
| - // append a name modifier to the name.
|
| + // Do file name de-duplication - Keep changing |entry|'s name until there is
|
| + // no other entry with the same name under the parent.
|
| int modifier = 1;
|
| std::string new_base_name = updated_entry.base_name();
|
| - while (!storage_->GetChild(entry.parent_resource_id(),
|
| - new_base_name).empty()) {
|
| + while (true) {
|
| + const std::string existing_entry_id =
|
| + storage_->GetChild(entry.parent_resource_id(), new_base_name);
|
| + if (existing_entry_id.empty() || existing_entry_id == entry.resource_id())
|
| + break;
|
| +
|
| base::FilePath new_path =
|
| base::FilePath::FromUTF8Unsafe(updated_entry.base_name());
|
| new_path =
|
| @@ -930,50 +937,26 @@ void DriveResourceMetadata::AddEntryToDirectory(const DriveEntryProto& entry) {
|
| }
|
| updated_entry.set_base_name(new_base_name);
|
|
|
| - // Setup child and parent links.
|
| - storage_->PutChild(entry.parent_resource_id(),
|
| - updated_entry.base_name(),
|
| - updated_entry.resource_id());
|
| -
|
| // Add the entry to resource map.
|
| - storage_->PutEntry(updated_entry);
|
| -}
|
| -
|
| -void DriveResourceMetadata::RemoveDirectoryChild(
|
| - const std::string& child_resource_id) {
|
| - DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
|
| -
|
| - scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(child_resource_id);
|
| - DCHECK(entry);
|
| - DetachEntryFromDirectory(child_resource_id);
|
| - storage_->RemoveEntry(entry->resource_id());
|
| - if (entry->file_info().is_directory())
|
| - RemoveDirectoryChildren(child_resource_id);
|
| + return storage_->PutEntry(updated_entry);
|
| }
|
|
|
| -void DriveResourceMetadata::DetachEntryFromDirectory(
|
| - const std::string& child_resource_id) {
|
| +bool DriveResourceMetadata::RemoveEntryRecursively(
|
| + const std::string& resource_id) {
|
| DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
|
|
|
| - scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(child_resource_id);
|
| + scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(resource_id);
|
| DCHECK(entry);
|
|
|
| - // entry must be present in this directory.
|
| - DCHECK_EQ(entry->resource_id(),
|
| - storage_->GetChild(entry->parent_resource_id(),
|
| - entry->base_name()));
|
| -
|
| - storage_->RemoveChild(entry->parent_resource_id(), entry->base_name());
|
| -}
|
| -
|
| -void DriveResourceMetadata::RemoveDirectoryChildren(
|
| - const std::string& directory_resource_id) {
|
| - DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
|
| -
|
| - std::vector<std::string> children;
|
| - storage_->GetChildren(directory_resource_id, &children);
|
| - for (size_t i = 0; i < children.size(); ++i)
|
| - RemoveDirectoryChild(children[i]);
|
| + if (entry->file_info().is_directory()) {
|
| + std::vector<std::string> children;
|
| + storage_->GetChildren(resource_id, &children);
|
| + for (size_t i = 0; i < children.size(); ++i) {
|
| + if (!RemoveEntryRecursively(children[i]))
|
| + return false;
|
| + }
|
| + }
|
| + return storage_->RemoveEntry(resource_id);
|
| }
|
|
|
| scoped_ptr<DriveEntryProtoVector>
|
|
|