metadata_database.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <map>
9bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <set>
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <string>
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <vector>
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback_forward.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_ptr.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_vector.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/weak_ptr.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/values.h"
18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/sync_file_system/drive_backend/tracker_set.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_callbacks.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace base {
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass FilePath;
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass SequencedTaskRunner;
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass SingleThreadTaskRunner;
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace leveldb {
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass DB;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass WriteBatch;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace google_apis {
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ChangeResource;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass FileResource;
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ResourceEntry;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace tracked_objects {
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class Location;
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace sync_file_system {
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive_backend {
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FileDetails;
47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass FileMetadata;
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochclass FileTracker;
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ServiceMetadata;
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct DatabaseContents;
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// MetadataDatabase holds and maintains a LevelDB instance and its indexes,
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// which holds 1)ServiceMetadata, 2)FileMetadata and 3)FileTracker.
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 1) ServiceMetadata is a singleton in the database which holds information for
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//    the backend.
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 2) FileMetadata represents a remote-side file and holds latest known
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//    metadata of the remote file.
58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 3) FileTracker represents a synced or to-be-synced file and maintains
59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//    the local-side folder tree.
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The term "file" includes files, folders and other resources on Drive.
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// FileTrackers form a tree structure on the database, which represents the
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// FileSystem trees of SyncFileSystem.  The tree has a FileTracker named
65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// sync-root as its root node, and a set of FileTracker named app-root.  An
66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// app-root represents a remote folder for an installed Chrome App and holds all
67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// synced contents for the App.
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// One FileMetadata is created for each tracked remote file, which is identified
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// by FileID.
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// One FileTracker is created for every different {parent tracker, FileID} pair,
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// excluding non-app-root inactive parent trackers. Multiple trackers may be
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// associated to one FileID when the file has multiple parents. Multiple
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// trackers may have the same {parent tracker, title} pair when the associated
75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// remote files have the same title.
76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Files have following state:
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//   - Unknown file
79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     - Has a dirty inactive tracker and empty synced_details.
80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     - Is initial state of a tracker, only file_id and parent_tracker_id field
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//       are known.
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//   - Folder
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//     - Is either one of sync-root folder, app-root folder or a regular folder.
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//     - Sync-root folder holds app-root folders as its direct children, and
85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//       holds entire SyncFileSystem files as its descentants.  Its tracker
86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//       should be stored in ServiceMetadata by its tracker_id.
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//     - App-root folder holds all files for an application as its descendants.
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//   - File
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//   - Unsupported file
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//     - Represents unsupported files such as hosted documents. Must be
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//       inactive.
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Invariants:
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   - Any tracker in the database must either:
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//     - be sync-root,
96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     - have an app-root as its parent tracker, or
97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     - have an active tracker as its parent.
98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   That is, all trackers must be reachable from sync-root via app-root folders
99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   and active trackers.
100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   - Any active tracker must either:
102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     - have |needs_folder_listing| flag and dirty flag, or
103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     - have all children at the stored largest change ID.
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   - If multiple trackers have the same parent tracker and same title, they
106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     must not have same |file_id|, and at most one of them may be active.
107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   - If multiple trackers have the same |file_id|, at most one of them may be
108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     active.
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MetadataDatabase {
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public:
112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::map<std::string, FileMetadata*> FileByID;
113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::map<int64, FileTracker*> TrackerByID;
114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::map<std::string, TrackerSet> TrackersByFileID;
115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::map<std::string, TrackerSet> TrackersByTitle;
116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::map<int64, TrackersByTitle> TrackersByParentAndTitle;
117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::map<std::string, FileTracker*> TrackerByAppID;
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  typedef std::vector<std::string> FileIDList;
119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  typedef base::Callback<
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      void(SyncStatusCode status, scoped_ptr<MetadataDatabase> instance)>
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateCallback;
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The entry point of the MetadataDatabase for production code.
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void Create(base::SequencedTaskRunner* task_runner,
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const base::FilePath& database_path,
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const CreateCallback& callback);
128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ~MetadataDatabase();
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static void ClearDatabase(scoped_ptr<MetadataDatabase> metadata_database);
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 GetLargestFetchedChangeID() const;
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 GetSyncRootTrackerID() const;
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool HasSyncRoot() const;
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns all file metadata for the given |app_id|.
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::ListValue> DumpFiles(const std::string& app_id);
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns all database data.
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<base::ListValue> DumpDatabase();
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(tzik): Move GetLargestKnownChangeID() to private section, and hide its
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // handling in the class, instead of letting user do.
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Gets / updates the largest known change ID.
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The largest known change ID is on-memory and not persist over restart.
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This is supposed to use when a task fetches ChangeList in parallel to other
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // operation.  When a task starts fetching paged ChangeList one by one, it
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // should update the largest known change ID on the first round and background
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // remaining fetch job.
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Then, when other tasks that update FileMetadata by UpdateByFileResource,
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // it should use largest known change ID as the |change_id| that prevents
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // FileMetadata from overwritten by ChangeList.
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Also if other tasks try to update a remote resource whose change is not yet
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // retrieved the task should fail due to etag check, so we should be fine.
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 GetLargestKnownChangeID() const;
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void UpdateLargestKnownChangeID(int64 change_id);
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Populates empty database with initial data.
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Adds a file metadata and a file tracker for |sync_root_folder|, and adds
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // file metadata and file trackers for each |app_root_folders|.
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Newly added tracker for |sync_root_folder| is active and non-dirty.
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Newly added trackers for |app_root_folders| are inactive and non-dirty.
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Trackers for |app_root_folders| are not yet registered as app-roots, but
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // are ready to register.
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void PopulateInitialData(
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      int64 largest_change_id,
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const google_apis::FileResource& sync_root_folder,
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const ScopedVector<google_apis::FileResource>& app_root_folders,
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const SyncStatusCallback& callback);
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns true if the folder associated to |app_id| is enabled.
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool IsAppEnabled(const std::string& app_id) const;
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Registers existing folder as the app-root for |app_id|.  The folder
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // must be an inactive folder that does not yet associated to any App.
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This method associates the folder with |app_id| and activates it.
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void RegisterApp(const std::string& app_id,
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   const std::string& folder_id,
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   const SyncStatusCallback& callback);
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Inactivates the folder associated to the app to disable |app_id|.
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Does nothing if |app_id| is already disabled.
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void DisableApp(const std::string& app_id,
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  const SyncStatusCallback& callback);
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Activates the folder associated to |app_id| to enable |app_id|.
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Does nothing if |app_id| is already enabled.
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void EnableApp(const std::string& app_id,
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 const SyncStatusCallback& callback);
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Unregisters the folder as the app-root for |app_id|.  If |app_id| does not
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // exist, does nothing.  The folder is left as an inactive regular folder.
194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Note that the inactivation drops all descendant files since they are no
195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // longer reachable from sync-root via active folder or app-root.
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void UnregisterApp(const std::string& app_id,
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     const SyncStatusCallback& callback);
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Finds the app-root folder for |app_id|.  Returns true if exists.
200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Copies the result to |tracker| if it is non-NULL.
201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool FindAppRootTracker(const std::string& app_id,
202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                          FileTracker* tracker) const;
203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Finds the file identified by |file_id|.  Returns true if the file is found.
205ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Copies the metadata identified by |file_id| into |file| if exists and
206ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // |file| is non-NULL.
207ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool FindFileByFileID(const std::string& file_id, FileMetadata* file) const;
208ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
209ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Finds the tracker identified by |tracker_id|.  Returns true if the tracker
210ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // is found.
211ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Copies the tracker identified by |tracker_id| into |tracker| if exists and
212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // |tracker| is non-NULL.
213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool FindTrackerByTrackerID(int64 tracker_id, FileTracker* tracker) const;
214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
215ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Finds the trackers tracking |file_id|.  Returns true if the trackers are
216ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // found.
217ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool FindTrackersByFileID(const std::string& file_id,
218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                            TrackerSet* trackers) const;
219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Finds the set of trackers whose parent's tracker ID is |parent_tracker_id|,
221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // and who has |title| as its title in the synced_details.
222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Copies the tracker set to |trackers| if it is non-NULL.
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Returns true if the trackers are found.
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool FindTrackersByParentAndTitle(
225ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      int64 parent_tracker_id,
226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      const std::string& title,
227ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      TrackerSet* trackers) const;
228ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
229ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Builds the file path for the given tracker.  Returns true on success.
230ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // |path| can be NULL.
231ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // The file path is relative to app-root and have a leading path separator.
232ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool BuildPathForTracker(int64 tracker_id, base::FilePath* path) const;
233ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Builds the file path for the given tracker for display purpose.
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This may return a path ending with '<unknown>' if the given tracker does
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // not have title information (yet). This may return an empty path.
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::FilePath BuildDisplayPathForTracker(const FileTracker& tracker) const;
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns false if no registered app exists associated to |app_id|.
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If |full_path| is active, assigns the tracker of |full_path| to |tracker|.
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Otherwise, assigns the nearest active ancestor to |full_path| to |tracker|.
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Also, assigns the full path of |tracker| to |path|.
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool FindNearestActiveAncestor(const std::string& app_id,
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const base::FilePath& full_path,
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 FileTracker* tracker,
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 base::FilePath* path) const;
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Updates database by |changes|.
249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Marks each tracker for modified file as dirty and adds new trackers if
250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // needed.
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void UpdateByChangeList(int64 largest_change_id,
2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          ScopedVector<google_apis::ChangeResource> changes,
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          const SyncStatusCallback& callback);
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Updates database by |resource|.
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Marks each tracker for modified file as dirty and adds new trackers if
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // needed.
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void UpdateByFileResource(const google_apis::FileResource& resource,
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const SyncStatusCallback& callback);
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void UpdateByFileResourceList(
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ScopedVector<google_apis::FileResource> resources,
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const SyncStatusCallback& callback);
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void UpdateByDeletedRemoteFile(const std::string& file_id,
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const SyncStatusCallback& callback);
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(tzik): Drop |change_id| parameter.
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Adds new FileTracker and FileMetadata.  The database must not have
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |resource| beforehand.
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The newly added tracker under |parent_tracker_id| is active and non-dirty.
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Deactivates existing active tracker if exists that has the same title and
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // parent_tracker to the newly added tracker.
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void ReplaceActiveTrackerWithNewResource(
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int64 parent_tracker_id,
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const google_apis::FileResource& resource,
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const SyncStatusCallback& callback);
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Adds |child_file_ids| to |folder_id| as its children.
2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // This method affects the active tracker only.
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // If the tracker has no further change to sync, unmarks its dirty flag.
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void PopulateFolderByChildList(const std::string& folder_id,
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 const FileIDList& child_file_ids,
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 const SyncStatusCallback& callback);
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Updates |synced_details| of the tracker with |updated_details|.
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void UpdateTracker(int64 tracker_id,
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const FileDetails& updated_details,
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const SyncStatusCallback& callback);
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns true if a tracker of the file can be safely activated without
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // deactivating any other trackers.  In this case, tries to activate the
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // tracker, and invokes |callback| upon completion.
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns false otherwise.  In false case, |callback| will not be invoked.
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool TryNoSideEffectActivation(int64 parent_tracker_id,
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const std::string& file_id,
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const SyncStatusCallback& callback);
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Changes the priority of the tracker to low.
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void LowerTrackerPriority(int64 tracker_id);
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void PromoteLowerPriorityTrackersToNormal();
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns true if there is a normal priority dirty tracker.
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Assigns the dirty tracker if exists and |tracker| is non-NULL.
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool GetNormalPriorityDirtyTracker(FileTracker* tracker) const;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns true if there is a low priority dirty tracker.
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Assigns the dirty tracker if exists and |tracker| is non-NULL.
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool GetLowPriorityDirtyTracker(FileTracker* tracker) const;
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool HasDirtyTracker() const {
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return !dirty_trackers_.empty() || !low_priority_dirty_trackers_.empty();
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t GetDirtyTrackerCount() {
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return dirty_trackers_.size();
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool GetMultiParentFileTrackers(std::string* file_id,
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                  TrackerSet* trackers);
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool GetConflictingTrackers(TrackerSet* trackers);
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sets |app_ids| to a list of all registered app ids.
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void GetRegisteredAppIDs(std::vector<std::string>* app_ids);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private:
3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  friend class ListChangesTaskTest;
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  friend class MetadataDatabaseTest;
3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  friend class RegisterAppTaskTest;
33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  friend class SyncEngineInitializerTest;
33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
332bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  struct DirtyTrackerComparator {
333bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    bool operator()(const FileTracker* left,
334bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                    const FileTracker* right) const;
335bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  };
336bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
337bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  typedef std::set<FileTracker*, DirtyTrackerComparator> DirtyTrackers;
338bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MetadataDatabase(base::SequencedTaskRunner* task_runner,
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   const base::FilePath& database_path);
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void CreateOnTaskRunner(base::SingleThreadTaskRunner* callback_runner,
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 base::SequencedTaskRunner* task_runner,
3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const base::FilePath& database_path,
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const CreateCallback& callback);
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static SyncStatusCode CreateForTesting(
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scoped_ptr<leveldb::DB> db,
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scoped_ptr<MetadataDatabase>* metadata_database_out);
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode InitializeOnTaskRunner();
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void BuildIndexes(DatabaseContents* contents);
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Database manipulation methods.
352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void RegisterTrackerAsAppRoot(const std::string& app_id,
353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                int64 tracker_id,
354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                leveldb::WriteBatch* batch);
355ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void MakeTrackerActive(int64 tracker_id, leveldb::WriteBatch* batch);
356ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void MakeTrackerInactive(int64 tracker_id, leveldb::WriteBatch* batch);
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void MakeAppRootDisabled(int64 tracker_id, leveldb::WriteBatch* batch);
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void MakeAppRootEnabled(int64 tracker_id, leveldb::WriteBatch* batch);
359ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
360ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void UnregisterTrackerAsAppRoot(const std::string& app_id,
361ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                  leveldb::WriteBatch* batch);
362ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void RemoveAllDescendantTrackers(int64 root_tracker_id,
363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                   leveldb::WriteBatch* batch);
364ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void CreateTrackerForParentAndFileID(const FileTracker& parent_tracker,
366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                       const std::string& file_id,
367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                       leveldb::WriteBatch* batch);
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CreateTrackerForParentAndFileMetadata(const FileTracker& parent_tracker,
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             const FileMetadata& file_metadata,
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             leveldb::WriteBatch* batch);
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void CreateTrackerInternal(const FileTracker& parent_tracker,
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const std::string& file_id,
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const FileDetails* details,
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             leveldb::WriteBatch* batch);
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void RemoveTracker(int64 tracker_id, leveldb::WriteBatch* batch);
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RemoveTrackerIgnoringSameTitle(int64 tracker_id,
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      leveldb::WriteBatch* batch);
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void RemoveTrackerInternal(int64 tracker_id,
38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                             leveldb::WriteBatch* batch,
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             bool ignoring_same_title);
382ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void MaybeAddTrackersForNewFile(const FileMetadata& file,
383ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                  leveldb::WriteBatch* batch);
384ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void MarkSingleTrackerDirty(FileTracker* tracker,
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              leveldb::WriteBatch* batch);
387ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void MarkTrackerSetDirty(TrackerSet* trackers,
388ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                           leveldb::WriteBatch* batch);
389ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void MarkTrackersDirtyByFileID(const std::string& file_id,
390ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                 leveldb::WriteBatch* batch);
391ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void MarkTrackersDirtyByPath(int64 parent_tracker_id,
392ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                               const std::string& title,
393ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                               leveldb::WriteBatch* batch);
394ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
395ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void EraseTrackerFromFileIDIndex(FileTracker* tracker,
396ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                   leveldb::WriteBatch* batch);
397ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void EraseTrackerFromPathIndex(FileTracker* tracker);
398ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void EraseFileFromDatabase(const std::string& file_id,
399ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             leveldb::WriteBatch* batch);
400ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
401ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  int64 GetNextTrackerID(leveldb::WriteBatch* batch);
402ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void RecursiveMarkTrackerAsDirty(int64 root_tracker_id,
4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                   leveldb::WriteBatch* batch);
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool CanActivateTracker(const FileTracker& tracker);
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool ShouldKeepDirty(const FileTracker& tracker) const;
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool HasDisabledAppRoot(const FileTracker& tracker) const;
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool HasActiveTrackerForFileID(const std::string& file_id) const;
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool HasActiveTrackerForPath(int64 parent_tracker,
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               const std::string& title) const;
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void UpdateByFileMetadata(const tracked_objects::Location& from_where,
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            scoped_ptr<FileMetadata> file,
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            leveldb::WriteBatch* batch);
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                       const SyncStatusCallback& callback);
4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool HasNewerFileMetadata(const std::string& file_id, int64 change_id);
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<base::ListValue> DumpTrackers();
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<base::ListValue> DumpMetadata();
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<base::SequencedTaskRunner> task_runner_;
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::FilePath database_path_;
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<leveldb::DB> db_;
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<ServiceMetadata> service_metadata_;
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int64 largest_known_change_id_;
4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  FileByID file_by_id_;  // Owned.
433bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  TrackerByID tracker_by_id_;  // Owned.
434bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
435bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Maps FileID to trackers.  The active tracker must be unique per FileID.
436bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // This must be updated when updating |active| field of a tracker.
437bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  TrackersByFileID trackers_by_file_id_;  // Not owned.
438bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
439bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Maps AppID to the app-root tracker.
440bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // This must be updated when a tracker is registered/unregistered as an
441bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // app-root.
442bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  TrackerByAppID app_root_by_app_id_;  // Not owned.
443bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
444bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Maps |tracker_id| to its children grouped by their |title|.
445bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // If the title is unknown for a tracker, treats its title as empty. Empty
446bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // titled file must not be active.
447bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // The active tracker must be unique per its parent_tracker and its title.
448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // This must be updated when updating |title|, |active| or
449bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // |parent_tracker_id|.
450bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  TrackersByParentAndTitle trackers_by_parent_and_title_;
451bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
452bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Holds all trackers which marked as dirty.
453bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // This must be updated when updating |dirty| field of a tracker.
454bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  DirtyTrackers dirty_trackers_;  // Not owned.
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DirtyTrackers low_priority_dirty_trackers_;  // Not owned.
456bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
4577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::WeakPtrFactory<MetadataDatabase> weak_ptr_factory_;
4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MetadataDatabase);
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive_backend
463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace sync_file_system
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_METADATA_DATABASE_H_
466