blob: d2cb9cde3e32b7bff8c4f22c4d94e4843b495433 [file] [log] [blame]
Ben Murdocheb525c52013-07-10 11:40:50 +01001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
6#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
7
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01008#include <map>
Ben Murdochbb1529c2013-08-08 10:24:53 +01009#include <set>
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010010#include <string>
11
Ben Murdocheb525c52013-07-10 11:40:50 +010012#include "base/callback_forward.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/scoped_vector.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010015#include "base/memory/weak_ptr.h"
Ben Murdochbb1529c2013-08-08 10:24:53 +010016#include "chrome/browser/sync_file_system/drive_backend/tracker_set.h"
Ben Murdoch2385ea32013-08-06 11:01:04 +010017#include "chrome/browser/sync_file_system/sync_callbacks.h"
18#include "chrome/browser/sync_file_system/sync_status_code.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010019
20namespace base {
21class FilePath;
22class SequencedTaskRunner;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010023class SingleThreadTaskRunner;
Ben Murdocheb525c52013-07-10 11:40:50 +010024}
25
26namespace leveldb {
27class DB;
28class WriteBatch;
29}
30
31namespace google_apis {
32class ChangeResource;
33class FileResource;
34class ResourceEntry;
35}
36
37namespace sync_file_system {
38namespace drive_backend {
39
Ben Murdochbb1529c2013-08-08 10:24:53 +010040class FileMetadata;
41class FileTracker;
Ben Murdocheb525c52013-07-10 11:40:50 +010042class ServiceMetadata;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010043struct DatabaseContents;
Ben Murdocheb525c52013-07-10 11:40:50 +010044
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010045// MetadataDatabase instance holds and maintains database and its indexes. The
46// database holds metadata of the server-side files/folders as
47// DriveFileMetadata instances.
48// The term "file" includes files, folders and other resources on Drive.
49//
50// Files have following state:
51// - Unknown file
52// - Is initial state of the files, only file_id and parent_folder_id field
53// are known.
54// - Has empty synced_details, must be active and dirty.
55// - Folder
56// - Is either one of sync-root folder, app-root folder or a regular folder.
57// - Sync-root folder holds app-root folders as its direct children, and
58// holds entire SyncFileSystem files as its descentants. Its file_id is
59// stored in ServiceMetadata.
60// - App-root folder holds all files for an application as its descendants.
61// - File
62// - Unsupported file
63// - Represents unsupported files such as hosted documents. Must be
64// inactive.
65//
66// Invariants:
67// - Any file in the database must either:
68// - be sync-root,
69// - have an app-root as its parent folder, or
70// - have an active folder as its parent.
71// That is, all files must be reachable from sync-root via app-root folders
72// and active folders.
73//
74// - Any active folder must either:
75// - have needs_folder_listing flag and dirty flag, or
76// - have all children at the stored largest change id.
77//
Ben Murdocheb525c52013-07-10 11:40:50 +010078class MetadataDatabase {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010079 public:
Ben Murdochbb1529c2013-08-08 10:24:53 +010080 typedef std::map<std::string, FileMetadata*> FileByID;
81 typedef std::map<int64, FileTracker*> TrackerByID;
82 typedef std::map<std::string, TrackerSet> TrackersByFileID;
83 typedef std::map<std::string, TrackerSet> TrackersByTitle;
84 typedef std::map<int64, TrackersByTitle> TrackersByParentAndTitle;
85 typedef std::map<std::string, FileTracker*> TrackerByAppID;
86
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010087 typedef base::Callback<
88 void(SyncStatusCode status, scoped_ptr<MetadataDatabase> instance)>
89 CreateCallback;
90
91 static void Create(base::SequencedTaskRunner* task_runner,
92 const base::FilePath& database_path,
93 const CreateCallback& callback);
94 ~MetadataDatabase();
Ben Murdocheb525c52013-07-10 11:40:50 +010095
96 int64 GetLargestChangeID() const;
97
98 // Registers existing folder as the app-root for |app_id|. The folder
99 // must be an inactive folder that does not yet associated to any App.
100 // This method associates the folder with |app_id| and activates it.
101 void RegisterApp(const std::string& app_id,
102 const std::string& folder_id,
103 const SyncStatusCallback& callback);
104
105 // Inactivates the folder associated to the app to disable |app_id|.
106 // Does nothing if |app_id| is already disabled.
107 void DisableApp(const std::string& app_id,
108 const SyncStatusCallback& callback);
109
110 // Activates the folder associated to |app_id| to enable |app_id|.
111 // Does nothing if |app_id| is already enabled.
112 void EnableApp(const std::string& app_id,
113 const SyncStatusCallback& callback);
114
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100115 // Unregisters the folder as the app-root for |app_id|. If |app_id| does not
116 // exist, does nothing. The folder is left as an inactive normal folder.
Ben Murdocheb525c52013-07-10 11:40:50 +0100117 void UnregisterApp(const std::string& app_id,
118 const SyncStatusCallback& callback);
119
Ben Murdocheb525c52013-07-10 11:40:50 +0100120 // Updates database by |changes|.
121 // Marks dirty for each changed file if the file has the metadata in the
122 // database. Adds new metadata to track the file if the file doesn't have
123 // the metadata and its parent folder has the active metadata.
124 void UpdateByChangeList(ScopedVector<google_apis::ChangeResource> changes,
125 const SyncStatusCallback& callback);
126
Ben Murdocheb525c52013-07-10 11:40:50 +0100127 private:
Ben Murdochbb1529c2013-08-08 10:24:53 +0100128 struct DirtyTrackerComparator {
129 bool operator()(const FileTracker* left,
130 const FileTracker* right) const;
131 };
132
133 typedef std::set<FileTracker*, DirtyTrackerComparator> DirtyTrackers;
134
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100135 friend class MetadataDatabaseTest;
136
137 explicit MetadataDatabase(base::SequencedTaskRunner* task_runner);
138 static void CreateOnTaskRunner(base::SingleThreadTaskRunner* callback_runner,
139 base::SequencedTaskRunner* task_runner,
140 const base::FilePath& database_path,
141 const CreateCallback& callback);
142 static SyncStatusCode CreateForTesting(
143 scoped_ptr<leveldb::DB> db,
144 scoped_ptr<MetadataDatabase>* metadata_database_out);
145 SyncStatusCode InitializeOnTaskRunner(const base::FilePath& database_path);
146 void BuildIndexes(DatabaseContents* contents);
147
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100148 void WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
149 const SyncStatusCallback& callback);
150
151 scoped_refptr<base::SequencedTaskRunner> task_runner_;
152 scoped_ptr<leveldb::DB> db_;
153
154 scoped_ptr<ServiceMetadata> service_metadata_;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100155
Ben Murdochbb1529c2013-08-08 10:24:53 +0100156 FileByID file_by_id_; // Owned.
157 TrackerByID tracker_by_id_; // Owned.
158
159 // Maps FileID to trackers. The active tracker must be unique per FileID.
160 // This must be updated when updating |active| field of a tracker.
161 TrackersByFileID trackers_by_file_id_; // Not owned.
162
163 // Maps AppID to the app-root tracker.
164 // This must be updated when a tracker is registered/unregistered as an
165 // app-root.
166 TrackerByAppID app_root_by_app_id_; // Not owned.
167
168 // Maps |tracker_id| to its children grouped by their |title|.
169 // If the title is unknown for a tracker, treats its title as empty. Empty
170 // titled file must not be active.
171 // The active tracker must be unique per its parent_tracker and its title.
172 // This must be updated when updating |title|, |active| or
173 // |parent_tracker_id|.
174 TrackersByParentAndTitle trackers_by_parent_and_title_;
175
176 // Holds all trackers which marked as dirty.
177 // This must be updated when updating |dirty| field of a tracker.
178 DirtyTrackers dirty_trackers_; // Not owned.
179
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100180 base::WeakPtrFactory<MetadataDatabase> weak_ptr_factory_;
181
Ben Murdocheb525c52013-07-10 11:40:50 +0100182 DISALLOW_COPY_AND_ASSIGN(MetadataDatabase);
183};
184
185} // namespace drive_backend
186} // namespace sync_file_system
187
188#endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_