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 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_ | 5 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_ |
6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_ | 6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/callback_forward.h" | |
14 #include "base/containers/hash_tables.h" | 13 #include "base/containers/hash_tables.h" |
15 #include "base/containers/scoped_ptr_hash_map.h" | 14 #include "base/containers/scoped_ptr_hash_map.h" |
| 15 #include "base/files/file_path.h" |
16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
17 #include "base/memory/scoped_vector.h" | 17 #include "base/memory/scoped_vector.h" |
18 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
19 #include "base/sequence_checker.h" | 19 #include "base/sequence_checker.h" |
20 #include "base/values.h" | 20 #include "base/values.h" |
21 #include "chrome/browser/sync_file_system/drive_backend/tracker_id_set.h" | 21 #include "chrome/browser/sync_file_system/drive_backend/tracker_id_set.h" |
22 #include "chrome/browser/sync_file_system/sync_callbacks.h" | |
23 #include "chrome/browser/sync_file_system/sync_status_code.h" | 22 #include "chrome/browser/sync_file_system/sync_status_code.h" |
24 | 23 |
25 namespace base { | |
26 class FilePath; | |
27 class SequencedTaskRunner; | |
28 class SingleThreadTaskRunner; | |
29 } | |
30 | |
31 namespace leveldb { | 24 namespace leveldb { |
32 class Env; | 25 class Env; |
33 } | 26 } |
34 | 27 |
35 namespace google_apis { | 28 namespace google_apis { |
36 class ChangeResource; | 29 class ChangeResource; |
37 class FileResource; | 30 class FileResource; |
38 class ResourceEntry; | 31 class ResourceEntry; |
39 } | 32 } |
40 | 33 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 // | 100 // |
108 // - If multiple trackers have the same parent tracker and same title, they | 101 // - If multiple trackers have the same parent tracker and same title, they |
109 // must not have same |file_id|, and at most one of them may be active. | 102 // must not have same |file_id|, and at most one of them may be active. |
110 // - If multiple trackers have the same |file_id|, at most one of them may be | 103 // - If multiple trackers have the same |file_id|, at most one of them may be |
111 // active. | 104 // active. |
112 // | 105 // |
113 class MetadataDatabase { | 106 class MetadataDatabase { |
114 public: | 107 public: |
115 typedef std::vector<std::string> FileIDList; | 108 typedef std::vector<std::string> FileIDList; |
116 | 109 |
117 typedef base::Callback< | |
118 void(SyncStatusCode status, scoped_ptr<MetadataDatabase> instance)> | |
119 CreateCallback; | |
120 | |
121 enum ActivationStatus { | 110 enum ActivationStatus { |
122 ACTIVATION_PENDING, | 111 ACTIVATION_PENDING, |
123 ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER, | 112 ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER, |
124 }; | 113 }; |
125 | 114 |
126 enum UpdateOption { | 115 enum UpdateOption { |
127 UPDATE_TRACKER_FOR_UNSYNCED_FILE, | 116 UPDATE_TRACKER_FOR_UNSYNCED_FILE, |
128 UPDATE_TRACKER_FOR_SYNCED_FILE, | 117 UPDATE_TRACKER_FOR_SYNCED_FILE, |
129 }; | 118 }; |
130 | 119 |
131 // The entry point of the MetadataDatabase for production code. | 120 // The entry point of the MetadataDatabase for production code. |
132 // If |env_override| is non-NULL, internal LevelDB uses |env_override| instead | 121 // If |env_override| is non-NULL, internal LevelDB uses |env_override| instead |
133 // of leveldb::Env::Default(). Use leveldb::MemEnv in test code for faster | 122 // of leveldb::Env::Default(). Use leveldb::MemEnv in test code for faster |
134 // testing. | 123 // testing. |
135 static void Create( | 124 static scoped_ptr<MetadataDatabase> Create( |
136 const base::FilePath& database_path, | 125 const base::FilePath& database_path, |
137 leveldb::Env* env_override, | 126 leveldb::Env* env_override, |
138 const CreateCallback& callback); | 127 SyncStatusCode* status); |
139 static SyncStatusCode CreateForTesting( | 128 static SyncStatusCode CreateForTesting( |
140 scoped_ptr<LevelDBWrapper> db, | 129 scoped_ptr<LevelDBWrapper> db, |
141 bool enable_on_disk_index, | 130 bool enable_on_disk_index, |
142 scoped_ptr<MetadataDatabase>* metadata_database_out); | 131 scoped_ptr<MetadataDatabase>* metadata_database_out); |
143 | 132 |
144 ~MetadataDatabase(); | 133 ~MetadataDatabase(); |
145 | 134 |
146 static void ClearDatabase(scoped_ptr<MetadataDatabase> metadata_database); | 135 static void ClearDatabase(scoped_ptr<MetadataDatabase> metadata_database); |
147 | 136 |
148 int64 GetLargestFetchedChangeID() const; | 137 int64 GetLargestFetchedChangeID() const; |
(...skipping 23 matching lines...) Expand all Loading... |
172 int64 GetLargestKnownChangeID() const; | 161 int64 GetLargestKnownChangeID() const; |
173 void UpdateLargestKnownChangeID(int64 change_id); | 162 void UpdateLargestKnownChangeID(int64 change_id); |
174 | 163 |
175 // Populates empty database with initial data. | 164 // Populates empty database with initial data. |
176 // Adds a file metadata and a file tracker for |sync_root_folder|, and adds | 165 // Adds a file metadata and a file tracker for |sync_root_folder|, and adds |
177 // file metadata and file trackers for each |app_root_folders|. | 166 // file metadata and file trackers for each |app_root_folders|. |
178 // Newly added tracker for |sync_root_folder| is active and non-dirty. | 167 // Newly added tracker for |sync_root_folder| is active and non-dirty. |
179 // Newly added trackers for |app_root_folders| are inactive and non-dirty. | 168 // Newly added trackers for |app_root_folders| are inactive and non-dirty. |
180 // Trackers for |app_root_folders| are not yet registered as app-roots, but | 169 // Trackers for |app_root_folders| are not yet registered as app-roots, but |
181 // are ready to register. | 170 // are ready to register. |
182 void PopulateInitialData( | 171 SyncStatusCode PopulateInitialData( |
183 int64 largest_change_id, | 172 int64 largest_change_id, |
184 const google_apis::FileResource& sync_root_folder, | 173 const google_apis::FileResource& sync_root_folder, |
185 const ScopedVector<google_apis::FileResource>& app_root_folders, | 174 const ScopedVector<google_apis::FileResource>& app_root_folders); |
186 const SyncStatusCallback& callback); | |
187 | 175 |
188 // Returns true if the folder associated to |app_id| is enabled. | 176 // Returns true if the folder associated to |app_id| is enabled. |
189 bool IsAppEnabled(const std::string& app_id) const; | 177 bool IsAppEnabled(const std::string& app_id) const; |
190 | 178 |
191 // Registers existing folder as the app-root for |app_id|. The folder | 179 // Registers existing folder as the app-root for |app_id|. The folder |
192 // must be an inactive folder that does not yet associated to any App. | 180 // must be an inactive folder that does not yet associated to any App. |
193 // This method associates the folder with |app_id| and activates it. | 181 // This method associates the folder with |app_id| and activates it. |
194 void RegisterApp(const std::string& app_id, | 182 SyncStatusCode RegisterApp(const std::string& app_id, |
195 const std::string& folder_id, | 183 const std::string& folder_id); |
196 const SyncStatusCallback& callback); | |
197 | 184 |
198 // Inactivates the folder associated to the app to disable |app_id|. | 185 // Inactivates the folder associated to the app to disable |app_id|. |
199 // Does nothing if |app_id| is already disabled. | 186 // Does nothing if |app_id| is already disabled. |
200 void DisableApp(const std::string& app_id, | 187 SyncStatusCode DisableApp(const std::string& app_id); |
201 const SyncStatusCallback& callback); | |
202 | 188 |
203 // Activates the folder associated to |app_id| to enable |app_id|. | 189 // Activates the folder associated to |app_id| to enable |app_id|. |
204 // Does nothing if |app_id| is already enabled. | 190 // Does nothing if |app_id| is already enabled. |
205 void EnableApp(const std::string& app_id, | 191 SyncStatusCode EnableApp(const std::string& app_id); |
206 const SyncStatusCallback& callback); | |
207 | 192 |
208 // Unregisters the folder as the app-root for |app_id|. If |app_id| does not | 193 // Unregisters the folder as the app-root for |app_id|. If |app_id| does not |
209 // exist, does nothing. The folder is left as an inactive regular folder. | 194 // exist, does nothing. The folder is left as an inactive regular folder. |
210 // Note that the inactivation drops all descendant files since they are no | 195 // Note that the inactivation drops all descendant files since they are no |
211 // longer reachable from sync-root via active folder or app-root. | 196 // longer reachable from sync-root via active folder or app-root. |
212 void UnregisterApp(const std::string& app_id, | 197 SyncStatusCode UnregisterApp(const std::string& app_id); |
213 const SyncStatusCallback& callback); | |
214 | 198 |
215 // Finds the app-root folder for |app_id|. Returns true if exists. | 199 // Finds the app-root folder for |app_id|. Returns true if exists. |
216 // Copies the result to |tracker| if it is non-NULL. | 200 // Copies the result to |tracker| if it is non-NULL. |
217 bool FindAppRootTracker(const std::string& app_id, | 201 bool FindAppRootTracker(const std::string& app_id, |
218 FileTracker* tracker) const; | 202 FileTracker* tracker) const; |
219 | 203 |
220 // Finds the file identified by |file_id|. Returns true if the file is found. | 204 // Finds the file identified by |file_id|. Returns true if the file is found. |
221 // Copies the metadata identified by |file_id| into |file| if exists and | 205 // Copies the metadata identified by |file_id| into |file| if exists and |
222 // |file| is non-NULL. | 206 // |file| is non-NULL. |
223 bool FindFileByFileID(const std::string& file_id, FileMetadata* file) const; | 207 bool FindFileByFileID(const std::string& file_id, FileMetadata* file) const; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 // Otherwise, assigns the nearest active ancestor to |full_path| to |tracker|. | 241 // Otherwise, assigns the nearest active ancestor to |full_path| to |tracker|. |
258 // Also, assigns the full path of |tracker| to |path|. | 242 // Also, assigns the full path of |tracker| to |path|. |
259 bool FindNearestActiveAncestor(const std::string& app_id, | 243 bool FindNearestActiveAncestor(const std::string& app_id, |
260 const base::FilePath& full_path, | 244 const base::FilePath& full_path, |
261 FileTracker* tracker, | 245 FileTracker* tracker, |
262 base::FilePath* path) const; | 246 base::FilePath* path) const; |
263 | 247 |
264 // Updates database by |changes|. | 248 // Updates database by |changes|. |
265 // Marks each tracker for modified file as dirty and adds new trackers if | 249 // Marks each tracker for modified file as dirty and adds new trackers if |
266 // needed. | 250 // needed. |
267 void UpdateByChangeList(int64 largest_change_id, | 251 SyncStatusCode UpdateByChangeList( |
268 ScopedVector<google_apis::ChangeResource> changes, | 252 int64 largest_change_id, |
269 const SyncStatusCallback& callback); | 253 ScopedVector<google_apis::ChangeResource> changes); |
270 | 254 |
271 // Updates database by |resource|. | 255 // Updates database by |resource|. |
272 // Marks each tracker for modified file as dirty and adds new trackers if | 256 // Marks each tracker for modified file as dirty and adds new trackers if |
273 // needed. | 257 // needed. |
274 void UpdateByFileResource(const google_apis::FileResource& resource, | 258 SyncStatusCode UpdateByFileResource( |
275 const SyncStatusCallback& callback); | 259 const google_apis::FileResource& resource); |
276 void UpdateByFileResourceList( | 260 SyncStatusCode UpdateByFileResourceList( |
277 ScopedVector<google_apis::FileResource> resources, | 261 ScopedVector<google_apis::FileResource> resources); |
278 const SyncStatusCallback& callback); | |
279 | 262 |
280 void UpdateByDeletedRemoteFile(const std::string& file_id, | 263 SyncStatusCode UpdateByDeletedRemoteFile(const std::string& file_id); |
281 const SyncStatusCallback& callback); | 264 SyncStatusCode UpdateByDeletedRemoteFileList(const FileIDList& file_ids); |
282 void UpdateByDeletedRemoteFileList(const FileIDList& file_ids, | |
283 const SyncStatusCallback& callback); | |
284 | 265 |
285 // Adds new FileTracker and FileMetadata. The database must not have | 266 // Adds new FileTracker and FileMetadata. The database must not have |
286 // |resource| beforehand. | 267 // |resource| beforehand. |
287 // The newly added tracker under |parent_tracker_id| is active and non-dirty. | 268 // The newly added tracker under |parent_tracker_id| is active and non-dirty. |
288 // Deactivates existing active tracker if exists that has the same title and | 269 // Deactivates existing active tracker if exists that has the same title and |
289 // parent_tracker to the newly added tracker. | 270 // parent_tracker to the newly added tracker. |
290 void ReplaceActiveTrackerWithNewResource( | 271 SyncStatusCode ReplaceActiveTrackerWithNewResource( |
291 int64 parent_tracker_id, | 272 int64 parent_tracker_id, |
292 const google_apis::FileResource& resource, | 273 const google_apis::FileResource& resource); |
293 const SyncStatusCallback& callback); | |
294 | 274 |
295 // Adds |child_file_ids| to |folder_id| as its children. | 275 // Adds |child_file_ids| to |folder_id| as its children. |
296 // This method affects the active tracker only. | 276 // This method affects the active tracker only. |
297 // If the tracker has no further change to sync, unmarks its dirty flag. | 277 // If the tracker has no further change to sync, unmarks its dirty flag. |
298 void PopulateFolderByChildList(const std::string& folder_id, | 278 SyncStatusCode PopulateFolderByChildList(const std::string& folder_id, |
299 const FileIDList& child_file_ids, | 279 const FileIDList& child_file_ids); |
300 const SyncStatusCallback& callback); | |
301 | 280 |
302 // Updates |synced_details| of the tracker with |updated_details|. | 281 // Updates |synced_details| of the tracker with |updated_details|. |
303 void UpdateTracker(int64 tracker_id, | 282 SyncStatusCode UpdateTracker(int64 tracker_id, |
304 const FileDetails& updated_details, | 283 const FileDetails& updated_details); |
305 const SyncStatusCallback& callback); | |
306 | 284 |
307 // Activates a tracker identified by |parent_tracker_id| and |file_id| if the | 285 // Activates a tracker identified by |parent_tracker_id| and |file_id| if the |
308 // tracker can be activated without inactivating other trackers that have the | 286 // tracker can be activated without inactivating other trackers that have the |
309 // same |file_id| but different paths. | 287 // same |file_id| but different paths. |
310 // If |file_id| has another active tracker, the function returns | 288 // If |file_id| has another active tracker, the function returns |
311 // ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER and does not invoke |callback|. | 289 // ACTIVATION_FAILED_ANOTHER_ACTIVE_TRACKER and does not invoke |callback|. |
312 // If there is another active tracker that has the same path but different | 290 // If there is another active tracker that has the same path but different |
313 // |file_id|, inactivates the tracker. | 291 // |file_id|, inactivates the tracker. |
314 // In success case, returns ACTIVATION_PENDING and invokes |callback| upon | 292 // In success case, returns ACTIVATION_PENDING and invokes |callback| upon |
315 // completion. | 293 // completion. |
316 // | 294 // |
317 // The tracker to be activated must: | 295 // The tracker to be activated must: |
318 // - have a tracked metadata in the database, | 296 // - have a tracked metadata in the database, |
319 // - have |synced_details| with valid |title|. | 297 // - have |synced_details| with valid |title|. |
320 ActivationStatus TryActivateTracker(int64 parent_tracker_id, | 298 ActivationStatus TryActivateTracker(int64 parent_tracker_id, |
321 const std::string& file_id, | 299 const std::string& file_id, |
322 const SyncStatusCallback& callback); | 300 SyncStatusCode* status); |
323 | 301 |
324 // Changes the priority of the tracker to low. | 302 // Changes the priority of the tracker to low. |
325 void DemoteTracker(int64 tracker_id); | 303 void DemoteTracker(int64 tracker_id); |
326 bool PromoteDemotedTrackers(); | 304 bool PromoteDemotedTrackers(); |
327 void PromoteDemotedTracker(int64 tracker_id); | 305 void PromoteDemotedTracker(int64 tracker_id); |
328 | 306 |
329 // Returns true if there is a normal priority dirty tracker. | 307 // Returns true if there is a normal priority dirty tracker. |
330 // Assigns the dirty tracker if exists and |tracker| is non-NULL. | 308 // Assigns the dirty tracker if exists and |tracker| is non-NULL. |
331 bool GetDirtyTracker(FileTracker* tracker) const; | 309 bool GetDirtyTracker(FileTracker* tracker) const; |
332 | 310 |
333 // Returns true if there is a low priority dirty tracker. | 311 // Returns true if there is a low priority dirty tracker. |
334 bool HasDemotedDirtyTracker() const; | 312 bool HasDemotedDirtyTracker() const; |
335 | 313 |
336 bool HasDirtyTracker() const; | 314 bool HasDirtyTracker() const; |
337 size_t CountDirtyTracker() const; | 315 size_t CountDirtyTracker() const; |
338 size_t CountFileMetadata() const; | 316 size_t CountFileMetadata() const; |
339 size_t CountFileTracker() const; | 317 size_t CountFileTracker() const; |
340 | 318 |
341 bool GetMultiParentFileTrackers(std::string* file_id, | 319 bool GetMultiParentFileTrackers(std::string* file_id, |
342 TrackerIDSet* trackers); | 320 TrackerIDSet* trackers); |
343 bool GetConflictingTrackers(TrackerIDSet* trackers); | 321 bool GetConflictingTrackers(TrackerIDSet* trackers); |
344 | 322 |
345 // Sets |app_ids| to a list of all registered app ids. | 323 // Sets |app_ids| to a list of all registered app ids. |
346 void GetRegisteredAppIDs(std::vector<std::string>* app_ids); | 324 void GetRegisteredAppIDs(std::vector<std::string>* app_ids); |
347 | 325 |
348 // Clears dirty flag of trackers that can be cleared without external | 326 // Clears dirty flag of trackers that can be cleared without external |
349 // interactien. | 327 // interactien. |
350 void SweepDirtyTrackers(const std::vector<std::string>& file_ids, | 328 SyncStatusCode SweepDirtyTrackers(const std::vector<std::string>& file_ids); |
351 const SyncStatusCallback& callback); | |
352 | 329 |
353 private: | 330 private: |
354 friend class MetadataDatabaseTest; | 331 friend class MetadataDatabaseTest; |
355 | 332 |
356 MetadataDatabase(const base::FilePath& database_path, | 333 MetadataDatabase(const base::FilePath& database_path, |
357 bool enable_on_disk_index, | 334 bool enable_on_disk_index, |
358 leveldb::Env* env_override); | 335 leveldb::Env* env_override); |
359 SyncStatusCode Initialize(); | 336 SyncStatusCode Initialize(); |
360 | 337 |
361 // Database manipulation methods. | 338 // Database manipulation methods. |
(...skipping 21 matching lines...) Expand all Loading... |
383 bool HasDisabledAppRoot(const FileTracker& tracker) const; | 360 bool HasDisabledAppRoot(const FileTracker& tracker) const; |
384 bool HasActiveTrackerForFileID(const std::string& file_id) const; | 361 bool HasActiveTrackerForFileID(const std::string& file_id) const; |
385 bool HasActiveTrackerForPath(int64 parent_tracker, | 362 bool HasActiveTrackerForPath(int64 parent_tracker, |
386 const std::string& title) const; | 363 const std::string& title) const; |
387 | 364 |
388 void RemoveUnneededTrackersForMissingFile(const std::string& file_id); | 365 void RemoveUnneededTrackersForMissingFile(const std::string& file_id); |
389 void UpdateByFileMetadata(const tracked_objects::Location& from_where, | 366 void UpdateByFileMetadata(const tracked_objects::Location& from_where, |
390 scoped_ptr<FileMetadata> file, | 367 scoped_ptr<FileMetadata> file, |
391 UpdateOption option); | 368 UpdateOption option); |
392 | 369 |
393 void WriteToDatabase(const SyncStatusCallback& callback); | 370 SyncStatusCode WriteToDatabase(); |
394 | 371 |
395 bool HasNewerFileMetadata(const std::string& file_id, int64 change_id); | 372 bool HasNewerFileMetadata(const std::string& file_id, int64 change_id); |
396 | 373 |
397 scoped_ptr<base::ListValue> DumpTrackers(); | 374 scoped_ptr<base::ListValue> DumpTrackers(); |
398 scoped_ptr<base::ListValue> DumpMetadata(); | 375 scoped_ptr<base::ListValue> DumpMetadata(); |
399 | 376 |
400 void AttachSyncRoot(const google_apis::FileResource& sync_root_folder); | 377 void AttachSyncRoot(const google_apis::FileResource& sync_root_folder); |
401 void AttachInitialAppRoot(const google_apis::FileResource& app_root_folder); | 378 void AttachInitialAppRoot(const google_apis::FileResource& app_root_folder); |
402 | 379 |
403 void ForceActivateTrackerByPath(int64 parent_tracker_id, | 380 void ForceActivateTrackerByPath(int64 parent_tracker_id, |
(...skipping 14 matching lines...) Expand all Loading... |
418 | 395 |
419 base::WeakPtrFactory<MetadataDatabase> weak_ptr_factory_; | 396 base::WeakPtrFactory<MetadataDatabase> weak_ptr_factory_; |
420 | 397 |
421 DISALLOW_COPY_AND_ASSIGN(MetadataDatabase); | 398 DISALLOW_COPY_AND_ASSIGN(MetadataDatabase); |
422 }; | 399 }; |
423 | 400 |
424 } // namespace drive_backend | 401 } // namespace drive_backend |
425 } // namespace sync_file_system | 402 } // namespace sync_file_system |
426 | 403 |
427 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_ | 404 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_ |
OLD | NEW |