| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef EXTENSIONS_BROWSER_VALUE_STORE_VALUE_STORE_H_ |
| #define EXTENSIONS_BROWSER_VALUE_STORE_VALUE_STORE_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/values.h" |
| #include "extensions/browser/value_store/value_store_change.h" |
| |
| // Interface for a storage area for Value objects. |
| class ValueStore { |
| public: |
| // Error codes returned from storage methods. |
| enum ErrorCode { |
| OK, |
| |
| // The failure was due to some kind of database corruption. Depending on |
| // what is corrupted, some part of the database may be recoverable. |
| // |
| // For example, if the on-disk representation of leveldb is corrupted, it's |
| // likely the whole database will need to be wiped and started again. |
| // |
| // If a single key has been committed with an invalid JSON representation, |
| // just that key can be deleted without affecting the rest of the database. |
| CORRUPTION, |
| |
| // The failure was due to the store being read-only (for example, policy). |
| READ_ONLY, |
| |
| // The failure was due to the store running out of space. |
| QUOTA_EXCEEDED, |
| |
| // Any other error. |
| OTHER_ERROR, |
| }; |
| |
| // Bundles an ErrorCode with further metadata. |
| struct Error { |
| Error(ErrorCode code, |
| const std::string& message, |
| scoped_ptr<std::string> key); |
| ~Error(); |
| |
| static scoped_ptr<Error> Create(ErrorCode code, |
| const std::string& message, |
| scoped_ptr<std::string> key) { |
| return make_scoped_ptr(new Error(code, message, key.Pass())); |
| } |
| |
| // The error code. |
| const ErrorCode code; |
| |
| // Message associated with the error. |
| const std::string message; |
| |
| // The key associated with the error, if any. Use a scoped_ptr here |
| // because empty-string is a valid key. |
| // |
| // TODO(kalman): add test(s) for an empty key. |
| const scoped_ptr<std::string> key; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(Error); |
| }; |
| |
| // The result of a read operation (Get). |
| class ReadResultType { |
| public: |
| explicit ReadResultType(scoped_ptr<base::DictionaryValue> settings); |
| explicit ReadResultType(scoped_ptr<Error> error); |
| ~ReadResultType(); |
| |
| bool HasError() const { return error_; } |
| |
| bool IsCorrupted() const { |
| return error_.get() && error_->code == CORRUPTION; |
| } |
| |
| // Gets the settings read from the storage. Note that this represents |
| // the root object. If you request the value for key "foo", that value will |
| // be in |settings|.|foo|. |
| // |
| // Must only be called if there is no error. |
| base::DictionaryValue& settings() { return *settings_; } |
| scoped_ptr<base::DictionaryValue> PassSettings() { |
| return settings_.Pass(); |
| } |
| |
| // Only call if HasError is true. |
| const Error& error() const { return *error_; } |
| scoped_ptr<Error> PassError() { return error_.Pass(); } |
| |
| private: |
| scoped_ptr<base::DictionaryValue> settings_; |
| scoped_ptr<Error> error_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ReadResultType); |
| }; |
| typedef scoped_ptr<ReadResultType> ReadResult; |
| |
| // The result of a write operation (Set/Remove/Clear). |
| class WriteResultType { |
| public: |
| explicit WriteResultType(scoped_ptr<ValueStoreChangeList> changes); |
| explicit WriteResultType(scoped_ptr<Error> error); |
| ~WriteResultType(); |
| |
| bool HasError() const { return error_; } |
| |
| // Gets the list of changes to the settings which resulted from the write. |
| // Won't be present if the NO_GENERATE_CHANGES WriteOptions was given. |
| // Only call if HasError is false. |
| ValueStoreChangeList& changes() { return *changes_; } |
| scoped_ptr<ValueStoreChangeList> PassChanges() { return changes_.Pass(); } |
| |
| // Only call if HasError is true. |
| const Error& error() const { return *error_; } |
| scoped_ptr<Error> PassError() { return error_.Pass(); } |
| |
| private: |
| scoped_ptr<ValueStoreChangeList> changes_; |
| scoped_ptr<Error> error_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WriteResultType); |
| }; |
| typedef scoped_ptr<WriteResultType> WriteResult; |
| |
| // Options for write operations. |
| enum WriteOptionsValues { |
| // Callers should usually use this. |
| DEFAULTS = 0, |
| |
| // Ignore any quota restrictions. |
| IGNORE_QUOTA = 1<<1, |
| |
| // Don't generate the changes for a WriteResult. |
| NO_GENERATE_CHANGES = 1<<2, |
| }; |
| typedef int WriteOptions; |
| |
| virtual ~ValueStore() {} |
| |
| // Helpers for making a Read/WriteResult. |
| template<typename T> |
| static ReadResult MakeReadResult(scoped_ptr<T> arg) { |
| return ReadResult(new ReadResultType(arg.Pass())); |
| } |
| |
| template<typename T> |
| static WriteResult MakeWriteResult(scoped_ptr<T> arg) { |
| return WriteResult(new WriteResultType(arg.Pass())); |
| } |
| |
| // Gets the amount of space being used by a single value, in bytes. |
| // Note: The GetBytesInUse methods are only used by extension settings at the |
| // moment. If these become more generally useful, the |
| // SettingsStorageQuotaEnforcer and WeakUnlimitedSettingsStorage classes |
| // should be moved to the value_store directory. |
| virtual size_t GetBytesInUse(const std::string& key) = 0; |
| |
| // Gets the total amount of space being used by multiple values, in bytes. |
| virtual size_t GetBytesInUse(const std::vector<std::string>& keys) = 0; |
| |
| // Gets the total amount of space being used by this storage area, in bytes. |
| virtual size_t GetBytesInUse() = 0; |
| |
| // Gets a single value from storage. |
| virtual ReadResult Get(const std::string& key) = 0; |
| |
| // Gets multiple values from storage. |
| virtual ReadResult Get(const std::vector<std::string>& keys) = 0; |
| |
| // Gets all values from storage. |
| virtual ReadResult Get() = 0; |
| |
| // Sets a single key to a new value. |
| virtual WriteResult Set(WriteOptions options, |
| const std::string& key, |
| const base::Value& value) = 0; |
| |
| // Sets multiple keys to new values. |
| virtual WriteResult Set( |
| WriteOptions options, const base::DictionaryValue& values) = 0; |
| |
| // Removes a key from the storage. |
| virtual WriteResult Remove(const std::string& key) = 0; |
| |
| // Removes multiple keys from the storage. |
| virtual WriteResult Remove(const std::vector<std::string>& keys) = 0; |
| |
| // Clears the storage. |
| virtual WriteResult Clear() = 0; |
| |
| // In the event of corruption, the ValueStore should be able to restore |
| // itself. This means deleting local corrupted files. If only a few keys are |
| // corrupted, then some of the database may be saved. If the full database is |
| // corrupted, this will erase it in its entirety. |
| // Returns true on success, false on failure. The only way this will fail is |
| // if we also cannot delete the database file. |
| // Note: This method may be expensive; some implementations may need to read |
| // the entire database to restore. Use sparingly. |
| // Note: This method (and the following RestoreKey()) are rude, and do not |
| // make any logs, track changes, or other generally polite things. Please do |
| // not use these as substitutes for Clear() and Remove(). |
| virtual bool Restore() = 0; |
| |
| // Similar to Restore(), but for only a particular key. If the key is corrupt, |
| // this will forcefully remove the key. It does not look at the database on |
| // the whole, which makes it faster, but does not guarantee there is no |
| // additional corruption. |
| // Returns true on success, and false on failure. If false, the next step is |
| // probably to Restore() the whole database. |
| virtual bool RestoreKey(const std::string& key) = 0; |
| }; |
| |
| #endif // EXTENSIONS_BROWSER_VALUE_STORE_VALUE_STORE_H_ |