15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_VALUE_STORE_VALUE_STORE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_VALUE_STORE_VALUE_STORE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/value_store/value_store_change.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Interface for a storage area for Value objects.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ValueStore {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Error codes returned from storage methods.
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  enum ErrorCode {
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    OK,
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The failure was due to some kind of database corruption. Depending on
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // what is corrupted, some part of the database may be recoverable.
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    //
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // For example, if the on-disk representation of leveldb is corrupted, it's
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // likely the whole database will need to be wiped and started again.
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    //
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // If a single key has been committed with an invalid JSON representation,
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // just that key can be deleted without affecting the rest of the database.
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    CORRUPTION,
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The failure was due to the store being read-only (for example, policy).
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    READ_ONLY,
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The failure was due to the store running out of space.
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    QUOTA_EXCEEDED,
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Any other error.
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    OTHER_ERROR,
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Bundles an ErrorCode with further metadata.
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  struct Error {
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Error(ErrorCode code,
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          const std::string& message,
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          scoped_ptr<std::string> key);
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ~Error();
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    static scoped_ptr<Error> Create(ErrorCode code,
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                    const std::string& message,
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                    scoped_ptr<std::string> key) {
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return make_scoped_ptr(new Error(code, message, key.Pass()));
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The error code.
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const ErrorCode code;
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Message associated with the error.
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string message;
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The key associated with the error, if any. Use a scoped_ptr here
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // because empty-string is a valid key.
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    //
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(kalman): add test(s) for an empty key.
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const scoped_ptr<std::string> key;
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)   private:
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(Error);
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result of a read operation (Get).
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ReadResultType {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    explicit ReadResultType(scoped_ptr<base::DictionaryValue> settings);
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    explicit ReadResultType(scoped_ptr<Error> error);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~ReadResultType();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool HasError() const { return error_; }
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Gets the settings read from the storage. Note that this represents
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the root object. If you request the value for key "foo", that value will
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // be in |settings|.|foo|.
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    //
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Must only be called if there is no error.
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::DictionaryValue& settings() { return *settings_; }
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> PassSettings() {
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return settings_.Pass();
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Only call if HasError is true.
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const Error& error() const { return *error_; }
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<Error> PassError() { return error_.Pass(); }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    scoped_ptr<base::DictionaryValue> settings_;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<Error> error_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(ReadResultType);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef scoped_ptr<ReadResultType> ReadResult;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result of a write operation (Set/Remove/Clear).
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class WriteResultType {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    explicit WriteResultType(scoped_ptr<ValueStoreChangeList> changes);
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    explicit WriteResultType(scoped_ptr<Error> error);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~WriteResultType();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool HasError() const { return error_; }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Gets the list of changes to the settings which resulted from the write.
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Won't be present if the NO_GENERATE_CHANGES WriteOptions was given.
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Only call if HasError is false.
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ValueStoreChangeList& changes() { return *changes_; }
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<ValueStoreChangeList> PassChanges() { return changes_.Pass(); }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Only call if HasError is true.
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const Error& error() const { return *error_; }
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<Error> PassError() { return error_.Pass(); }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<ValueStoreChangeList> changes_;
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<Error> error_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(WriteResultType);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef scoped_ptr<WriteResultType> WriteResult;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Options for write operations.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum WriteOptionsValues {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Callers should usually use this.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DEFAULTS = 0,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ignore any quota restrictions.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IGNORE_QUOTA = 1<<1,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't generate the changes for a WriteResult.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NO_GENERATE_CHANGES = 1<<2,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef int WriteOptions;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ValueStore() {}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helpers for making a Read/WriteResult.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T>
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static ReadResult MakeReadResult(scoped_ptr<T> arg) {
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return ReadResult(new ReadResultType(arg.Pass()));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename T>
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static WriteResult MakeWriteResult(scoped_ptr<T> arg) {
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return WriteResult(new WriteResultType(arg.Pass()));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the amount of space being used by a single value, in bytes.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: The GetBytesInUse methods are only used by extension settings at the
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // moment. If these become more generally useful, the
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SettingsStorageQuotaEnforcer and WeakUnlimitedSettingsStorage classes
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be moved to the value_store directory.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual size_t GetBytesInUse(const std::string& key) = 0;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the total amount of space being used by multiple values, in bytes.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual size_t GetBytesInUse(const std::vector<std::string>& keys) = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the total amount of space being used by this storage area, in bytes.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual size_t GetBytesInUse() = 0;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets a single value from storage.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ReadResult Get(const std::string& key) = 0;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets multiple values from storage.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ReadResult Get(const std::vector<std::string>& keys) = 0;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets all values from storage.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ReadResult Get() = 0;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets a single key to a new value.
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual WriteResult Set(WriteOptions options,
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          const std::string& key,
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          const base::Value& value) = 0;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets multiple keys to new values.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WriteResult Set(
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WriteOptions options, const base::DictionaryValue& values) = 0;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes a key from the storage.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WriteResult Remove(const std::string& key) = 0;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes multiple keys from the storage.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WriteResult Remove(const std::vector<std::string>& keys) = 0;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clears the storage.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WriteResult Clear() = 0;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_VALUE_STORE_VALUE_STORE_H_
197