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 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "content/browser/child_process_security_policy_impl.h" |
| 16 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
15 #include "content/browser/indexed_db/indexed_db_database_error.h" | 17 #include "content/browser/indexed_db/indexed_db_database_error.h" |
16 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" | 18 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" |
17 #include "content/browser/indexed_db/indexed_db_metadata.h" | 19 #include "content/browser/indexed_db/indexed_db_metadata.h" |
18 #include "content/browser/indexed_db/indexed_db_tracing.h" | 20 #include "content/browser/indexed_db/indexed_db_tracing.h" |
19 #include "content/browser/indexed_db/indexed_db_value.h" | 21 #include "content/browser/indexed_db/indexed_db_value.h" |
20 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" | 22 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" |
21 #include "content/browser/indexed_db/leveldb/leveldb_database.h" | 23 #include "content/browser/indexed_db/leveldb/leveldb_database.h" |
22 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" | 24 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" |
23 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" | 25 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" |
24 #include "content/common/indexed_db/indexed_db_key.h" | 26 #include "content/common/indexed_db/indexed_db_key.h" |
25 #include "content/common/indexed_db/indexed_db_key_path.h" | 27 #include "content/common/indexed_db/indexed_db_key_path.h" |
26 #include "content/common/indexed_db/indexed_db_key_range.h" | 28 #include "content/common/indexed_db/indexed_db_key_range.h" |
27 #include "third_party/WebKit/public/platform/WebIDBTypes.h" | 29 #include "third_party/WebKit/public/platform/WebIDBTypes.h" |
28 #include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h" | 30 #include "third_party/WebKit/public/web/WebSerializedScriptValueVersion.h" |
29 #include "third_party/leveldatabase/env_chromium.h" | 31 #include "third_party/leveldatabase/env_chromium.h" |
| 32 #include "webkit/browser/blob/blob_data_handle.h" |
30 #include "webkit/common/database/database_identifier.h" | 33 #include "webkit/common/database/database_identifier.h" |
31 | 34 |
32 using base::StringPiece; | 35 using base::StringPiece; |
33 | 36 |
34 namespace content { | 37 namespace content { |
35 | 38 |
36 namespace { | 39 namespace { |
37 | 40 |
38 static std::string ComputeOriginIdentifier(const GURL& origin_url) { | 41 static std::string ComputeOriginIdentifier(const GURL& origin_url) { |
39 return webkit_database::GetIdentifierFromOrigin(origin_url) + "@1"; | 42 return webkit_database::GetIdentifierFromOrigin(origin_url) + "@1"; |
40 } | 43 } |
41 | 44 |
42 static base::FilePath ComputeFileName(const GURL& origin_url) { | 45 static base::FilePath ComputeFileName(const GURL& origin_url) { |
43 return base::FilePath() | 46 return base::FilePath() |
44 .AppendASCII(webkit_database::GetIdentifierFromOrigin(origin_url)) | 47 .AppendASCII(webkit_database::GetIdentifierFromOrigin(origin_url)) |
45 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); | 48 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); |
46 } | 49 } |
47 | 50 |
| 51 static base::FilePath ComputeBlobPath(const GURL& origin_url) { |
| 52 return base::FilePath() |
| 53 .AppendASCII(webkit_database::GetIdentifierFromOrigin(origin_url)) |
| 54 .AddExtension(FILE_PATH_LITERAL(".indexeddb.blob")); |
| 55 } |
| 56 |
48 static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) { | 57 static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) { |
49 return ComputeFileName(origin_url) | 58 return ComputeFileName(origin_url) |
50 .Append(FILE_PATH_LITERAL("corruption_info.json")); | 59 .Append(FILE_PATH_LITERAL("corruption_info.json")); |
51 } | 60 } |
52 | 61 |
53 } // namespace | 62 } // namespace |
54 | 63 |
55 static const int64 kKeyGeneratorInitialNumber = | 64 static const int64 kKeyGeneratorInitialNumber = |
56 1; // From the IndexedDB specification. | 65 1; // From the IndexedDB specification. |
57 | 66 |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 } | 433 } |
425 virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) | 434 virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) |
426 OVERRIDE { | 435 OVERRIDE { |
427 return LevelDBDatabase::Destroy(file_name); | 436 return LevelDBDatabase::Destroy(file_name); |
428 } | 437 } |
429 }; | 438 }; |
430 | 439 |
431 IndexedDBBackingStore::IndexedDBBackingStore( | 440 IndexedDBBackingStore::IndexedDBBackingStore( |
432 IndexedDBFactory* indexed_db_factory, | 441 IndexedDBFactory* indexed_db_factory, |
433 const GURL& origin_url, | 442 const GURL& origin_url, |
| 443 const base::FilePath& blob_path, |
434 scoped_ptr<LevelDBDatabase> db, | 444 scoped_ptr<LevelDBDatabase> db, |
435 scoped_ptr<LevelDBComparator> comparator, | 445 scoped_ptr<LevelDBComparator> comparator, |
436 base::TaskRunner* task_runner) | 446 base::TaskRunner* task_runner) |
437 : indexed_db_factory_(indexed_db_factory), | 447 : indexed_db_factory_(indexed_db_factory), |
438 origin_url_(origin_url), | 448 origin_url_(origin_url), |
| 449 blob_path_(blob_path), |
439 origin_identifier_(ComputeOriginIdentifier(origin_url)), | 450 origin_identifier_(ComputeOriginIdentifier(origin_url)), |
440 task_runner_(task_runner), | 451 task_runner_(task_runner), |
441 db_(db.Pass()), | 452 db_(db.Pass()), |
442 comparator_(comparator.Pass()), | 453 comparator_(comparator.Pass()), |
443 active_blob_registry_(this) {} | 454 active_blob_registry_(this) {} |
444 | 455 |
445 IndexedDBBackingStore::~IndexedDBBackingStore() { | 456 IndexedDBBackingStore::~IndexedDBBackingStore() { |
| 457 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { |
| 458 ChildProcessSecurityPolicyImpl* policy = |
| 459 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 460 std::set<int>::const_iterator iter; |
| 461 for (iter = child_process_ids_granted_.begin(); |
| 462 iter != child_process_ids_granted_.end(); |
| 463 ++iter) { |
| 464 policy->RevokeAllPermissionsForFile(*iter, blob_path_); |
| 465 } |
| 466 } |
446 // db_'s destructor uses comparator_. The order of destruction is important. | 467 // db_'s destructor uses comparator_. The order of destruction is important. |
447 db_.reset(); | 468 db_.reset(); |
448 comparator_.reset(); | 469 comparator_.reset(); |
449 } | 470 } |
450 | 471 |
451 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( | 472 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( |
452 const std::string& primary_key, | 473 const std::string& primary_key, |
453 int64 version) | 474 int64 version) |
454 : primary_key_(primary_key), version_(version) { | 475 : primary_key_(primary_key), version_(version) { |
455 DCHECK(!primary_key.empty()); | 476 DCHECK(!primary_key.empty()); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 if (!base::CreateDirectory(path_base)) { | 675 if (!base::CreateDirectory(path_base)) { |
655 LOG(ERROR) << "Unable to create IndexedDB database path " | 676 LOG(ERROR) << "Unable to create IndexedDB database path " |
656 << path_base.AsUTF8Unsafe(); | 677 << path_base.AsUTF8Unsafe(); |
657 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, | 678 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, |
658 origin_url); | 679 origin_url); |
659 return scoped_refptr<IndexedDBBackingStore>(); | 680 return scoped_refptr<IndexedDBBackingStore>(); |
660 } | 681 } |
661 | 682 |
662 const base::FilePath file_path = | 683 const base::FilePath file_path = |
663 path_base.Append(ComputeFileName(origin_url)); | 684 path_base.Append(ComputeFileName(origin_url)); |
| 685 const base::FilePath blob_path = |
| 686 path_base.Append(ComputeBlobPath(origin_url)); |
664 | 687 |
665 if (IsPathTooLong(file_path)) { | 688 if (IsPathTooLong(file_path)) { |
666 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, | 689 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, |
667 origin_url); | 690 origin_url); |
668 return scoped_refptr<IndexedDBBackingStore>(); | 691 return scoped_refptr<IndexedDBBackingStore>(); |
669 } | 692 } |
670 | 693 |
671 scoped_ptr<LevelDBDatabase> db; | 694 scoped_ptr<LevelDBDatabase> db; |
672 leveldb::Status status = leveldb_factory->OpenLevelDB( | 695 leveldb::Status status = leveldb_factory->OpenLevelDB( |
673 file_path, comparator.get(), &db, is_disk_full); | 696 file_path, comparator.get(), &db, is_disk_full); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 | 772 |
750 if (!db) { | 773 if (!db) { |
751 NOTREACHED(); | 774 NOTREACHED(); |
752 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, | 775 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, |
753 origin_url); | 776 origin_url); |
754 return scoped_refptr<IndexedDBBackingStore>(); | 777 return scoped_refptr<IndexedDBBackingStore>(); |
755 } | 778 } |
756 | 779 |
757 return Create(indexed_db_factory, | 780 return Create(indexed_db_factory, |
758 origin_url, | 781 origin_url, |
| 782 blob_path, |
759 db.Pass(), | 783 db.Pass(), |
760 comparator.Pass(), | 784 comparator.Pass(), |
761 task_runner); | 785 task_runner); |
762 } | 786 } |
763 | 787 |
764 // static | 788 // static |
765 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 789 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
766 const GURL& origin_url, | 790 const GURL& origin_url, |
767 base::TaskRunner* task_runner) { | 791 base::TaskRunner* task_runner) { |
768 DefaultLevelDBFactory leveldb_factory; | 792 DefaultLevelDBFactory leveldb_factory; |
(...skipping 14 matching lines...) Expand all Loading... |
783 if (!db) { | 807 if (!db) { |
784 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; | 808 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; |
785 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, | 809 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, |
786 origin_url); | 810 origin_url); |
787 return scoped_refptr<IndexedDBBackingStore>(); | 811 return scoped_refptr<IndexedDBBackingStore>(); |
788 } | 812 } |
789 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin_url); | 813 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin_url); |
790 | 814 |
791 return Create(NULL /* indexed_db_factory */, | 815 return Create(NULL /* indexed_db_factory */, |
792 origin_url, | 816 origin_url, |
| 817 base::FilePath(), |
793 db.Pass(), | 818 db.Pass(), |
794 comparator.Pass(), | 819 comparator.Pass(), |
795 task_runner); | 820 task_runner); |
796 } | 821 } |
797 | 822 |
798 // static | 823 // static |
799 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( | 824 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( |
800 IndexedDBFactory* indexed_db_factory, | 825 IndexedDBFactory* indexed_db_factory, |
801 const GURL& origin_url, | 826 const GURL& origin_url, |
| 827 const base::FilePath& blob_path, |
802 scoped_ptr<LevelDBDatabase> db, | 828 scoped_ptr<LevelDBDatabase> db, |
803 scoped_ptr<LevelDBComparator> comparator, | 829 scoped_ptr<LevelDBComparator> comparator, |
804 base::TaskRunner* task_runner) { | 830 base::TaskRunner* task_runner) { |
805 // TODO(jsbell): Handle comparator name changes. | 831 // TODO(jsbell): Handle comparator name changes. |
806 | 832 |
807 scoped_refptr<IndexedDBBackingStore> backing_store( | 833 scoped_refptr<IndexedDBBackingStore> backing_store( |
808 new IndexedDBBackingStore(indexed_db_factory, | 834 new IndexedDBBackingStore(indexed_db_factory, |
809 origin_url, | 835 origin_url, |
| 836 blob_path, |
810 db.Pass(), | 837 db.Pass(), |
811 comparator.Pass(), | 838 comparator.Pass(), |
812 task_runner)); | 839 task_runner)); |
813 if (!SetUpMetadata(backing_store->db_.get(), | 840 if (!SetUpMetadata(backing_store->db_.get(), |
814 backing_store->origin_identifier_)) | 841 backing_store->origin_identifier_)) |
815 return scoped_refptr<IndexedDBBackingStore>(); | 842 return scoped_refptr<IndexedDBBackingStore>(); |
816 | 843 |
817 return backing_store; | 844 return backing_store; |
818 } | 845 } |
819 | 846 |
| 847 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) { |
| 848 if (!child_process_ids_granted_.count(child_process_id)) { |
| 849 child_process_ids_granted_.insert(child_process_id); |
| 850 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
| 851 child_process_id, blob_path_); |
| 852 } |
| 853 } |
| 854 |
820 std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames( | 855 std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames( |
821 leveldb::Status* s) { | 856 leveldb::Status* s) { |
822 *s = leveldb::Status::OK(); | 857 *s = leveldb::Status::OK(); |
823 std::vector<base::string16> found_names; | 858 std::vector<base::string16> found_names; |
824 const std::string start_key = | 859 const std::string start_key = |
825 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); | 860 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); |
826 const std::string stop_key = | 861 const std::string stop_key = |
827 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); | 862 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); |
828 | 863 |
829 DCHECK(found_names.empty()); | 864 DCHECK(found_names.empty()); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1147 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
1113 break; | 1148 break; |
1114 } | 1149 } |
1115 bool auto_increment; | 1150 bool auto_increment; |
1116 { | 1151 { |
1117 StringPiece slice(it->Value()); | 1152 StringPiece slice(it->Value()); |
1118 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) | 1153 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) |
1119 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1154 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
1120 } | 1155 } |
1121 | 1156 |
1122 s = it->Next(); // Is evicatble. | 1157 s = it->Next(); // Is evictable. |
1123 if (!s.ok()) | 1158 if (!s.ok()) |
1124 break; | 1159 break; |
1125 if (!CheckObjectStoreAndMetaDataType(it.get(), | 1160 if (!CheckObjectStoreAndMetaDataType(it.get(), |
1126 stop_key, | 1161 stop_key, |
1127 object_store_id, | 1162 object_store_id, |
1128 ObjectStoreMetaDataKey::EVICTABLE)) { | 1163 ObjectStoreMetaDataKey::EVICTABLE)) { |
1129 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1164 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
1130 break; | 1165 break; |
1131 } | 1166 } |
1132 | 1167 |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 | 1463 |
1429 *new_version_number = version; | 1464 *new_version_number = version; |
1430 return s; | 1465 return s; |
1431 } | 1466 } |
1432 | 1467 |
1433 leveldb::Status IndexedDBBackingStore::PutRecord( | 1468 leveldb::Status IndexedDBBackingStore::PutRecord( |
1434 IndexedDBBackingStore::Transaction* transaction, | 1469 IndexedDBBackingStore::Transaction* transaction, |
1435 int64 database_id, | 1470 int64 database_id, |
1436 int64 object_store_id, | 1471 int64 object_store_id, |
1437 const IndexedDBKey& key, | 1472 const IndexedDBKey& key, |
1438 const IndexedDBValue& value, | 1473 IndexedDBValue& value, |
| 1474 ScopedVector<webkit_blob::BlobDataHandle>* handles, |
1439 RecordIdentifier* record_identifier) { | 1475 RecordIdentifier* record_identifier) { |
1440 IDB_TRACE("IndexedDBBackingStore::PutRecord"); | 1476 IDB_TRACE("IndexedDBBackingStore::PutRecord"); |
1441 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1477 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
1442 return InvalidDBKeyStatus(); | 1478 return InvalidDBKeyStatus(); |
1443 DCHECK(key.IsValid()); | 1479 DCHECK(key.IsValid()); |
1444 | 1480 |
1445 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1481 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
1446 int64 version = -1; | 1482 int64 version = -1; |
1447 leveldb::Status s = GetNewVersionNumber( | 1483 leveldb::Status s = GetNewVersionNumber( |
1448 leveldb_transaction, database_id, object_store_id, &version); | 1484 leveldb_transaction, database_id, object_store_id, &version); |
1449 if (!s.ok()) | 1485 if (!s.ok()) |
1450 return s; | 1486 return s; |
1451 DCHECK_GE(version, 0); | 1487 DCHECK_GE(version, 0); |
1452 const std::string object_store_data_key = | 1488 const std::string object_store_data_key = |
1453 ObjectStoreDataKey::Encode(database_id, object_store_id, key); | 1489 ObjectStoreDataKey::Encode(database_id, object_store_id, key); |
1454 | 1490 |
1455 std::string v; | 1491 std::string v; |
1456 EncodeVarInt(version, &v); | 1492 EncodeVarInt(version, &v); |
1457 v.append(value.bits); | 1493 v.append(value.bits); |
1458 | 1494 |
1459 leveldb_transaction->Put(object_store_data_key, &v); | 1495 leveldb_transaction->Put(object_store_data_key, &v); |
| 1496 transaction->PutBlobInfo(database_id, |
| 1497 object_store_id, |
| 1498 object_store_data_key, |
| 1499 &value.blob_info, |
| 1500 handles); |
| 1501 DCHECK(!handles->size()); |
1460 | 1502 |
1461 const std::string exists_entry_key = | 1503 const std::string exists_entry_key = |
1462 ExistsEntryKey::Encode(database_id, object_store_id, key); | 1504 ExistsEntryKey::Encode(database_id, object_store_id, key); |
1463 std::string version_encoded; | 1505 std::string version_encoded; |
1464 EncodeInt(version, &version_encoded); | 1506 EncodeInt(version, &version_encoded); |
1465 leveldb_transaction->Put(exists_entry_key, &version_encoded); | 1507 leveldb_transaction->Put(exists_entry_key, &version_encoded); |
1466 | 1508 |
1467 std::string key_encoded; | 1509 std::string key_encoded; |
1468 EncodeIDBKey(key, &key_encoded); | 1510 EncodeIDBKey(key, &key_encoded); |
1469 record_identifier->Reset(key_encoded, version); | 1511 record_identifier->Reset(key_encoded, version); |
(...skipping 25 matching lines...) Expand all Loading... |
1495 int64 object_store_id, | 1537 int64 object_store_id, |
1496 const RecordIdentifier& record_identifier) { | 1538 const RecordIdentifier& record_identifier) { |
1497 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); | 1539 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); |
1498 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1540 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
1499 return InvalidDBKeyStatus(); | 1541 return InvalidDBKeyStatus(); |
1500 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1542 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
1501 | 1543 |
1502 const std::string object_store_data_key = ObjectStoreDataKey::Encode( | 1544 const std::string object_store_data_key = ObjectStoreDataKey::Encode( |
1503 database_id, object_store_id, record_identifier.primary_key()); | 1545 database_id, object_store_id, record_identifier.primary_key()); |
1504 leveldb_transaction->Remove(object_store_data_key); | 1546 leveldb_transaction->Remove(object_store_data_key); |
| 1547 transaction->PutBlobInfo( |
| 1548 database_id, object_store_id, object_store_data_key, NULL, NULL); |
1505 | 1549 |
1506 const std::string exists_entry_key = ExistsEntryKey::Encode( | 1550 const std::string exists_entry_key = ExistsEntryKey::Encode( |
1507 database_id, object_store_id, record_identifier.primary_key()); | 1551 database_id, object_store_id, record_identifier.primary_key()); |
1508 leveldb_transaction->Remove(exists_entry_key); | 1552 leveldb_transaction->Remove(exists_entry_key); |
1509 return leveldb::Status::OK(); | 1553 return leveldb::Status::OK(); |
1510 } | 1554 } |
1511 | 1555 |
1512 leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( | 1556 leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( |
1513 IndexedDBBackingStore::Transaction* transaction, | 1557 IndexedDBBackingStore::Transaction* transaction, |
1514 int64 database_id, | 1558 int64 database_id, |
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2872 scoped_ptr<IndexCursorImpl> cursor( | 2916 scoped_ptr<IndexCursorImpl> cursor( |
2873 new IndexCursorImpl(leveldb_transaction, cursor_options)); | 2917 new IndexCursorImpl(leveldb_transaction, cursor_options)); |
2874 if (!cursor->FirstSeek(s)) | 2918 if (!cursor->FirstSeek(s)) |
2875 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 2919 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
2876 | 2920 |
2877 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); | 2921 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |
2878 } | 2922 } |
2879 | 2923 |
2880 IndexedDBBackingStore::Transaction::Transaction( | 2924 IndexedDBBackingStore::Transaction::Transaction( |
2881 IndexedDBBackingStore* backing_store) | 2925 IndexedDBBackingStore* backing_store) |
2882 : backing_store_(backing_store) {} | 2926 : backing_store_(backing_store), database_id_(-1) {} |
2883 | 2927 |
2884 IndexedDBBackingStore::Transaction::~Transaction() {} | 2928 IndexedDBBackingStore::Transaction::~Transaction() { |
| 2929 STLDeleteContainerPairSecondPointers( |
| 2930 blob_change_map_.begin(), blob_change_map_.end()); |
| 2931 } |
2885 | 2932 |
2886 void IndexedDBBackingStore::Transaction::Begin() { | 2933 void IndexedDBBackingStore::Transaction::Begin() { |
2887 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); | 2934 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); |
2888 DCHECK(!transaction_.get()); | 2935 DCHECK(!transaction_.get()); |
2889 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); | 2936 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); |
2890 } | 2937 } |
2891 | 2938 |
2892 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { | 2939 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { |
2893 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); | 2940 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); |
2894 DCHECK(transaction_.get()); | 2941 DCHECK(transaction_.get()); |
2895 leveldb::Status s = transaction_->Commit(); | 2942 leveldb::Status s = transaction_->Commit(); |
2896 transaction_ = NULL; | 2943 transaction_ = NULL; |
2897 if (!s.ok()) | 2944 if (!s.ok()) |
2898 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD); | 2945 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD); |
2899 return s; | 2946 return s; |
2900 } | 2947 } |
2901 | 2948 |
2902 void IndexedDBBackingStore::Transaction::Rollback() { | 2949 void IndexedDBBackingStore::Transaction::Rollback() { |
2903 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); | 2950 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); |
2904 DCHECK(transaction_.get()); | 2951 DCHECK(transaction_.get()); |
2905 transaction_->Rollback(); | 2952 transaction_->Rollback(); |
2906 transaction_ = NULL; | 2953 transaction_ = NULL; |
2907 } | 2954 } |
2908 | 2955 |
| 2956 IndexedDBBackingStore::Transaction::BlobChangeRecord::BlobChangeRecord( |
| 2957 const std::string& key, int64 object_store_id) |
| 2958 : key_(key), object_store_id_(object_store_id) { |
| 2959 } |
| 2960 |
| 2961 IndexedDBBackingStore::Transaction::BlobChangeRecord::~BlobChangeRecord() { |
| 2962 } |
| 2963 |
| 2964 void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetBlobInfo( |
| 2965 std::vector<IndexedDBBlobInfo>* blob_info) { |
| 2966 blob_info_.clear(); |
| 2967 if (blob_info) |
| 2968 blob_info_.swap(*blob_info); |
| 2969 } |
| 2970 |
| 2971 void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetHandles( |
| 2972 ScopedVector<webkit_blob::BlobDataHandle>* handles) { |
| 2973 handles_.clear(); |
| 2974 if (handles) |
| 2975 handles_.swap(*handles); |
| 2976 } |
| 2977 |
| 2978 // This is storing an info, even if empty, even if the previous key had no blob |
| 2979 // info that we know of. It duplicates a bunch of information stored in the |
| 2980 // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the |
| 2981 // changes to exists or index keys here. |
| 2982 void IndexedDBBackingStore::Transaction::PutBlobInfo( |
| 2983 int64 database_id, |
| 2984 int64 object_store_id, |
| 2985 const std::string& key, |
| 2986 std::vector<IndexedDBBlobInfo>* blob_info, |
| 2987 ScopedVector<webkit_blob::BlobDataHandle>* handles) { |
| 2988 DCHECK_GT(key.size(), 0UL); |
| 2989 if (database_id_ < 0) |
| 2990 database_id_ = database_id; |
| 2991 DCHECK_EQ(database_id_, database_id); |
| 2992 |
| 2993 BlobChangeMap::iterator it = blob_change_map_.find(key); |
| 2994 BlobChangeRecord* record = NULL; |
| 2995 if (it == blob_change_map_.end()) { |
| 2996 record = new BlobChangeRecord(key, object_store_id); |
| 2997 blob_change_map_[key] = record; |
| 2998 } else { |
| 2999 record = it->second; |
| 3000 } |
| 3001 DCHECK_EQ(record->object_store_id(), object_store_id); |
| 3002 record->SetBlobInfo(blob_info); |
| 3003 record->SetHandles(handles); |
| 3004 DCHECK(!handles || !handles->size()); |
| 3005 } |
| 3006 |
2909 } // namespace content | 3007 } // namespace content |
OLD | NEW |