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