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 RefCounted<BlobWriteCallback> { |
| 175 public: |
| 176 virtual ~BlobWriteCallback() {} |
| 177 virtual void Run(bool succeeded) = 0; |
| 178 }; |
| 179 |
163 virtual leveldb::Status GetRecord( | 180 virtual leveldb::Status GetRecord( |
164 IndexedDBBackingStore::Transaction* transaction, | 181 IndexedDBBackingStore::Transaction* transaction, |
165 int64 database_id, | 182 int64 database_id, |
166 int64 object_store_id, | 183 int64 object_store_id, |
167 const IndexedDBKey& key, | 184 const IndexedDBKey& key, |
168 IndexedDBValue* record) WARN_UNUSED_RESULT; | 185 IndexedDBValue* record) WARN_UNUSED_RESULT; |
169 virtual leveldb::Status PutRecord( | 186 virtual leveldb::Status PutRecord( |
170 IndexedDBBackingStore::Transaction* transaction, | 187 IndexedDBBackingStore::Transaction* transaction, |
171 int64 database_id, | 188 int64 database_id, |
172 int64 object_store_id, | 189 int64 object_store_id, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 int64 database_id, | 252 int64 database_id, |
236 int64 object_store_id, | 253 int64 object_store_id, |
237 int64 index_id, | 254 int64 index_id, |
238 const IndexedDBKey& key, | 255 const IndexedDBKey& key, |
239 scoped_ptr<IndexedDBKey>* found_primary_key, | 256 scoped_ptr<IndexedDBKey>* found_primary_key, |
240 bool* exists) WARN_UNUSED_RESULT; | 257 bool* exists) WARN_UNUSED_RESULT; |
241 | 258 |
242 // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef. | 259 // Public for IndexedDBActiveBlobRegistry::ReleaseBlobRef. |
243 virtual void ReportBlobUnused(int64 database_id, int64 blob_key); | 260 virtual void ReportBlobUnused(int64 database_id, int64 blob_key); |
244 | 261 |
| 262 base::FilePath GetBlobFileName(int64 database_id, int64 key); |
| 263 |
245 class Cursor { | 264 class Cursor { |
246 public: | 265 public: |
247 virtual ~Cursor(); | 266 virtual ~Cursor(); |
248 | 267 |
249 enum IteratorState { | 268 enum IteratorState { |
250 READY = 0, | 269 READY = 0, |
251 SEEK | 270 SEEK |
252 }; | 271 }; |
253 | 272 |
254 struct CursorOptions { | 273 struct CursorOptions { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 transaction_ = NULL; | 366 transaction_ = NULL; |
348 } | 367 } |
349 void PutBlobInfo(int64 database_id, | 368 void PutBlobInfo(int64 database_id, |
350 int64 object_store_id, | 369 int64 object_store_id, |
351 const std::string& key, | 370 const std::string& key, |
352 std::vector<IndexedDBBlobInfo>*, | 371 std::vector<IndexedDBBlobInfo>*, |
353 ScopedVector<webkit_blob::BlobDataHandle>* handles); | 372 ScopedVector<webkit_blob::BlobDataHandle>* handles); |
354 | 373 |
355 LevelDBTransaction* transaction() { return transaction_; } | 374 LevelDBTransaction* transaction() { return transaction_; } |
356 | 375 |
| 376 // This holds a BlobEntryKey and the encoded IndexedDBBlobInfo vector stored |
| 377 // under that key. |
| 378 typedef std::vector<std::pair<BlobEntryKey, std::string> > |
| 379 BlobEntryKeyValuePairVec; |
| 380 |
| 381 class WriteDescriptor { |
| 382 public: |
| 383 WriteDescriptor(const GURL& url, int64_t key); |
| 384 WriteDescriptor(const base::FilePath& path, int64_t key); |
| 385 |
| 386 bool is_file() const { return is_file_; } |
| 387 const GURL& url() const { |
| 388 DCHECK(!is_file_); |
| 389 return url_; |
| 390 } |
| 391 const base::FilePath& file_path() const { |
| 392 DCHECK(is_file_); |
| 393 return file_path_; |
| 394 } |
| 395 int64_t key() const { return key_; } |
| 396 |
| 397 private: |
| 398 bool is_file_; |
| 399 GURL url_; |
| 400 base::FilePath file_path_; |
| 401 int64_t key_; |
| 402 }; |
| 403 |
| 404 class ChainedBlobWriter : public base::RefCounted<ChainedBlobWriter> { |
| 405 public: |
| 406 virtual void set_delegate( |
| 407 scoped_ptr<fileapi::FileWriterDelegate> delegate) = 0; |
| 408 |
| 409 // TODO(ericu): Add a reason in the event of failure. |
| 410 virtual void ReportWriteCompletion(bool succeeded, |
| 411 int64 bytes_written) = 0; |
| 412 |
| 413 virtual void Abort() = 0; |
| 414 |
| 415 protected: |
| 416 virtual ~ChainedBlobWriter() {} |
| 417 friend class base::RefCounted<ChainedBlobWriter>; |
| 418 }; |
| 419 class ChainedBlobWriterImpl; |
| 420 |
| 421 typedef std::vector<WriteDescriptor> WriteDescriptorVec; |
| 422 |
357 private: | 423 private: |
358 class BlobChangeRecord { | 424 class BlobChangeRecord { |
359 public: | 425 public: |
360 BlobChangeRecord(const std::string& key, int64 object_store_id); | 426 BlobChangeRecord(const std::string& key, int64 object_store_id); |
361 ~BlobChangeRecord(); | 427 ~BlobChangeRecord(); |
362 const std::string& key() const { return key_; } | 428 const std::string& key() const { return key_; } |
363 int64 object_store_id() const { return object_store_id_; } | 429 int64 object_store_id() const { return object_store_id_; } |
364 void SetBlobInfo(std::vector<IndexedDBBlobInfo>* blob_info); | 430 void SetBlobInfo(std::vector<IndexedDBBlobInfo>* blob_info); |
365 std::vector<IndexedDBBlobInfo>& mutable_blob_info() { return blob_info_; } | 431 std::vector<IndexedDBBlobInfo>& mutable_blob_info() { return blob_info_; } |
366 void SetHandles(ScopedVector<webkit_blob::BlobDataHandle>* handles); | 432 void SetHandles(ScopedVector<webkit_blob::BlobDataHandle>* handles); |
367 | 433 |
368 private: | 434 private: |
369 std::string key_; | 435 std::string key_; |
370 int64 object_store_id_; | 436 int64 object_store_id_; |
371 std::vector<IndexedDBBlobInfo> blob_info_; | 437 std::vector<IndexedDBBlobInfo> blob_info_; |
372 ScopedVector<webkit_blob::BlobDataHandle> handles_; | 438 ScopedVector<webkit_blob::BlobDataHandle> handles_; |
373 }; | 439 }; |
| 440 class BlobWriteCallbackWrapper; |
374 typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap; | 441 typedef std::map<std::string, BlobChangeRecord*> BlobChangeMap; |
375 | 442 |
| 443 // The callback will be called eventually on success or failure. |
| 444 void WriteNewBlobs(BlobEntryKeyValuePairVec& new_blob_entries, |
| 445 WriteDescriptorVec& new_files_to_write, |
| 446 scoped_refptr<BlobWriteCallback> callback); |
| 447 |
376 IndexedDBBackingStore* backing_store_; | 448 IndexedDBBackingStore* backing_store_; |
377 scoped_refptr<LevelDBTransaction> transaction_; | 449 scoped_refptr<LevelDBTransaction> transaction_; |
378 BlobChangeMap blob_change_map_; | 450 BlobChangeMap blob_change_map_; |
379 int64 database_id_; | 451 int64 database_id_; |
| 452 scoped_refptr<ChainedBlobWriter> chained_blob_writer_; |
380 }; | 453 }; |
381 | 454 |
382 protected: | 455 protected: |
383 IndexedDBBackingStore(IndexedDBFactory* indexed_db_factory, | 456 IndexedDBBackingStore(IndexedDBFactory* indexed_db_factory, |
384 const GURL& origin_url, | 457 const GURL& origin_url, |
385 const base::FilePath& blob_path, | 458 const base::FilePath& blob_path, |
| 459 net::URLRequestContext* request_context, |
386 scoped_ptr<LevelDBDatabase> db, | 460 scoped_ptr<LevelDBDatabase> db, |
387 scoped_ptr<LevelDBComparator> comparator, | 461 scoped_ptr<LevelDBComparator> comparator, |
388 base::TaskRunner* task_runner); | 462 base::TaskRunner* task_runner); |
389 virtual ~IndexedDBBackingStore(); | 463 virtual ~IndexedDBBackingStore(); |
390 friend class base::RefCounted<IndexedDBBackingStore>; | 464 friend class base::RefCounted<IndexedDBBackingStore>; |
391 | 465 |
| 466 virtual bool WriteBlobFile( |
| 467 int64 database_id, |
| 468 const Transaction::WriteDescriptor& descriptor, |
| 469 Transaction::ChainedBlobWriter* chained_blob_writer); |
| 470 virtual bool RemoveBlobFile(int64 database_id, int64 key); |
| 471 |
392 private: | 472 private: |
393 static scoped_refptr<IndexedDBBackingStore> Create( | 473 static scoped_refptr<IndexedDBBackingStore> Create( |
394 IndexedDBFactory* indexed_db_factory, | 474 IndexedDBFactory* indexed_db_factory, |
395 const GURL& origin_url, | 475 const GURL& origin_url, |
396 const base::FilePath& blob_path, | 476 const base::FilePath& blob_path, |
| 477 net::URLRequestContext* request_context, |
397 scoped_ptr<LevelDBDatabase> db, | 478 scoped_ptr<LevelDBDatabase> db, |
398 scoped_ptr<LevelDBComparator> comparator, | 479 scoped_ptr<LevelDBComparator> comparator, |
399 base::TaskRunner* task_runner); | 480 base::TaskRunner* task_runner); |
400 | 481 |
401 static bool ReadCorruptionInfo(const base::FilePath& path_base, | 482 static bool ReadCorruptionInfo(const base::FilePath& path_base, |
402 const GURL& origin_url, | 483 const GURL& origin_url, |
403 std::string& message); | 484 std::string& message); |
404 | 485 |
405 leveldb::Status FindKeyInIndex( | 486 leveldb::Status FindKeyInIndex( |
406 IndexedDBBackingStore::Transaction* transaction, | 487 IndexedDBBackingStore::Transaction* transaction, |
407 int64 database_id, | 488 int64 database_id, |
408 int64 object_store_id, | 489 int64 object_store_id, |
409 int64 index_id, | 490 int64 index_id, |
410 const IndexedDBKey& key, | 491 const IndexedDBKey& key, |
411 std::string* found_encoded_primary_key, | 492 std::string* found_encoded_primary_key, |
412 bool* found); | 493 bool* found); |
413 leveldb::Status GetIndexes(int64 database_id, | 494 leveldb::Status GetIndexes(int64 database_id, |
414 int64 object_store_id, | 495 int64 object_store_id, |
415 IndexedDBObjectStoreMetadata::IndexMap* map) | 496 IndexedDBObjectStoreMetadata::IndexMap* map) |
416 WARN_UNUSED_RESULT; | 497 WARN_UNUSED_RESULT; |
| 498 bool RemoveBlobDirectory(int64 database_id); |
417 | 499 |
418 IndexedDBFactory* indexed_db_factory_; | 500 IndexedDBFactory* indexed_db_factory_; |
419 const GURL origin_url_; | 501 const GURL origin_url_; |
420 base::FilePath blob_path_; | 502 base::FilePath blob_path_; |
421 | 503 |
422 // The origin identifier is a key prefix unique to the origin used in the | 504 // 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 | 505 // 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. | 506 // 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 | 507 // "http_localhost_81@1" Since only one origin is stored per backing store |
426 // this is redundant but necessary for backwards compatibility; the suffix | 508 // this is redundant but necessary for backwards compatibility; the suffix |
427 // provides for future flexibility. | 509 // provides for future flexibility. |
428 const std::string origin_identifier_; | 510 const std::string origin_identifier_; |
| 511 |
| 512 net::URLRequestContext* request_context_; |
429 base::TaskRunner* task_runner_; | 513 base::TaskRunner* task_runner_; |
430 std::set<int> child_process_ids_granted_; | 514 std::set<int> child_process_ids_granted_; |
431 | 515 |
432 scoped_ptr<LevelDBDatabase> db_; | 516 scoped_ptr<LevelDBDatabase> db_; |
433 scoped_ptr<LevelDBComparator> comparator_; | 517 scoped_ptr<LevelDBComparator> comparator_; |
434 // Whenever blobs are registered in active_blob_registry_, indexed_db_factory_ | 518 // Whenever blobs are registered in active_blob_registry_, indexed_db_factory_ |
435 // will hold a reference to this backing store. | 519 // will hold a reference to this backing store. |
436 IndexedDBActiveBlobRegistry active_blob_registry_; | 520 IndexedDBActiveBlobRegistry active_blob_registry_; |
437 base::OneShotTimer<IndexedDBBackingStore> close_timer_; | 521 base::OneShotTimer<IndexedDBBackingStore> close_timer_; |
438 }; | 522 }; |
439 | 523 |
440 } // namespace content | 524 } // namespace content |
441 | 525 |
442 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ | 526 #endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_ |
OLD | NEW |