Home | History | Annotate | Download | only in indexed_db
      1 // Copyright (c) 2013 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 CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
      6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/files/file_path.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "content/browser/indexed_db/indexed_db.h"
     17 #include "content/browser/indexed_db/indexed_db_metadata.h"
     18 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
     19 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
     20 #include "content/common/content_export.h"
     21 #include "content/common/indexed_db/indexed_db_key.h"
     22 #include "content/common/indexed_db/indexed_db_key_path.h"
     23 #include "content/common/indexed_db/indexed_db_key_range.h"
     24 #include "third_party/WebKit/public/platform/WebIDBCallbacks.h"
     25 
     26 namespace content {
     27 
     28 class LevelDBComparator;
     29 class LevelDBDatabase;
     30 
     31 class LevelDBFactory {
     32  public:
     33   virtual ~LevelDBFactory() {}
     34   virtual leveldb::Status OpenLevelDB(
     35       const base::FilePath& file_name,
     36       const LevelDBComparator* comparator,
     37       scoped_ptr<LevelDBDatabase>* db,
     38       bool* is_disk_full) = 0;
     39   virtual bool DestroyLevelDB(const base::FilePath& file_name) = 0;
     40 };
     41 
     42 class CONTENT_EXPORT IndexedDBBackingStore
     43     : public base::RefCounted<IndexedDBBackingStore> {
     44  public:
     45   class CONTENT_EXPORT Transaction;
     46 
     47   static scoped_refptr<IndexedDBBackingStore> Open(
     48       const std::string& origin_identifier,
     49       const base::FilePath& path_base,
     50       const std::string& file_identifier,
     51       WebKit::WebIDBCallbacks::DataLoss* data_loss);
     52 
     53   static scoped_refptr<IndexedDBBackingStore> Open(
     54       const std::string& origin_identifier,
     55       const base::FilePath& path_base,
     56       const std::string& file_identifier,
     57       WebKit::WebIDBCallbacks::DataLoss* data_loss,
     58       LevelDBFactory* factory);
     59   static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
     60       const std::string& file_identifier);
     61   static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
     62       const std::string& file_identifier,
     63       LevelDBFactory* factory);
     64   base::WeakPtr<IndexedDBBackingStore> GetWeakPtr() {
     65     return weak_factory_.GetWeakPtr();
     66   }
     67 
     68   virtual std::vector<string16> GetDatabaseNames();
     69   virtual bool GetIDBDatabaseMetaData(const string16& name,
     70                                       IndexedDBDatabaseMetadata* metadata,
     71                                       bool* success) WARN_UNUSED_RESULT;
     72   virtual bool CreateIDBDatabaseMetaData(const string16& name,
     73                                          const string16& version,
     74                                          int64 int_version,
     75                                          int64* row_id);
     76   virtual bool UpdateIDBDatabaseMetaData(
     77       IndexedDBBackingStore::Transaction* transaction,
     78       int64 row_id,
     79       const string16& version);
     80   virtual bool UpdateIDBDatabaseIntVersion(
     81       IndexedDBBackingStore::Transaction* transaction,
     82       int64 row_id,
     83       int64 int_version);
     84   virtual bool DeleteDatabase(const string16& name);
     85 
     86   bool GetObjectStores(int64 database_id,
     87                        IndexedDBDatabaseMetadata::ObjectStoreMap* map)
     88       WARN_UNUSED_RESULT;
     89   virtual bool CreateObjectStore(
     90       IndexedDBBackingStore::Transaction* transaction,
     91       int64 database_id,
     92       int64 object_store_id,
     93       const string16& name,
     94       const IndexedDBKeyPath& key_path,
     95       bool auto_increment);
     96   virtual bool DeleteObjectStore(
     97       IndexedDBBackingStore::Transaction* transaction,
     98       int64 database_id,
     99       int64 object_store_id) WARN_UNUSED_RESULT;
    100 
    101   class CONTENT_EXPORT RecordIdentifier {
    102    public:
    103     RecordIdentifier(const std::string& primary_key, int64 version);
    104     RecordIdentifier();
    105     ~RecordIdentifier();
    106 
    107     const std::string& primary_key() const { return primary_key_; }
    108     int64 version() const { return version_; }
    109     void Reset(const std::string& primary_key, int64 version) {
    110       primary_key_ = primary_key;
    111       version_ = version;
    112     }
    113 
    114    private:
    115     // TODO(jsbell): Make it more clear that this is the *encoded* version of
    116     // the key.
    117     std::string primary_key_;
    118     int64 version_;
    119     DISALLOW_COPY_AND_ASSIGN(RecordIdentifier);
    120   };
    121 
    122   virtual bool GetRecord(IndexedDBBackingStore::Transaction* transaction,
    123                          int64 database_id,
    124                          int64 object_store_id,
    125                          const IndexedDBKey& key,
    126                          std::string* record) WARN_UNUSED_RESULT;
    127   virtual bool PutRecord(IndexedDBBackingStore::Transaction* transaction,
    128                          int64 database_id,
    129                          int64 object_store_id,
    130                          const IndexedDBKey& key,
    131                          const std::string& value,
    132                          RecordIdentifier* record) WARN_UNUSED_RESULT;
    133   virtual bool ClearObjectStore(IndexedDBBackingStore::Transaction* transaction,
    134                                 int64 database_id,
    135                                 int64 object_store_id) WARN_UNUSED_RESULT;
    136   virtual bool DeleteRecord(IndexedDBBackingStore::Transaction* transaction,
    137                             int64 database_id,
    138                             int64 object_store_id,
    139                             const RecordIdentifier& record) WARN_UNUSED_RESULT;
    140   virtual bool GetKeyGeneratorCurrentNumber(
    141       IndexedDBBackingStore::Transaction* transaction,
    142       int64 database_id,
    143       int64 object_store_id,
    144       int64* current_number) WARN_UNUSED_RESULT;
    145   virtual bool MaybeUpdateKeyGeneratorCurrentNumber(
    146       IndexedDBBackingStore::Transaction* transaction,
    147       int64 database_id,
    148       int64 object_store_id,
    149       int64 new_state,
    150       bool check_current) WARN_UNUSED_RESULT;
    151   virtual bool KeyExistsInObjectStore(
    152       IndexedDBBackingStore::Transaction* transaction,
    153       int64 database_id,
    154       int64 object_store_id,
    155       const IndexedDBKey& key,
    156       RecordIdentifier* found_record_identifier,
    157       bool* found) WARN_UNUSED_RESULT;
    158 
    159   virtual bool CreateIndex(IndexedDBBackingStore::Transaction* transaction,
    160                            int64 database_id,
    161                            int64 object_store_id,
    162                            int64 index_id,
    163                            const string16& name,
    164                            const IndexedDBKeyPath& key_path,
    165                            bool is_unique,
    166                            bool is_multi_entry) WARN_UNUSED_RESULT;
    167   virtual bool DeleteIndex(IndexedDBBackingStore::Transaction* transaction,
    168                            int64 database_id,
    169                            int64 object_store_id,
    170                            int64 index_id) WARN_UNUSED_RESULT;
    171   virtual bool PutIndexDataForRecord(
    172       IndexedDBBackingStore::Transaction* transaction,
    173       int64 database_id,
    174       int64 object_store_id,
    175       int64 index_id,
    176       const IndexedDBKey& key,
    177       const RecordIdentifier& record) WARN_UNUSED_RESULT;
    178   virtual bool GetPrimaryKeyViaIndex(
    179       IndexedDBBackingStore::Transaction* transaction,
    180       int64 database_id,
    181       int64 object_store_id,
    182       int64 index_id,
    183       const IndexedDBKey& key,
    184       scoped_ptr<IndexedDBKey>* primary_key) WARN_UNUSED_RESULT;
    185   virtual bool KeyExistsInIndex(IndexedDBBackingStore::Transaction* transaction,
    186                                 int64 database_id,
    187                                 int64 object_store_id,
    188                                 int64 index_id,
    189                                 const IndexedDBKey& key,
    190                                 scoped_ptr<IndexedDBKey>* found_primary_key,
    191                                 bool* exists) WARN_UNUSED_RESULT;
    192 
    193   class Cursor {
    194    public:
    195     virtual ~Cursor();
    196 
    197     enum IteratorState {
    198       READY = 0,
    199       SEEK
    200     };
    201 
    202     struct CursorOptions {
    203       CursorOptions();
    204       ~CursorOptions();
    205       int64 database_id;
    206       int64 object_store_id;
    207       int64 index_id;
    208       std::string low_key;
    209       bool low_open;
    210       std::string high_key;
    211       bool high_open;
    212       bool forward;
    213       bool unique;
    214     };
    215 
    216     const IndexedDBKey& key() const { return *current_key_; }
    217     bool Continue() { return Continue(NULL, SEEK); }
    218     bool Continue(const IndexedDBKey* key, IteratorState state);
    219     bool Advance(uint32 count);
    220     bool FirstSeek();
    221 
    222     virtual Cursor* Clone() = 0;
    223     virtual const IndexedDBKey& primary_key() const;
    224     virtual std::string* Value() = 0;
    225     virtual const RecordIdentifier& record_identifier() const;
    226     virtual bool LoadCurrentRow() = 0;
    227 
    228    protected:
    229     Cursor(LevelDBTransaction* transaction,
    230            const CursorOptions& cursor_options);
    231     explicit Cursor(const IndexedDBBackingStore::Cursor* other);
    232 
    233     virtual std::string EncodeKey(const IndexedDBKey& key) = 0;
    234 
    235     bool IsPastBounds() const;
    236     bool HaveEnteredRange() const;
    237 
    238     LevelDBTransaction* transaction_;
    239     const CursorOptions cursor_options_;
    240     scoped_ptr<LevelDBIterator> iterator_;
    241     scoped_ptr<IndexedDBKey> current_key_;
    242     IndexedDBBackingStore::RecordIdentifier record_identifier_;
    243   };
    244 
    245   virtual scoped_ptr<Cursor> OpenObjectStoreKeyCursor(
    246       IndexedDBBackingStore::Transaction* transaction,
    247       int64 database_id,
    248       int64 object_store_id,
    249       const IndexedDBKeyRange& key_range,
    250       indexed_db::CursorDirection);
    251   virtual scoped_ptr<Cursor> OpenObjectStoreCursor(
    252       IndexedDBBackingStore::Transaction* transaction,
    253       int64 database_id,
    254       int64 object_store_id,
    255       const IndexedDBKeyRange& key_range,
    256       indexed_db::CursorDirection);
    257   virtual scoped_ptr<Cursor> OpenIndexKeyCursor(
    258       IndexedDBBackingStore::Transaction* transaction,
    259       int64 database_id,
    260       int64 object_store_id,
    261       int64 index_id,
    262       const IndexedDBKeyRange& key_range,
    263       indexed_db::CursorDirection);
    264   virtual scoped_ptr<Cursor> OpenIndexCursor(
    265       IndexedDBBackingStore::Transaction* transaction,
    266       int64 database_id,
    267       int64 object_store_id,
    268       int64 index_id,
    269       const IndexedDBKeyRange& key_range,
    270       indexed_db::CursorDirection);
    271 
    272   class Transaction {
    273    public:
    274     explicit Transaction(IndexedDBBackingStore* backing_store);
    275     ~Transaction();
    276     void Begin();
    277     bool Commit();
    278     void Rollback();
    279     void Reset() {
    280       backing_store_ = NULL;
    281       transaction_ = NULL;
    282     }
    283 
    284     static LevelDBTransaction* LevelDBTransactionFrom(
    285         Transaction* transaction) {
    286       return transaction->transaction_;
    287     }
    288 
    289    private:
    290     IndexedDBBackingStore* backing_store_;
    291     scoped_refptr<LevelDBTransaction> transaction_;
    292   };
    293 
    294  protected:
    295   IndexedDBBackingStore(const std::string& identifier,
    296                         scoped_ptr<LevelDBDatabase> db,
    297                         scoped_ptr<LevelDBComparator> comparator);
    298   virtual ~IndexedDBBackingStore();
    299   friend class base::RefCounted<IndexedDBBackingStore>;
    300 
    301  private:
    302   static scoped_refptr<IndexedDBBackingStore> Create(
    303       const std::string& identifier,
    304       scoped_ptr<LevelDBDatabase> db,
    305       scoped_ptr<LevelDBComparator> comparator);
    306 
    307   bool FindKeyInIndex(IndexedDBBackingStore::Transaction* transaction,
    308                       int64 database_id,
    309                       int64 object_store_id,
    310                       int64 index_id,
    311                       const IndexedDBKey& key,
    312                       std::string* found_encoded_primary_key,
    313                       bool* found);
    314   bool GetIndexes(int64 database_id,
    315                   int64 object_store_id,
    316                   IndexedDBObjectStoreMetadata::IndexMap* map)
    317       WARN_UNUSED_RESULT;
    318 
    319   std::string identifier_;
    320 
    321   scoped_ptr<LevelDBDatabase> db_;
    322   scoped_ptr<LevelDBComparator> comparator_;
    323   base::WeakPtrFactory<IndexedDBBackingStore> weak_factory_;
    324 };
    325 
    326 }  // namespace content
    327 
    328 #endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
    329