Home | History | Annotate | Download | only in value_store
      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