1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_RESOURCE_METADATA_STORAGE_H_
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_DRIVE_RESOURCE_METADATA_STORAGE_H_
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/ref_counted.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
15b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_errors.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace base {
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass SequencedTaskRunner;
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace leveldb {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DB;
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class Iterator;
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace drive {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ResourceEntry;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ResourceMetadataHeader;
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace internal {
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Storage for ResourceMetadata which is responsible to manage resource
35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// entries and child-parent relationships between entries.
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ResourceMetadataStorage {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This should be incremented when incompatibility change is made to DB
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // format.
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static const int kDBVersion = 13;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Object to iterate over entries stored in this storage.
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  class Iterator {
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)   public:
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    explicit Iterator(scoped_ptr<leveldb::Iterator> it);
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ~Iterator();
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Returns true if this iterator cannot advance any more and does not point
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // to a valid entry. Get() and Advance() should not be called in such cases.
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    bool IsAtEnd() const;
51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Returns the ID of the entry currently pointed by this object.
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string GetID() const;
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Returns the entry currently pointed by this object.
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const ResourceEntry& GetValue() const;
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Advances to the next entry.
59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    void Advance();
60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Returns true if this object has encountered any error.
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    bool HasError() const;
63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)   private:
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ResourceEntry entry_;
66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    scoped_ptr<leveldb::Iterator> it_;
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(Iterator);
69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  };
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Cache information recovered from trashed DB.
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  struct RecoveredCacheInfo {
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RecoveredCacheInfo();
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ~RecoveredCacheInfo();
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool is_dirty;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string md5;
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string title;
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef std::map<std::string, RecoveredCacheInfo> RecoveredCacheInfoMap;
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Returns true if the DB was successfully upgraded to the newest version.
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static bool UpgradeOldDB(const base::FilePath& directory_path);
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ResourceMetadataStorage(const base::FilePath& directory_path,
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          base::SequencedTaskRunner* blocking_task_runner);
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const base::FilePath& directory_path() const { return directory_path_; }
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Returns true when cache entries were not loaded to the DB during
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // initialization.
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool cache_file_scan_is_needed() const { return cache_file_scan_is_needed_; }
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Destroys this object.
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Destroy();
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Initializes this object.
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool Initialize();
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Collects cache info from trashed resource map DB.
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RecoverCacheInfoFromTrashedResourceMap(RecoveredCacheInfoMap* out_info);
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sets the largest changestamp.
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError SetLargestChangestamp(int64 largest_changestamp);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Gets the largest changestamp.
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError GetLargestChangestamp(int64* largest_changestamp);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Puts the entry to this storage.
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError PutEntry(const ResourceEntry& entry);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Gets an entry stored in this storage.
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError GetEntry(const std::string& id, ResourceEntry* out_entry);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Removes an entry from this storage.
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError RemoveEntry(const std::string& id);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Returns an object to iterate over entries stored in this storage.
119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_ptr<Iterator> GetIterator();
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns the ID of the parent's child.
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError GetChild(const std::string& parent_id,
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     const std::string& child_name,
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     std::string* child_id);
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns the IDs of the parent's children.
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError GetChildren(const std::string& parent_id,
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        std::vector<std::string>* children);
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Returns the local ID associated with the given resource ID.
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError GetIdByResourceId(const std::string& resource_id,
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              std::string* out_id);
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class ResourceMetadataStorageTest;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // To destruct this object, use Destroy().
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ~ResourceMetadataStorage();
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Used to implement Destroy().
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void DestroyOnBlockingPool();
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns a string to be used as a key for child entry.
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static std::string GetChildEntryKey(const std::string& parent_id,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const std::string& child_name);
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Puts header.
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError PutHeader(const ResourceMetadataHeader& header);
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Gets header.
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError GetHeader(ResourceMetadataHeader* out_header);
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Checks validity of the data.
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool CheckValidity();
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Path to the directory where the data is stored.
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath directory_path_;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool cache_file_scan_is_needed_;
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Entries stored in this storage.
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<leveldb::DB> resource_map_;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ResourceMetadataStorage);
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace internal
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace drive
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_RESOURCE_METADATA_STORAGE_H_
173