Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/chromeos/drive/drive_resource_metadata.cc

Issue 14108009: chromeos: Use WriteBatch to update DriveResourceMetadata DB (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename method Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/drive/drive_resource_metadata.h" 5 #include "chrome/browser/chromeos/drive/drive_resource_metadata.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/stringprintf.h" 8 #include "base/stringprintf.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/sys_info.h" 10 #include "base/sys_info.h"
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 // Initialize the grand root and "other" entries. "/drive" and "/drive/other". 215 // Initialize the grand root and "other" entries. "/drive" and "/drive/other".
216 // As an intermediate change, "/drive/root" is also added here. 216 // As an intermediate change, "/drive/root" is also added here.
217 if (!storage_->GetEntry(util::kDriveGrandRootSpecialResourceId)) { 217 if (!storage_->GetEntry(util::kDriveGrandRootSpecialResourceId)) {
218 DriveEntryProto root; 218 DriveEntryProto root;
219 root.mutable_file_info()->set_is_directory(true); 219 root.mutable_file_info()->set_is_directory(true);
220 root.set_resource_id(util::kDriveGrandRootSpecialResourceId); 220 root.set_resource_id(util::kDriveGrandRootSpecialResourceId);
221 root.set_title(util::kDriveGrandRootDirName); 221 root.set_title(util::kDriveGrandRootDirName);
222 storage_->PutEntry(CreateEntryWithProperBaseName(root)); 222 storage_->PutEntry(CreateEntryWithProperBaseName(root));
223 } 223 }
224 if (!storage_->GetEntry(util::kDriveOtherDirSpecialResourceId)) { 224 if (!storage_->GetEntry(util::kDriveOtherDirSpecialResourceId)) {
225 AddEntryToDirectory(util::CreateOtherDirEntry()); 225 PutEntryUnderDirectory(util::CreateOtherDirEntry());
226 } 226 }
227 } 227 }
228 228
229 void DriveResourceMetadata::DestroyOnBlockingPool() { 229 void DriveResourceMetadata::DestroyOnBlockingPool() {
230 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 230 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
231 delete this; 231 delete this;
232 } 232 }
233 233
234 void DriveResourceMetadata::ResetOnBlockingPool() { 234 void DriveResourceMetadata::ResetOnBlockingPool() {
235 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 235 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 return FileMoveResult(FILE_ERROR_NO_SPACE); 540 return FileMoveResult(FILE_ERROR_NO_SPACE);
541 541
542 // Disallow deletion of special entries "/drive" and "/drive/other". 542 // Disallow deletion of special entries "/drive" and "/drive/other".
543 if (util::IsSpecialResourceId(resource_id)) 543 if (util::IsSpecialResourceId(resource_id))
544 return FileMoveResult(FILE_ERROR_ACCESS_DENIED); 544 return FileMoveResult(FILE_ERROR_ACCESS_DENIED);
545 545
546 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(resource_id); 546 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(resource_id);
547 if (!entry) 547 if (!entry)
548 return FileMoveResult(FILE_ERROR_NOT_FOUND); 548 return FileMoveResult(FILE_ERROR_NOT_FOUND);
549 549
550 RemoveDirectoryChild(entry->resource_id()); 550 if (!RemoveEntryRecursively(entry->resource_id()))
551 return FileMoveResult(FILE_ERROR_FAILED);
552
551 return FileMoveResult(FILE_ERROR_OK, 553 return FileMoveResult(FILE_ERROR_OK,
552 GetFilePath(entry->parent_resource_id())); 554 GetFilePath(entry->parent_resource_id()));
553 } 555 }
554 556
555 scoped_ptr<DriveEntryProto> DriveResourceMetadata::FindEntryByPathSync( 557 scoped_ptr<DriveEntryProto> DriveResourceMetadata::FindEntryByPathSync(
556 const base::FilePath& file_path) { 558 const base::FilePath& file_path) {
557 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 559 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
558 560
559 // Start from the root. 561 // Start from the root.
560 scoped_ptr<DriveEntryProto> entry = 562 scoped_ptr<DriveEntryProto> entry =
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 return FILE_ERROR_INVALID_OPERATION; 674 return FILE_ERROR_INVALID_OPERATION;
673 675
674 // Update data. 676 // Update data.
675 scoped_ptr<DriveEntryProto> new_parent = 677 scoped_ptr<DriveEntryProto> new_parent =
676 GetDirectory(entry.parent_resource_id()); 678 GetDirectory(entry.parent_resource_id());
677 679
678 if (!new_parent) 680 if (!new_parent)
679 return FILE_ERROR_NOT_FOUND; 681 return FILE_ERROR_NOT_FOUND;
680 682
681 // Remove from the old parent and add it to the new parent with the new data. 683 // Remove from the old parent and add it to the new parent with the new data.
682 DetachEntryFromDirectory(old_entry->resource_id()); 684 if (!PutEntryUnderDirectory(CreateEntryWithProperBaseName(entry)))
683 AddEntryToDirectory(CreateEntryWithProperBaseName(entry)); 685 return FILE_ERROR_FAILED;
684 686
685 if (out_file_path) 687 if (out_file_path)
686 *out_file_path = GetFilePath(entry.resource_id()); 688 *out_file_path = GetFilePath(entry.resource_id());
687 689
688 if (out_entry) { 690 if (out_entry) {
689 // Note that base_name is not the same for the new entry and entry_proto. 691 // Note that base_name is not the same for the new entry and entry_proto.
690 scoped_ptr<DriveEntryProto> result_entry_proto = 692 scoped_ptr<DriveEntryProto> result_entry_proto =
691 storage_->GetEntry(entry.resource_id()); 693 storage_->GetEntry(entry.resource_id());
692 DCHECK(result_entry_proto); 694 DCHECK(result_entry_proto);
693 *out_entry = *result_entry_proto; 695 *out_entry = *result_entry_proto;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 // have a parent resource ID which does not match the target directory's. 734 // have a parent resource ID which does not match the target directory's.
733 // 735 //
734 // TODO(satorux): Move the filtering logic to somewhere more appropriate. 736 // TODO(satorux): Move the filtering logic to somewhere more appropriate.
735 // crbug.com/193525. 737 // crbug.com/193525.
736 if (entry_proto.parent_resource_id() != 738 if (entry_proto.parent_resource_id() !=
737 directory_fetch_info.resource_id()) { 739 directory_fetch_info.resource_id()) {
738 DVLOG(1) << "Wrong-parent entry rejected: " << entry_proto.resource_id(); 740 DVLOG(1) << "Wrong-parent entry rejected: " << entry_proto.resource_id();
739 continue; 741 continue;
740 } 742 }
741 743
742 scoped_ptr<DriveEntryProto> existing_entry = 744 if (!PutEntryUnderDirectory(CreateEntryWithProperBaseName(entry_proto)))
743 storage_->GetEntry(entry_proto.resource_id()); 745 return FileMoveResult(FILE_ERROR_FAILED);
744 if (existing_entry)
745 DetachEntryFromDirectory(entry_proto.resource_id());
746
747 AddEntryToDirectory(CreateEntryWithProperBaseName(entry_proto));
748 } 746 }
749 747
750 // Go through the existing entries and remove deleted entries. 748 // Go through the existing entries and remove deleted entries.
751 scoped_ptr<DriveEntryProtoVector> entries = 749 scoped_ptr<DriveEntryProtoVector> entries =
752 DirectoryChildrenToProtoVector(directory->resource_id()); 750 DirectoryChildrenToProtoVector(directory->resource_id());
753 for (size_t i = 0; i < entries->size(); ++i) { 751 for (size_t i = 0; i < entries->size(); ++i) {
754 if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 752 if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_))
755 return FileMoveResult(FILE_ERROR_NO_SPACE); 753 return FileMoveResult(FILE_ERROR_NO_SPACE);
756 754
757 const DriveEntryProto& entry_proto = entries->at(i); 755 const DriveEntryProto& entry_proto = entries->at(i);
758 if (entry_proto_map.count(entry_proto.resource_id()) == 0) 756 if (entry_proto_map.count(entry_proto.resource_id()) == 0) {
759 RemoveDirectoryChild(entry_proto.resource_id()); 757 if (!RemoveEntryRecursively(entry_proto.resource_id()))
758 return FileMoveResult(FILE_ERROR_FAILED);
759 }
760 } 760 }
761 761
762 return FileMoveResult(FILE_ERROR_OK, GetFilePath(directory->resource_id())); 762 return FileMoveResult(FILE_ERROR_OK, GetFilePath(directory->resource_id()));
763 } 763 }
764 764
765 DriveResourceMetadata::FileMoveResult 765 DriveResourceMetadata::FileMoveResult
766 DriveResourceMetadata::AddEntryOnBlockingPool( 766 DriveResourceMetadata::AddEntryOnBlockingPool(
767 const DriveEntryProto& entry_proto) { 767 const DriveEntryProto& entry_proto) {
768 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 768 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
769 769
770 if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) 770 if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_))
771 return FileMoveResult(FILE_ERROR_NO_SPACE); 771 return FileMoveResult(FILE_ERROR_NO_SPACE);
772 772
773 scoped_ptr<DriveEntryProto> existing_entry = 773 scoped_ptr<DriveEntryProto> existing_entry =
774 storage_->GetEntry(entry_proto.resource_id()); 774 storage_->GetEntry(entry_proto.resource_id());
775 if (existing_entry) 775 if (existing_entry)
776 return FileMoveResult(FILE_ERROR_EXISTS); 776 return FileMoveResult(FILE_ERROR_EXISTS);
777 777
778 scoped_ptr<DriveEntryProto> parent = 778 scoped_ptr<DriveEntryProto> parent =
779 GetDirectory(entry_proto.parent_resource_id()); 779 GetDirectory(entry_proto.parent_resource_id());
780 if (!parent) 780 if (!parent)
781 return FileMoveResult(FILE_ERROR_NOT_FOUND); 781 return FileMoveResult(FILE_ERROR_NOT_FOUND);
782 782
783 AddEntryToDirectory(entry_proto); 783 if (!PutEntryUnderDirectory(entry_proto))
784 return FileMoveResult(FILE_ERROR_FAILED);
785
784 return FileMoveResult(FILE_ERROR_OK, GetFilePath(entry_proto.resource_id())); 786 return FileMoveResult(FILE_ERROR_OK, GetFilePath(entry_proto.resource_id()));
785 } 787 }
786 788
787 scoped_ptr<DriveEntryProto> DriveResourceMetadata::GetDirectory( 789 scoped_ptr<DriveEntryProto> DriveResourceMetadata::GetDirectory(
788 const std::string& resource_id) { 790 const std::string& resource_id) {
789 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 791 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
790 DCHECK(!resource_id.empty()); 792 DCHECK(!resource_id.empty());
791 793
792 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(resource_id); 794 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(resource_id);
793 return entry && entry->file_info().is_directory() ? 795 return entry && entry->file_info().is_directory() ?
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 842
841 void DriveResourceMetadata::RemoveAllOnBlockingPool() { 843 void DriveResourceMetadata::RemoveAllOnBlockingPool() {
842 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 844 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
843 845
844 // TODO(hashimoto): Return FILE_ERROR_NO_SPACE here. 846 // TODO(hashimoto): Return FILE_ERROR_NO_SPACE here.
845 if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) { 847 if (!EnoughDiskSpaceIsAvailableForDBOperation(data_directory_path_)) {
846 LOG(ERROR) << "Required disk space not available."; 848 LOG(ERROR) << "Required disk space not available.";
847 return; 849 return;
848 } 850 }
849 851
850 RemoveDirectoryChildren(util::kDriveGrandRootSpecialResourceId); 852 RemoveEntryRecursively(util::kDriveGrandRootSpecialResourceId);
851 SetUpDefaultEntries(); 853 SetUpDefaultEntries();
852 } 854 }
853 855
854 void DriveResourceMetadata::IterateEntriesOnBlockingPool( 856 void DriveResourceMetadata::IterateEntriesOnBlockingPool(
855 const IterateCallback& callback) { 857 const IterateCallback& callback) {
856 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 858 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
857 DCHECK(!callback.is_null()); 859 DCHECK(!callback.is_null());
858 860
859 storage_->Iterate(callback); 861 storage_->Iterate(callback);
860 } 862 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 DCHECK(!callback.is_null()); 901 DCHECK(!callback.is_null());
900 DCHECK(result.get()); 902 DCHECK(result.get());
901 903
902 result->second.path = second_path; 904 result->second.path = second_path;
903 result->second.error = error; 905 result->second.error = error;
904 result->second.proto = entry_proto.Pass(); 906 result->second.proto = entry_proto.Pass();
905 907
906 callback.Run(result.Pass()); 908 callback.Run(result.Pass());
907 } 909 }
908 910
909 void DriveResourceMetadata::AddEntryToDirectory(const DriveEntryProto& entry) { 911 bool DriveResourceMetadata::PutEntryUnderDirectory(
912 const DriveEntryProto& entry) {
910 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 913 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
911 914
912 DriveEntryProto updated_entry(entry); 915 DriveEntryProto updated_entry(entry);
913 916
914 // The entry name may have been changed due to prior name de-duplication. 917 // The entry name may have been changed due to prior name de-duplication.
915 // We need to first restore the file name based on the title before going 918 // We need to first restore the file name based on the title before going
916 // through name de-duplication again when it is added to another directory. 919 // through name de-duplication again when it is added to another directory.
917 SetBaseNameFromTitle(&updated_entry); 920 SetBaseNameFromTitle(&updated_entry);
918 921
919 // Do file name de-duplication - find files with the same name and 922 // Do file name de-duplication - Keep changing |entry|'s name until there is
920 // append a name modifier to the name. 923 // no other entry with the same name under the parent.
921 int modifier = 1; 924 int modifier = 1;
922 std::string new_base_name = updated_entry.base_name(); 925 std::string new_base_name = updated_entry.base_name();
923 while (!storage_->GetChild(entry.parent_resource_id(), 926 while (true) {
924 new_base_name).empty()) { 927 const std::string existing_entry_id =
928 storage_->GetChild(entry.parent_resource_id(), new_base_name);
929 if (existing_entry_id.empty() || existing_entry_id == entry.resource_id())
930 break;
931
925 base::FilePath new_path = 932 base::FilePath new_path =
926 base::FilePath::FromUTF8Unsafe(updated_entry.base_name()); 933 base::FilePath::FromUTF8Unsafe(updated_entry.base_name());
927 new_path = 934 new_path =
928 new_path.InsertBeforeExtension(base::StringPrintf(" (%d)", ++modifier)); 935 new_path.InsertBeforeExtension(base::StringPrintf(" (%d)", ++modifier));
929 new_base_name = new_path.AsUTF8Unsafe(); 936 new_base_name = new_path.AsUTF8Unsafe();
930 } 937 }
931 updated_entry.set_base_name(new_base_name); 938 updated_entry.set_base_name(new_base_name);
932 939
933 // Setup child and parent links.
934 storage_->PutChild(entry.parent_resource_id(),
935 updated_entry.base_name(),
936 updated_entry.resource_id());
937
938 // Add the entry to resource map. 940 // Add the entry to resource map.
939 storage_->PutEntry(updated_entry); 941 return storage_->PutEntry(updated_entry);
940 } 942 }
941 943
942 void DriveResourceMetadata::RemoveDirectoryChild( 944 bool DriveResourceMetadata::RemoveEntryRecursively(
943 const std::string& child_resource_id) { 945 const std::string& resource_id) {
944 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 946 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
945 947
946 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(child_resource_id); 948 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(resource_id);
947 DCHECK(entry);
948 DetachEntryFromDirectory(child_resource_id);
949 storage_->RemoveEntry(entry->resource_id());
950 if (entry->file_info().is_directory())
951 RemoveDirectoryChildren(child_resource_id);
952 }
953
954 void DriveResourceMetadata::DetachEntryFromDirectory(
955 const std::string& child_resource_id) {
956 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
957
958 scoped_ptr<DriveEntryProto> entry = storage_->GetEntry(child_resource_id);
959 DCHECK(entry); 949 DCHECK(entry);
960 950
961 // entry must be present in this directory. 951 if (entry->file_info().is_directory()) {
962 DCHECK_EQ(entry->resource_id(), 952 std::vector<std::string> children;
963 storage_->GetChild(entry->parent_resource_id(), 953 storage_->GetChildren(resource_id, &children);
964 entry->base_name())); 954 for (size_t i = 0; i < children.size(); ++i) {
965 955 if (!RemoveEntryRecursively(children[i]))
966 storage_->RemoveChild(entry->parent_resource_id(), entry->base_name()); 956 return false;
967 } 957 }
968 958 }
969 void DriveResourceMetadata::RemoveDirectoryChildren( 959 return storage_->RemoveEntry(resource_id);
970 const std::string& directory_resource_id) {
971 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
972
973 std::vector<std::string> children;
974 storage_->GetChildren(directory_resource_id, &children);
975 for (size_t i = 0; i < children.size(); ++i)
976 RemoveDirectoryChild(children[i]);
977 } 960 }
978 961
979 scoped_ptr<DriveEntryProtoVector> 962 scoped_ptr<DriveEntryProtoVector>
980 DriveResourceMetadata::DirectoryChildrenToProtoVector( 963 DriveResourceMetadata::DirectoryChildrenToProtoVector(
981 const std::string& directory_resource_id) { 964 const std::string& directory_resource_id) {
982 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); 965 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
983 966
984 scoped_ptr<DriveEntryProtoVector> entries(new DriveEntryProtoVector); 967 scoped_ptr<DriveEntryProtoVector> entries(new DriveEntryProtoVector);
985 std::vector<std::string> children; 968 std::vector<std::string> children;
986 storage_->GetChildren(directory_resource_id, &children); 969 storage_->GetChildren(directory_resource_id, &children);
987 for (size_t i = 0; i < children.size(); ++i) { 970 for (size_t i = 0; i < children.size(); ++i) {
988 scoped_ptr<DriveEntryProto> child = storage_->GetEntry(children[i]); 971 scoped_ptr<DriveEntryProto> child = storage_->GetEntry(children[i]);
989 DCHECK(child); 972 DCHECK(child);
990 entries->push_back(*child); 973 entries->push_back(*child);
991 } 974 }
992 return entries.Pass(); 975 return entries.Pass();
993 } 976 }
994 977
995 } // namespace drive 978 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698