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