OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 5 #ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 6 #define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
7 | 7 |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
16 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
17 #include "base/timer/timer.h" | 17 #include "base/timer/timer.h" |
18 #include "content/browser/indexed_db/indexed_db.h" | 18 #include "content/browser/indexed_db/indexed_db.h" |
19 #include "content/browser/indexed_db/indexed_db_active_blob_registry.h" | 19 #include "content/browser/indexed_db/indexed_db_active_blob_registry.h" |
20 #include "content/browser/indexed_db/indexed_db_blob_info.h" | 20 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
| 21 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" |
21 #include "content/browser/indexed_db/indexed_db_metadata.h" | 22 #include "content/browser/indexed_db/indexed_db_metadata.h" |
22 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" | 23 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" |
23 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" | 24 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" |
24 #include "content/common/content_export.h" | 25 #include "content/common/content_export.h" |
25 #include "content/common/indexed_db/indexed_db_key.h" | 26 #include "content/common/indexed_db/indexed_db_key.h" |
26 #include "content/common/indexed_db/indexed_db_key_path.h" | 27 #include "content/common/indexed_db/indexed_db_key_path.h" |
27 #include "content/common/indexed_db/indexed_db_key_range.h" | 28 #include "content/common/indexed_db/indexed_db_key_range.h" |
28 #include "third_party/leveldatabase/src/include/leveldb/status.h" | 29 #include "third_party/leveldatabase/src/include/leveldb/status.h" |
29 #include "url/gurl.h" | 30 #include "url/gurl.h" |
30 #include "webkit/browser/blob/blob_data_handle.h" | 31 #include "webkit/browser/blob/blob_data_handle.h" |
31 | 32 |
32 namespace base { | 33 namespace base { |
33 class TaskRunner; | 34 class TaskRunner; |
34 } | 35 } |
35 | 36 |
| 37 namespace fileapi { |
| 38 class FileWriterDelegate; |
| 39 } |
| 40 |
| 41 namespace net { |
| 42 class URLRequestContext; |
| 43 } |
| 44 |
36 namespace content { | 45 namespace content { |
37 | 46 |
38 class IndexedDBFactory; | 47 class IndexedDBFactory; |
39 class LevelDBComparator; | 48 class LevelDBComparator; |
40 class LevelDBDatabase; | 49 class LevelDBDatabase; |
41 struct IndexedDBValue; | 50 struct IndexedDBValue; |
42 | 51 |
43 class LevelDBFactory { | 52 class LevelDBFactory { |
44 public: | 53 public: |
45 virtual ~LevelDBFactory() {} | 54 virtual ~LevelDBFactory() {} |
(...skipping 23 matching lines...) Expand all Loading... |
69 return &close_timer_; | 78 return &close_timer_; |
70 } | 79 } |
71 IndexedDBActiveBlobRegistry* active_blob_registry() { | 80 IndexedDBActiveBlobRegistry* active_blob_registry() { |
72 return &active_blob_registry_; | 81 return &active_blob_registry_; |
73 } | 82 } |
74 | 83 |
75 static scoped_refptr<IndexedDBBackingStore> Open( | 84 static scoped_refptr<IndexedDBBackingStore> Open( |
76 IndexedDBFactory* indexed_db_factory, | 85 IndexedDBFactory* indexed_db_factory, |
77 const GURL& origin_url, | 86 const GURL& origin_url, |
78 const base::FilePath& path_base, | 87 const base::FilePath& path_base, |
| 88 net::URLRequestContext* request_context, |
79 blink::WebIDBDataLoss* data_loss, | 89 blink::WebIDBDataLoss* data_loss, |
80 std::string* data_loss_message, | 90 std::string* data_loss_message, |
81 bool* disk_full, | 91 bool* disk_full, |
82 base::TaskRunner* task_runner); | 92 base::TaskRunner* task_runner); |
83 | 93 |
84 static scoped_refptr<IndexedDBBackingStore> Open( | 94 static scoped_refptr<IndexedDBBackingStore> Open( |
85 IndexedDBFactory* indexed_db_factory, | 95 IndexedDBFactory* indexed_db_factory, |
86 const GURL& origin_url, | 96 const GURL& origin_url, |
87 const base::FilePath& path_base, | 97 const base::FilePath& path_base, |
| 98 net::URLRequestContext* request_context, |
88 blink::WebIDBDataLoss* data_loss, | 99 blink::WebIDBDataLoss* data_loss, |
89 std::string* data_loss_message, | 100 std::string* data_loss_message, |
90 bool* disk_full, | 101 bool* disk_full, |
91 LevelDBFactory* leveldb_factory, | 102 LevelDBFactory* leveldb_factory, |
92 base::TaskRunner* task_runner); | 103 base::TaskRunner* task_runner); |
93 static scoped_refptr<IndexedDBBackingStore> OpenInMemory( | 104 static scoped_refptr<IndexedDBBackingStore> OpenInMemory( |
94 const GURL& origin_url, | 105 const GURL& origin_url, |
95 base::TaskRunner* task_runner); | 106 base::TaskRunner* task_runner); |
96 static scoped_refptr<IndexedDBBackingStore> OpenInMemory( | 107 static scoped_refptr<IndexedDBBackingStore> OpenInMemory( |
97 const GURL& origin_url, | 108 const GURL& origin_url, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 164 } |
154 | 165 |
155 private: | 166 private: |
156 // TODO(jsbell): Make it more clear that this is the *encoded* version of | 167 // TODO(jsbell): Make it more clear that this is the *encoded* version of |
157 // the key. | 168 // the key. |
158 std::string primary_key_; | 169 std::string primary_key_; |
159 int64 version_; | 170 int64 version_; |
160 DISALLOW_COPY_AND_ASSIGN(RecordIdentifier); | 171 DISALLOW_COPY_AND_ASSIGN(RecordIdentifier); |
161 }; | 172 }; |
162 | 173 |
| 174 class BlobWriteCallback : public base::RefCounted<BlobWriteCallback> { |
| 175 public: |
| 176 virtual void Run(bool succeeded) = 0; |
| 177 protected: |
| 178 virtual ~BlobWriteCallback() {} |
| 179 friend class base::RefCounted<BlobWriteCallback>; |
| 180 }; |
| 181 |
163 virtual leveldb::Status GetRecord( | 182 virtual leveldb::Status GetRecord( |
164 IndexedDBBackingStore::Transaction* transaction, | 183 IndexedDBBackingStore::Transaction* transaction, |
165 int64 database_id, | 184 int64 database_id, |
166 int64 object_store_id, | 185 int64 object_store_id, |
167 const IndexedDBKey& key, | 186 const IndexedDBKey& key, |
168 IndexedDBValue* record) WARN_UNUSED_RESULT; | 187 IndexedDBValue* record) WARN_UNUSED_RESULT; |
169 virtual leveldb::Status PutRecord( | 188 virtual leveldb::Status PutRecord( |
170 IndexedDBBackingStore::Transaction* transaction, | 189 IndexedDBBackingStore::Transaction* transaction, |
171 int64 database_id, | 190 int64 database_id, |
172 int64 object_store_id, | 191 int64 object_store_id, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 int64 database_id, | 254 int64 database_id, |
236 int64 object_store_id, | 255 int64 object_store_id, |
237 int64 index_id, | 256 int64 index_id, |
238 const IndexedDBKey& key, | 257 const IndexedDBKey& key, |
239 scoped_ptr<IndexedDBKey>* found_primary_key, | 258 scoped_ptr<IndexedDBKey>* found_primary_key, |
240 bool* exists) WARN_UNUSED_RESULT; | 259 bool* exists) WARN_UNUSED_RESULT; |
241 | 260 |
242 // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef. | 261 // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef. |
243 virtual void ReportBlobUnused(int64 database_id, int64 blob_key); | 262 virtual void ReportBlobUnused(int64 database_id, int64 blob_key); |
244 | 263 |
| 264 base::FilePath GetBlobFileName(int64 database_id, int64 key); |
| 265 |
245 class Cursor { | 266 class Cursor { |
246 public: | 267 public: |
247 virtual ~Cursor(); | 268 virtual ~Cursor(); |
248 | 269 |
249 enum IteratorState { | 270 enum IteratorState { |
250 READY = 0, | 271 READY = 0, |
251 SEEK | 272 SEEK |
252 }; | 273 }; |
253 | 274 |
254 struct CursorOptions { | 275 struct CursorOptions { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 transaction_ = NULL; | 368 transaction_ = NULL; |
348 } | 369 } |
349 void PutBlobInfo(int64 database_id, | 370 void PutBlobInfo(int64 database_id, |
350 int64 object_store_id, | 371 int64 object_store_id, |
351 const std::string& key, | 372 const std::string& key, |
352 std::vector<IndexedDBBlobInfo>*, | 373 std::vector<IndexedDBBlobInfo>*, |
353 ScopedVector<webkit_blob::BlobDataHandle>* handles); | 374 ScopedVector<webkit_blob::BlobDataHandle>* handles); |
354 | 375 |
355 LevelDBTransaction* transaction() { return transaction_; } | 376 LevelDBTransaction* transaction() { return transaction_; } |
356 | 377 |
| 378 // This holds a BlobEntryKey and the encoded IndexedDBBlobInfo vector stored |
| 379 // under that key. |
| 380 typedef std::vector<std::pair<BlobEntryKey, std::string> > |
| 381 BlobEntryKeyValuePairVec; |
| 382 |
| 383 class WriteDescriptor { |
| 384 public: |
| 385 WriteDescriptor(const GURL& url, int64_t key); |
| 386 WriteDescriptor(const base::FilePath& path, int64_t key); |
| 387 |
| 388 bool is_file() const { return is_file_; } |
| 389 const GURL& url() const { |
| 390 DCHECK(!is_file_); |
| 391 return url_; |
| 392 } |
| 393 const base::FilePath& file_path() const { |
| 394 DCHECK(is_file_); |
| 395 return file_path_; |
| 396 } |
| 397 int64_t key() const { return key_; } |
| 398 |
| 399 private: |
| 400 bool is_file_; |
| 401 GURL url_; |
| 402 base::FilePath file_path_; |
| 403 int64_t key_; |
| 404 }; |
| 405 |
| 406 class ChainedBlobWriter : public base::RefCounted<ChainedBlobWriter> { |
| 407 public: |
| 408 virtual void set_delegate( |
| 409 scoped_ptr<fileapi::FileWriterDelegate> delegate) = 0; |
| 410 |
| 411 // TODO(ericu): Add a reason in the event of failure. |
| 412 virtual void ReportWriteCompletion(bool succeeded, |
| 413 int64 bytes_written) = 0; |
| 414 |
| 415 virtual void Abort() = 0; |
| 416 |
| 417 protected: |
| 418 virtual ~ChainedBlobWriter() {} |
| 419 friend class base::RefCounted<ChainedBlobWriter>; |
| 420 }; |
| 421 class ChainedBlobWriterImpl; |
| 422 |
| 423 typedef std::vector<WriteDescriptor> WriteDescriptorVec; |
| 424 |
357 private: | 425 private: |
358 class BlobChangeRecord { | 426 class BlobChangeRecord { |
359 public: | 427 public: |
360 BlobChangeRecord(const std::string& key, int64 object_store_id); | 428 BlobChangeRecord(const std::string& key, int64 object_store_id); |
361 ~BlobChangeRecord(); | 429 ~BlobChangeRecord(); |
362 const std::string& key() const { return key_; } | 430 const std::string& key() const { return key_; } |
363 int64 object_store_id() const { return object_store_id_; } | 431 int64 object_store_id() const { return object_store_id_; } |
364 void SetBlobInfo(std::vector<IndexedDBBlobInfo>* blob_info); | 432 void SetBlobInfo(std::vector<IndexedDBBlobInfo>* blob_info); |
365 std::vector<IndexedDBBlobInfo>& mutable_blob_info() { return blob_info_; } | 433 std::vector<IndexedDBBlobInfo>& mutable_blob_info() { return blob_info_; } |
366 void SetHandles(ScopedVector<webkit_blob::BlobDataHandle>* handles); | 434 void SetHandles(ScopedVector<webkit_blob::BlobDataHandle>* handles); |
367 | 435 |
368 private: | 436 private: |
369 std::string key_; | 437 std::string key_; |
370 int64 object_store_id_; | 438 int64 object_store_id_; |
371 std::vector<IndexedDBBlobInfo> blob_info_; | 439 std::vector<IndexedDBBlobInfo> blob_info_; |
372 ScopedVector<webkit_blob::BlobDataHandle> handles_; | 440 ScopedVector<webkit_blob::BlobDataHandle> handles_; |
373 }; | 441 }; |
| 442 class BlobWriteCallbackWrapper; |
374 typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap; | 443 typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap; |
375 | 444 |
| 445 // The callback will be called eventually on success or failure. |
| 446 void WriteNewBlobs(BlobEntryKeyValuePairVec& new_blob_entries, |
| 447 WriteDescriptorVec& new_files_to_write, |
| 448 scoped_refptr<BlobWriteCallback> callback); |
| 449 |
376 IndexedDBBackingStore* backing_store_; | 450 IndexedDBBackingStore* backing_store_; |
377 scoped_refptr<LevelDBTransaction> transaction_; | 451 scoped_refptr<LevelDBTransaction> transaction_; |
378 BlobChangeMap blob_change_map_; | 452 BlobChangeMap blob_change_map_; |
379 int64 database_id_; | 453 int64 database_id_; |
| 454 scoped_refptr<ChainedBlobWriter> chained_blob_writer_; |
380 }; | 455 }; |
381 | 456 |
382 protected: | 457 protected: |
383 IndexedDBBackingStore(IndexedDBFactory* indexed_db_factory, | 458 IndexedDBBackingStore(IndexedDBFactory* indexed_db_factory, |
384 const GURL& origin_url, | 459 const GURL& origin_url, |
385 const base::FilePath& blob_path, | 460 const base::FilePath& blob_path, |
| 461 net::URLRequestContext* request_context, |
386 scoped_ptr<LevelDBDatabase> db, | 462 scoped_ptr<LevelDBDatabase> db, |
387 scoped_ptr<LevelDBComparator> comparator, | 463 scoped_ptr<LevelDBComparator> comparator, |
388 base::TaskRunner* task_runner); | 464 base::TaskRunner* task_runner); |
389 virtual ~IndexedDBBackingStore(); | 465 virtual ~IndexedDBBackingStore(); |
390 friend class base::RefCounted<IndexedDBBackingStore>; | 466 friend class base::RefCounted<IndexedDBBackingStore>; |
391 | 467 |
| 468 virtual bool WriteBlobFile( |
| 469 int64 database_id, |
| 470 const Transaction::WriteDescriptor& descriptor, |
| 471 Transaction::ChainedBlobWriter* chained_blob_writer); |
| 472 virtual bool RemoveBlobFile(int64 database_id, int64 key); |
| 473 |
392 private: | 474 private: |
393 static scoped_refptr<IndexedDBBackingStore> Create( | 475 static scoped_refptr<IndexedDBBackingStore> Create( |
394 IndexedDBFactory* indexed_db_factory, | 476 IndexedDBFactory* indexed_db_factory, |
395 const GURL& origin_url, | 477 const GURL& origin_url, |
396 const base::FilePath& blob_path, | 478 const base::FilePath& blob_path, |
| 479 net::URLRequestContext* request_context, |
397 scoped_ptr<LevelDBDatabase> db, | 480 scoped_ptr<LevelDBDatabase> db, |
398 scoped_ptr<LevelDBComparator> comparator, | 481 scoped_ptr<LevelDBComparator> comparator, |
399 base::TaskRunner* task_runner); | 482 base::TaskRunner* task_runner); |
400 | 483 |
401 static bool ReadCorruptionInfo(const base::FilePath& path_base, | 484 static bool ReadCorruptionInfo(const base::FilePath& path_base, |
402 const GURL& origin_url, | 485 const GURL& origin_url, |
403 std::string& message); | 486 std::string& message); |
404 | 487 |
405 leveldb::Status FindKeyInIndex( | 488 leveldb::Status FindKeyInIndex( |
406 IndexedDBBackingStore::Transaction* transaction, | 489 IndexedDBBackingStore::Transaction* transaction, |
407 int64 database_id, | 490 int64 database_id, |
408 int64 object_store_id, | 491 int64 object_store_id, |
409 int64 index_id, | 492 int64 index_id, |
410 const IndexedDBKey& key, | 493 const IndexedDBKey& key, |
411 std::string* found_encoded_primary_key, | 494 std::string* found_encoded_primary_key, |
412 bool* found); | 495 bool* found); |
413 leveldb::Status GetIndexes(int64 database_id, | 496 leveldb::Status GetIndexes(int64 database_id, |
414 int64 object_store_id, | 497 int64 object_store_id, |
415 IndexedDBObjectStoreMetadata::IndexMap* map) | 498 IndexedDBObjectStoreMetadata::IndexMap* map) |
416 WARN_UNUSED_RESULT; | 499 WARN_UNUSED_RESULT; |
| 500 bool RemoveBlobDirectory(int64 database_id); |
417 | 501 |
418 IndexedDBFactory* indexed_db_factory_; | 502 IndexedDBFactory* indexed_db_factory_; |
419 const GURL origin_url_; | 503 const GURL origin_url_; |
420 base::FilePath blob_path_; | 504 base::FilePath blob_path_; |
421 | 505 |
422 // The origin identifier is a key prefix unique to the origin used in the | 506 // The origin identifier is a key prefix unique to the origin used in the |
423 // leveldb backing store to partition data by origin. It is a normalized | 507 // leveldb backing store to partition data by origin. It is a normalized |
424 // version of the origin URL with a versioning suffix appended, e.g. | 508 // version of the origin URL with a versioning suffix appended, e.g. |
425 // "http_localhost_81@1" Since only one origin is stored per backing store | 509 // "http_localhost_81@1" Since only one origin is stored per backing store |
426 // this is redundant but necessary for backwards compatibility; the suffix | 510 // this is redundant but necessary for backwards compatibility; the suffix |
427 // provides for future flexibility. | 511 // provides for future flexibility. |
428 const std::string origin_identifier_; | 512 const std::string origin_identifier_; |
| 513 |
| 514 net::URLRequestContext* request_context_; |
429 base::TaskRunner* task_runner_; | 515 base::TaskRunner* task_runner_; |
430 std::set<int> child_process_ids_granted_; | 516 std::set<int> child_process_ids_granted_; |
431 | 517 |
432 scoped_ptr<LevelDBDatabase> db_; | 518 scoped_ptr<LevelDBDatabase> db_; |
433 scoped_ptr<LevelDBComparator> comparator_; | 519 scoped_ptr<LevelDBComparator> comparator_; |
434 // Whenever blobs are registered in active_blob_registry_, indexed_db_factory_ | 520 // Whenever blobs are registered in active_blob_registry_, indexed_db_factory_ |
435 // will hold a reference to this backing store. | 521 // will hold a reference to this backing store. |
436 IndexedDBActiveBlobRegistry active_blob_registry_; | 522 IndexedDBActiveBlobRegistry active_blob_registry_; |
437 base::OneShotTimer<IndexedDBBackingStore> close_timer_; | 523 base::OneShotTimer<IndexedDBBackingStore> close_timer_; |
438 }; | 524 }; |
439 | 525 |
440 } // namespace content | 526 } // namespace content |
441 | 527 |
442 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 528 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
OLD | NEW |