Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/sync_file_system/drive_backend/metadata_database.h" | 5 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <stack> | 8 #include <stack> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 result.reserve(total_size); | 77 result.reserve(total_size); |
| 78 for (PathComponents::const_reverse_iterator itr = components.rbegin(); | 78 for (PathComponents::const_reverse_iterator itr = components.rbegin(); |
| 79 itr != components.rend(); ++itr) { | 79 itr != components.rend(); ++itr) { |
| 80 result.append(1, base::FilePath::kSeparators[0]); | 80 result.append(1, base::FilePath::kSeparators[0]); |
| 81 result.append(itr->value()); | 81 result.append(itr->value()); |
| 82 } | 82 } |
| 83 | 83 |
| 84 return base::FilePath(result).NormalizePathSeparators(); | 84 return base::FilePath(result).NormalizePathSeparators(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 scoped_ptr<FileMetadata> CreateFileMetadataFromChangeResource( | 87 void PopulateFileDetailsByFileResource( |
| 88 const google_apis::ChangeResource& change) { | 88 const google_apis::FileResource& file_resource, |
| 89 scoped_ptr<FileMetadata> file(new FileMetadata); | 89 FileDetails* details) { |
| 90 file->set_file_id(change.file_id()); | 90 details->clear_parent_folder_ids(); |
| 91 | |
| 92 FileDetails* details = file->mutable_details(); | |
| 93 details->set_change_id(change.change_id()); | |
| 94 | |
| 95 if (change.is_deleted()) { | |
| 96 details->set_deleted(true); | |
| 97 return file.Pass(); | |
| 98 } | |
| 99 | |
| 100 const google_apis::FileResource& file_resource = *change.file(); | |
| 101 for (ScopedVector<google_apis::ParentReference>::const_iterator itr = | 91 for (ScopedVector<google_apis::ParentReference>::const_iterator itr = |
| 102 file_resource.parents().begin(); | 92 file_resource.parents().begin(); |
| 103 itr != file_resource.parents().end(); | 93 itr != file_resource.parents().end(); |
| 104 ++itr) { | 94 ++itr) { |
| 105 details->add_parent_folder_ids((*itr)->file_id()); | 95 details->add_parent_folder_ids((*itr)->file_id()); |
| 106 } | 96 } |
| 107 details->set_title(file_resource.title()); | 97 details->set_title(file_resource.title()); |
| 108 | 98 |
| 109 google_apis::DriveEntryKind kind = file_resource.GetKind(); | 99 google_apis::DriveEntryKind kind = file_resource.GetKind(); |
| 110 if (kind == google_apis::ENTRY_KIND_FILE) | 100 if (kind == google_apis::ENTRY_KIND_FILE) |
| 111 details->set_file_kind(FILE_KIND_FILE); | 101 details->set_file_kind(FILE_KIND_FILE); |
| 112 else if (kind == google_apis::ENTRY_KIND_FOLDER) | 102 else if (kind == google_apis::ENTRY_KIND_FOLDER) |
| 113 details->set_file_kind(FILE_KIND_FOLDER); | 103 details->set_file_kind(FILE_KIND_FOLDER); |
| 114 else | 104 else |
| 115 details->set_file_kind(FILE_KIND_UNSUPPORTED); | 105 details->set_file_kind(FILE_KIND_UNSUPPORTED); |
| 116 | 106 |
| 117 details->set_md5(file_resource.md5_checksum()); | 107 details->set_md5(file_resource.md5_checksum()); |
| 118 details->set_etag(file_resource.etag()); | 108 details->set_etag(file_resource.etag()); |
| 119 details->set_creation_time(file_resource.created_date().ToInternalValue()); | 109 details->set_creation_time(file_resource.created_date().ToInternalValue()); |
| 120 details->set_modification_time( | 110 details->set_modification_time( |
| 121 file_resource.modified_date().ToInternalValue()); | 111 file_resource.modified_date().ToInternalValue()); |
| 122 details->set_deleted(false); | 112 details->set_deleted(false); |
| 113 } | |
| 123 | 114 |
| 115 scoped_ptr<FileMetadata> CreateFileMetadataFromChangeResource( | |
| 116 const google_apis::ChangeResource& change) { | |
| 117 scoped_ptr<FileMetadata> file(new FileMetadata); | |
| 118 file->set_file_id(change.file_id()); | |
| 119 | |
| 120 FileDetails* details = file->mutable_details(); | |
| 121 details->set_change_id(change.change_id()); | |
| 122 | |
| 123 if (change.is_deleted()) { | |
| 124 details->set_deleted(true); | |
| 125 return file.Pass(); | |
| 126 } | |
| 127 | |
| 128 PopulateFileDetailsByFileResource(*change.file(), details); | |
| 124 return file.Pass(); | 129 return file.Pass(); |
| 125 } | 130 } |
| 126 | 131 |
| 132 void CreateInitialSyncRootTracker( | |
| 133 int64 tracker_id, | |
| 134 const google_apis::FileResource& file_resource, | |
| 135 scoped_ptr<FileMetadata>* file_out, | |
| 136 scoped_ptr<FileTracker>* tracker_out) { | |
| 137 FileDetails details; | |
| 138 PopulateFileDetailsByFileResource(file_resource, &details); | |
| 139 | |
| 140 scoped_ptr<FileMetadata> file(new FileMetadata); | |
| 141 file->set_file_id(file_resource.file_id()); | |
| 142 *file->mutable_details() = details; | |
| 143 | |
| 144 scoped_ptr<FileTracker> tracker(new FileTracker); | |
| 145 tracker->set_tracker_id(tracker_id); | |
| 146 tracker->set_file_id(file_resource.file_id()); | |
| 147 tracker->set_parent_tracker_id(0); | |
| 148 tracker->set_tracker_kind(TRACKER_KIND_REGULAR); | |
| 149 tracker->set_dirty(false); | |
| 150 tracker->set_active(true); | |
| 151 tracker->set_needs_folder_listing(false); | |
| 152 *tracker->mutable_synced_details() = details; | |
| 153 | |
| 154 *file_out = file.Pass(); | |
| 155 *tracker_out = tracker.Pass(); | |
| 156 } | |
| 157 | |
| 158 void CreateInitialAppRootTracker( | |
| 159 int64 tracker_id, | |
| 160 const FileTracker& parent_tracker, | |
| 161 const google_apis::FileResource& file_resource, | |
| 162 scoped_ptr<FileMetadata>* file_out, | |
| 163 scoped_ptr<FileTracker>* tracker_out) { | |
| 164 FileDetails details; | |
| 165 PopulateFileDetailsByFileResource(file_resource, &details); | |
| 166 | |
| 167 scoped_ptr<FileMetadata> file(new FileMetadata); | |
| 168 file->set_file_id(file_resource.file_id()); | |
| 169 *file->mutable_details() = details; | |
| 170 | |
| 171 scoped_ptr<FileTracker> tracker(new FileTracker); | |
| 172 tracker->set_tracker_id(tracker_id); | |
| 173 tracker->set_parent_tracker_id(parent_tracker.tracker_id()); | |
| 174 tracker->set_file_id(file_resource.file_id()); | |
| 175 tracker->set_tracker_kind(TRACKER_KIND_REGULAR); | |
| 176 tracker->set_dirty(false); | |
| 177 tracker->set_active(false); | |
|
kinuko
2013/09/05 08:43:43
Initially we add this as non-active REGULAR tracke
tzik
2013/09/05 09:17:02
Yes, we do.
The tracker will be registered as a ap
| |
| 178 tracker->set_needs_folder_listing(false); | |
| 179 *tracker->mutable_synced_details() = details; | |
| 180 | |
| 181 *file_out = file.Pass(); | |
| 182 *tracker_out = tracker.Pass(); | |
| 183 } | |
| 184 | |
| 127 void AdaptLevelDBStatusToSyncStatusCode(const SyncStatusCallback& callback, | 185 void AdaptLevelDBStatusToSyncStatusCode(const SyncStatusCallback& callback, |
| 128 const leveldb::Status& status) { | 186 const leveldb::Status& status) { |
| 129 callback.Run(LevelDBStatusToSyncStatusCode(status)); | 187 callback.Run(LevelDBStatusToSyncStatusCode(status)); |
| 130 } | 188 } |
| 131 | 189 |
| 132 void PutServiceMetadataToBatch(const ServiceMetadata& service_metadata, | 190 void PutServiceMetadataToBatch(const ServiceMetadata& service_metadata, |
| 133 leveldb::WriteBatch* batch) { | 191 leveldb::WriteBatch* batch) { |
| 134 std::string value; | 192 std::string value; |
| 135 bool success = service_metadata.SerializeToString(&value); | 193 bool success = service_metadata.SerializeToString(&value); |
| 136 DCHECK(success); | 194 DCHECK(success); |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 STLDeleteContainerPairSecondPointers( | 558 STLDeleteContainerPairSecondPointers( |
| 501 file_by_id_.begin(), file_by_id_.end()); | 559 file_by_id_.begin(), file_by_id_.end()); |
| 502 STLDeleteContainerPairSecondPointers( | 560 STLDeleteContainerPairSecondPointers( |
| 503 tracker_by_id_.begin(), tracker_by_id_.end()); | 561 tracker_by_id_.begin(), tracker_by_id_.end()); |
| 504 } | 562 } |
| 505 | 563 |
| 506 int64 MetadataDatabase::GetLargestChangeID() const { | 564 int64 MetadataDatabase::GetLargestChangeID() const { |
| 507 return service_metadata_->largest_change_id(); | 565 return service_metadata_->largest_change_id(); |
| 508 } | 566 } |
| 509 | 567 |
| 568 bool MetadataDatabase::HasSyncRoot() const { | |
| 569 return service_metadata_->has_sync_root_tracker_id() && | |
| 570 !!service_metadata_->sync_root_tracker_id(); | |
| 571 } | |
| 572 | |
| 573 void MetadataDatabase::PopulateInitialData( | |
| 574 int64 largest_change_id, | |
| 575 const google_apis::FileResource& sync_root_folder, | |
| 576 const ScopedVector<google_apis::FileResource>& app_root_folders, | |
| 577 const SyncStatusCallback& callback) { | |
| 578 DCHECK(tracker_by_id_.empty()); | |
| 579 DCHECK(file_by_id_.empty()); | |
| 580 | |
| 581 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); | |
| 582 service_metadata_->set_largest_change_id(largest_change_id); | |
| 583 | |
| 584 FileTracker* sync_root_tracker = NULL; | |
| 585 int64 sync_root_tracker_id = 0; | |
| 586 { | |
| 587 scoped_ptr<FileMetadata> folder; | |
| 588 scoped_ptr<FileTracker> tracker; | |
| 589 CreateInitialSyncRootTracker(GetNextTrackerID(batch.get()), | |
| 590 sync_root_folder, | |
| 591 &folder, | |
| 592 &tracker); | |
| 593 std::string sync_root_folder_id = folder->file_id(); | |
| 594 sync_root_tracker = tracker.get(); | |
| 595 sync_root_tracker_id = tracker->tracker_id(); | |
| 596 | |
| 597 PutFileToBatch(*folder, batch.get()); | |
| 598 PutTrackerToBatch(*tracker, batch.get()); | |
| 599 | |
| 600 service_metadata_->set_sync_root_tracker_id(tracker->tracker_id()); | |
| 601 trackers_by_file_id_[folder->file_id()].Insert(tracker.get()); | |
| 602 | |
| 603 file_by_id_[sync_root_folder_id] = folder.release(); | |
| 604 tracker_by_id_[sync_root_tracker_id] = tracker.release(); | |
| 605 } | |
| 606 | |
| 607 for (ScopedVector<google_apis::FileResource>::const_iterator itr = | |
| 608 app_root_folders.begin(); | |
| 609 itr != app_root_folders.end(); | |
| 610 ++itr) { | |
| 611 const google_apis::FileResource& folder_resource = **itr; | |
|
kinuko
2013/09/05 08:43:43
nit: extra space
tzik
2013/09/05 09:17:02
Done.
| |
| 612 scoped_ptr<FileMetadata> folder; | |
| 613 scoped_ptr<FileTracker> tracker; | |
| 614 CreateInitialAppRootTracker(GetNextTrackerID(batch.get()), | |
| 615 *sync_root_tracker, | |
| 616 folder_resource, | |
| 617 &folder, | |
| 618 &tracker); | |
| 619 std::string title = folder->details().title(); | |
| 620 std::string folder_id = folder->file_id(); | |
| 621 int64 tracker_id = tracker->tracker_id(); | |
| 622 | |
| 623 PutFileToBatch(*folder, batch.get()); | |
| 624 PutTrackerToBatch(*tracker, batch.get()); | |
| 625 | |
| 626 trackers_by_file_id_[folder_id].Insert(tracker.get()); | |
| 627 trackers_by_parent_and_title_[sync_root_tracker_id][title] | |
| 628 .Insert(tracker.get()); | |
| 629 | |
| 630 file_by_id_[folder_id] = folder.release(); | |
| 631 tracker_by_id_[tracker_id] = tracker.release(); | |
| 632 } | |
| 633 | |
| 634 WriteToDatabase(batch.Pass(), callback); | |
|
kinuko
2013/09/05 08:43:43
We don't call PutServiceMetadataToBatch since it's
tzik
2013/09/05 09:17:02
I just forgot to call that. Good catch!
Fixed.
| |
| 635 } | |
| 636 | |
| 637 | |
| 510 void MetadataDatabase::RegisterApp(const std::string& app_id, | 638 void MetadataDatabase::RegisterApp(const std::string& app_id, |
| 511 const std::string& folder_id, | 639 const std::string& folder_id, |
| 512 const SyncStatusCallback& callback) { | 640 const SyncStatusCallback& callback) { |
| 513 if (FindAppRootTracker(app_id, NULL)) { | 641 if (FindAppRootTracker(app_id, NULL)) { |
| 514 // The app-root is already registered. | 642 // The app-root is already registered. |
| 515 RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK)); | 643 RunSoon(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK)); |
| 516 return; | 644 return; |
| 517 } | 645 } |
| 518 | 646 |
| 519 TrackerSet trackers; | 647 TrackerSet trackers; |
| (...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1338 FROM_HERE, | 1466 FROM_HERE, |
| 1339 base::Bind(&leveldb::DB::Write, | 1467 base::Bind(&leveldb::DB::Write, |
| 1340 base::Unretained(db_.get()), | 1468 base::Unretained(db_.get()), |
| 1341 leveldb::WriteOptions(), | 1469 leveldb::WriteOptions(), |
| 1342 base::Owned(batch.release())), | 1470 base::Owned(batch.release())), |
| 1343 base::Bind(&AdaptLevelDBStatusToSyncStatusCode, callback)); | 1471 base::Bind(&AdaptLevelDBStatusToSyncStatusCode, callback)); |
| 1344 } | 1472 } |
| 1345 | 1473 |
| 1346 } // namespace drive_backend | 1474 } // namespace drive_backend |
| 1347 } // namespace sync_file_system | 1475 } // namespace sync_file_system |
| OLD | NEW |