1 // Copyright 2014 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 EXTENSIONS_BROWSER_VALUE_STORE_VALUE_STORE_H_ 6 #define EXTENSIONS_BROWSER_VALUE_STORE_VALUE_STORE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/values.h" 13 #include "extensions/browser/value_store/value_store_change.h" 14 15 // Interface for a storage area for Value objects. 16 class ValueStore { 17 public: 18 // Error codes returned from storage methods. 19 enum ErrorCode { 20 OK, 21 22 // The failure was due to some kind of database corruption. Depending on 23 // what is corrupted, some part of the database may be recoverable. 24 // 25 // For example, if the on-disk representation of leveldb is corrupted, it's 26 // likely the whole database will need to be wiped and started again. 27 // 28 // If a single key has been committed with an invalid JSON representation, 29 // just that key can be deleted without affecting the rest of the database. 30 CORRUPTION, 31 32 // The failure was due to the store being read-only (for example, policy). 33 READ_ONLY, 34 35 // The failure was due to the store running out of space. 36 QUOTA_EXCEEDED, 37 38 // Any other error. 39 OTHER_ERROR, 40 }; 41 42 // Bundles an ErrorCode with further metadata. 43 struct Error { 44 Error(ErrorCode code, 45 const std::string& message, 46 scoped_ptr<std::string> key); 47 ~Error(); 48 49 static scoped_ptr<Error> Create(ErrorCode code, 50 const std::string& message, 51 scoped_ptr<std::string> key) { 52 return make_scoped_ptr(new Error(code, message, key.Pass())); 53 } 54 55 // The error code. 56 const ErrorCode code; 57 58 // Message associated with the error. 59 const std::string message; 60 61 // The key associated with the error, if any. Use a scoped_ptr here 62 // because empty-string is a valid key. 63 // 64 // TODO(kalman): add test(s) for an empty key. 65 const scoped_ptr<std::string> key; 66 67 private: 68 DISALLOW_COPY_AND_ASSIGN(Error); 69 }; 70 71 // The result of a read operation (Get). 72 class ReadResultType { 73 public: 74 explicit ReadResultType(scoped_ptr<base::DictionaryValue> settings); 75 explicit ReadResultType(scoped_ptr<Error> error); 76 ~ReadResultType(); 77 78 bool HasError() const { return error_; } 79 80 bool IsCorrupted() const { 81 return error_.get() && error_->code == CORRUPTION; 82 } 83 84 // Gets the settings read from the storage. Note that this represents 85 // the root object. If you request the value for key "foo", that value will 86 // be in |settings|.|foo|. 87 // 88 // Must only be called if there is no error. 89 base::DictionaryValue& settings() { return *settings_; } 90 scoped_ptr<base::DictionaryValue> PassSettings() { 91 return settings_.Pass(); 92 } 93 94 // Only call if HasError is true. 95 const Error& error() const { return *error_; } 96 scoped_ptr<Error> PassError() { return error_.Pass(); } 97 98 private: 99 scoped_ptr<base::DictionaryValue> settings_; 100 scoped_ptr<Error> error_; 101 102 DISALLOW_COPY_AND_ASSIGN(ReadResultType); 103 }; 104 typedef scoped_ptr<ReadResultType> ReadResult; 105 106 // The result of a write operation (Set/Remove/Clear). 107 class WriteResultType { 108 public: 109 explicit WriteResultType(scoped_ptr<ValueStoreChangeList> changes); 110 explicit WriteResultType(scoped_ptr<Error> error); 111 ~WriteResultType(); 112 113 bool HasError() const { return error_; } 114 115 // Gets the list of changes to the settings which resulted from the write. 116 // Won't be present if the NO_GENERATE_CHANGES WriteOptions was given. 117 // Only call if HasError is false. 118 ValueStoreChangeList& changes() { return *changes_; } 119 scoped_ptr<ValueStoreChangeList> PassChanges() { return changes_.Pass(); } 120 121 // Only call if HasError is true. 122 const Error& error() const { return *error_; } 123 scoped_ptr<Error> PassError() { return error_.Pass(); } 124 125 private: 126 scoped_ptr<ValueStoreChangeList> changes_; 127 scoped_ptr<Error> error_; 128 129 DISALLOW_COPY_AND_ASSIGN(WriteResultType); 130 }; 131 typedef scoped_ptr<WriteResultType> WriteResult; 132 133 // Options for write operations. 134 enum WriteOptionsValues { 135 // Callers should usually use this. 136 DEFAULTS = 0, 137 138 // Ignore any quota restrictions. 139 IGNORE_QUOTA = 1<<1, 140 141 // Don't generate the changes for a WriteResult. 142 NO_GENERATE_CHANGES = 1<<2, 143 }; 144 typedef int WriteOptions; 145 146 virtual ~ValueStore() {} 147 148 // Helpers for making a Read/WriteResult. 149 template<typename T> 150 static ReadResult MakeReadResult(scoped_ptr<T> arg) { 151 return ReadResult(new ReadResultType(arg.Pass())); 152 } 153 154 template<typename T> 155 static WriteResult MakeWriteResult(scoped_ptr<T> arg) { 156 return WriteResult(new WriteResultType(arg.Pass())); 157 } 158 159 // Gets the amount of space being used by a single value, in bytes. 160 // Note: The GetBytesInUse methods are only used by extension settings at the 161 // moment. If these become more generally useful, the 162 // SettingsStorageQuotaEnforcer and WeakUnlimitedSettingsStorage classes 163 // should be moved to the value_store directory. 164 virtual size_t GetBytesInUse(const std::string& key) = 0; 165 166 // Gets the total amount of space being used by multiple values, in bytes. 167 virtual size_t GetBytesInUse(const std::vector<std::string>& keys) = 0; 168 169 // Gets the total amount of space being used by this storage area, in bytes. 170 virtual size_t GetBytesInUse() = 0; 171 172 // Gets a single value from storage. 173 virtual ReadResult Get(const std::string& key) = 0; 174 175 // Gets multiple values from storage. 176 virtual ReadResult Get(const std::vector<std::string>& keys) = 0; 177 178 // Gets all values from storage. 179 virtual ReadResult Get() = 0; 180 181 // Sets a single key to a new value. 182 virtual WriteResult Set(WriteOptions options, 183 const std::string& key, 184 const base::Value& value) = 0; 185 186 // Sets multiple keys to new values. 187 virtual WriteResult Set( 188 WriteOptions options, const base::DictionaryValue& values) = 0; 189 190 // Removes a key from the storage. 191 virtual WriteResult Remove(const std::string& key) = 0; 192 193 // Removes multiple keys from the storage. 194 virtual WriteResult Remove(const std::vector<std::string>& keys) = 0; 195 196 // Clears the storage. 197 virtual WriteResult Clear() = 0; 198 199 // In the event of corruption, the ValueStore should be able to restore 200 // itself. This means deleting local corrupted files. If only a few keys are 201 // corrupted, then some of the database may be saved. If the full database is 202 // corrupted, this will erase it in its entirety. 203 // Returns true on success, false on failure. The only way this will fail is 204 // if we also cannot delete the database file. 205 // Note: This method may be expensive; some implementations may need to read 206 // the entire database to restore. Use sparingly. 207 // Note: This method (and the following RestoreKey()) are rude, and do not 208 // make any logs, track changes, or other generally polite things. Please do 209 // not use these as substitutes for Clear() and Remove(). 210 virtual bool Restore() = 0; 211 212 // Similar to Restore(), but for only a particular key. If the key is corrupt, 213 // this will forcefully remove the key. It does not look at the database on 214 // the whole, which makes it faster, but does not guarantee there is no 215 // additional corruption. 216 // Returns true on success, and false on failure. If false, the next step is 217 // probably to Restore() the whole database. 218 virtual bool RestoreKey(const std::string& key) = 0; 219 }; 220 221 #endif // EXTENSIONS_BROWSER_VALUE_STORE_VALUE_STORE_H_ 222