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")); | |
cmumford
2014/04/10 16:59:43
Nit: Consider removing leading '.' as FilePath::kE
jsbell
2014/04/11 16:19:57
Can you give an example of where this would be pro
ericu
2014/04/14 23:23:38
It need not be an extension separator as long as i
| |
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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 } | 426 } |
418 virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) | 427 virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) |
419 OVERRIDE { | 428 OVERRIDE { |
420 return LevelDBDatabase::Destroy(file_name); | 429 return LevelDBDatabase::Destroy(file_name); |
421 } | 430 } |
422 }; | 431 }; |
423 | 432 |
424 IndexedDBBackingStore::IndexedDBBackingStore( | 433 IndexedDBBackingStore::IndexedDBBackingStore( |
425 IndexedDBFactory* indexed_db_factory, | 434 IndexedDBFactory* indexed_db_factory, |
426 const GURL& origin_url, | 435 const GURL& origin_url, |
436 const base::FilePath& blob_path, | |
427 scoped_ptr<LevelDBDatabase> db, | 437 scoped_ptr<LevelDBDatabase> db, |
428 scoped_ptr<LevelDBComparator> comparator, | 438 scoped_ptr<LevelDBComparator> comparator, |
429 base::TaskRunner* task_runner) | 439 base::TaskRunner* task_runner) |
430 : indexed_db_factory_(indexed_db_factory), | 440 : indexed_db_factory_(indexed_db_factory), |
431 origin_url_(origin_url), | 441 origin_url_(origin_url), |
442 blob_path_(blob_path), | |
432 origin_identifier_(ComputeOriginIdentifier(origin_url)), | 443 origin_identifier_(ComputeOriginIdentifier(origin_url)), |
433 task_runner_(task_runner), | 444 task_runner_(task_runner), |
434 db_(db.Pass()), | 445 db_(db.Pass()), |
435 comparator_(comparator.Pass()), | 446 comparator_(comparator.Pass()), |
436 active_blob_registry_(this) {} | 447 active_blob_registry_(this) {} |
437 | 448 |
438 IndexedDBBackingStore::~IndexedDBBackingStore() { | 449 IndexedDBBackingStore::~IndexedDBBackingStore() { |
450 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { | |
451 ChildProcessSecurityPolicyImpl* policy = | |
452 ChildProcessSecurityPolicyImpl::GetInstance(); | |
453 for (std::set<int>::iterator iter = child_process_ids_granted_.begin(); | |
cmumford
2014/04/10 16:59:43
Nit: const_iterator?
ericu
2014/04/14 23:23:38
Done.
| |
454 iter != child_process_ids_granted_.end(); | |
455 ++iter) { | |
456 policy->RevokeAllPermissionsForFile(*iter, blob_path_); | |
457 } | |
458 } | |
439 // db_'s destructor uses comparator_. The order of destruction is important. | 459 // db_'s destructor uses comparator_. The order of destruction is important. |
440 db_.reset(); | 460 db_.reset(); |
441 comparator_.reset(); | 461 comparator_.reset(); |
442 } | 462 } |
443 | 463 |
444 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( | 464 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( |
445 const std::string& primary_key, | 465 const std::string& primary_key, |
446 int64 version) | 466 int64 version) |
447 : primary_key_(primary_key), version_(version) { | 467 : primary_key_(primary_key), version_(version) { |
448 DCHECK(!primary_key.empty()); | 468 DCHECK(!primary_key.empty()); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 if (!base::CreateDirectory(path_base)) { | 667 if (!base::CreateDirectory(path_base)) { |
648 LOG(ERROR) << "Unable to create IndexedDB database path " | 668 LOG(ERROR) << "Unable to create IndexedDB database path " |
649 << path_base.AsUTF8Unsafe(); | 669 << path_base.AsUTF8Unsafe(); |
650 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, | 670 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY, |
651 origin_url); | 671 origin_url); |
652 return scoped_refptr<IndexedDBBackingStore>(); | 672 return scoped_refptr<IndexedDBBackingStore>(); |
653 } | 673 } |
654 | 674 |
655 const base::FilePath file_path = | 675 const base::FilePath file_path = |
656 path_base.Append(ComputeFileName(origin_url)); | 676 path_base.Append(ComputeFileName(origin_url)); |
677 const base::FilePath blob_path = | |
678 path_base.Append(ComputeBlobPath(origin_url)); | |
657 | 679 |
658 if (IsPathTooLong(file_path)) { | 680 if (IsPathTooLong(file_path)) { |
659 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, | 681 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, |
660 origin_url); | 682 origin_url); |
661 return scoped_refptr<IndexedDBBackingStore>(); | 683 return scoped_refptr<IndexedDBBackingStore>(); |
662 } | 684 } |
663 | 685 |
664 scoped_ptr<LevelDBDatabase> db; | 686 scoped_ptr<LevelDBDatabase> db; |
665 leveldb::Status status = leveldb_factory->OpenLevelDB( | 687 leveldb::Status status = leveldb_factory->OpenLevelDB( |
666 file_path, comparator.get(), &db, is_disk_full); | 688 file_path, comparator.get(), &db, is_disk_full); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 | 764 |
743 if (!db) { | 765 if (!db) { |
744 NOTREACHED(); | 766 NOTREACHED(); |
745 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, | 767 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, |
746 origin_url); | 768 origin_url); |
747 return scoped_refptr<IndexedDBBackingStore>(); | 769 return scoped_refptr<IndexedDBBackingStore>(); |
748 } | 770 } |
749 | 771 |
750 return Create(indexed_db_factory, | 772 return Create(indexed_db_factory, |
751 origin_url, | 773 origin_url, |
774 blob_path, | |
752 db.Pass(), | 775 db.Pass(), |
753 comparator.Pass(), | 776 comparator.Pass(), |
754 task_runner); | 777 task_runner); |
755 } | 778 } |
756 | 779 |
757 // static | 780 // static |
758 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 781 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
759 const GURL& origin_url, | 782 const GURL& origin_url, |
760 base::TaskRunner* task_runner) { | 783 base::TaskRunner* task_runner) { |
761 DefaultLevelDBFactory leveldb_factory; | 784 DefaultLevelDBFactory leveldb_factory; |
(...skipping 14 matching lines...) Expand all Loading... | |
776 if (!db) { | 799 if (!db) { |
777 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; | 800 LOG(ERROR) << "LevelDBDatabase::OpenInMemory failed."; |
778 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, | 801 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, |
779 origin_url); | 802 origin_url); |
780 return scoped_refptr<IndexedDBBackingStore>(); | 803 return scoped_refptr<IndexedDBBackingStore>(); |
781 } | 804 } |
782 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin_url); | 805 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS, origin_url); |
783 | 806 |
784 return Create(NULL /* indexed_db_factory */, | 807 return Create(NULL /* indexed_db_factory */, |
785 origin_url, | 808 origin_url, |
809 base::FilePath(), | |
786 db.Pass(), | 810 db.Pass(), |
787 comparator.Pass(), | 811 comparator.Pass(), |
788 task_runner); | 812 task_runner); |
789 } | 813 } |
790 | 814 |
791 // static | 815 // static |
792 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( | 816 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( |
793 IndexedDBFactory* indexed_db_factory, | 817 IndexedDBFactory* indexed_db_factory, |
794 const GURL& origin_url, | 818 const GURL& origin_url, |
819 const base::FilePath& blob_path, | |
795 scoped_ptr<LevelDBDatabase> db, | 820 scoped_ptr<LevelDBDatabase> db, |
796 scoped_ptr<LevelDBComparator> comparator, | 821 scoped_ptr<LevelDBComparator> comparator, |
797 base::TaskRunner* task_runner) { | 822 base::TaskRunner* task_runner) { |
798 // TODO(jsbell): Handle comparator name changes. | 823 // TODO(jsbell): Handle comparator name changes. |
799 | 824 |
800 scoped_refptr<IndexedDBBackingStore> backing_store( | 825 scoped_refptr<IndexedDBBackingStore> backing_store( |
801 new IndexedDBBackingStore(indexed_db_factory, | 826 new IndexedDBBackingStore(indexed_db_factory, |
802 origin_url, | 827 origin_url, |
828 blob_path, | |
803 db.Pass(), | 829 db.Pass(), |
804 comparator.Pass(), | 830 comparator.Pass(), |
805 task_runner)); | 831 task_runner)); |
806 if (!SetUpMetadata(backing_store->db_.get(), | 832 if (!SetUpMetadata(backing_store->db_.get(), |
807 backing_store->origin_identifier_)) | 833 backing_store->origin_identifier_)) |
808 return scoped_refptr<IndexedDBBackingStore>(); | 834 return scoped_refptr<IndexedDBBackingStore>(); |
809 | 835 |
810 return backing_store; | 836 return backing_store; |
811 } | 837 } |
812 | 838 |
839 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) { | |
840 if (!child_process_ids_granted_.count(child_process_id)) { | |
841 child_process_ids_granted_.insert(child_process_id); | |
842 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( | |
843 child_process_id, blob_path_); | |
844 } | |
845 } | |
846 | |
813 std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() { | 847 std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() { |
814 std::vector<base::string16> found_names; | 848 std::vector<base::string16> found_names; |
815 const std::string start_key = | 849 const std::string start_key = |
816 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); | 850 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); |
817 const std::string stop_key = | 851 const std::string stop_key = |
818 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); | 852 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); |
819 | 853 |
820 DCHECK(found_names.empty()); | 854 DCHECK(found_names.empty()); |
821 | 855 |
822 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); | 856 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1086 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1120 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
1087 break; | 1121 break; |
1088 } | 1122 } |
1089 bool auto_increment; | 1123 bool auto_increment; |
1090 { | 1124 { |
1091 StringPiece slice(it->Value()); | 1125 StringPiece slice(it->Value()); |
1092 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) | 1126 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) |
1093 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1127 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
1094 } | 1128 } |
1095 | 1129 |
1096 it->Next(); // Is evicatble. | 1130 it->Next(); // Is evictable. |
1097 if (!CheckObjectStoreAndMetaDataType(it.get(), | 1131 if (!CheckObjectStoreAndMetaDataType(it.get(), |
1098 stop_key, | 1132 stop_key, |
1099 object_store_id, | 1133 object_store_id, |
1100 ObjectStoreMetaDataKey::EVICTABLE)) { | 1134 ObjectStoreMetaDataKey::EVICTABLE)) { |
1101 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1135 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
1102 break; | 1136 break; |
1103 } | 1137 } |
1104 | 1138 |
1105 it->Next(); // Last version. | 1139 it->Next(); // Last version. |
1106 if (!CheckObjectStoreAndMetaDataType( | 1140 if (!CheckObjectStoreAndMetaDataType( |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1375 | 1409 |
1376 *new_version_number = version; | 1410 *new_version_number = version; |
1377 return s; | 1411 return s; |
1378 } | 1412 } |
1379 | 1413 |
1380 leveldb::Status IndexedDBBackingStore::PutRecord( | 1414 leveldb::Status IndexedDBBackingStore::PutRecord( |
1381 IndexedDBBackingStore::Transaction* transaction, | 1415 IndexedDBBackingStore::Transaction* transaction, |
1382 int64 database_id, | 1416 int64 database_id, |
1383 int64 object_store_id, | 1417 int64 object_store_id, |
1384 const IndexedDBKey& key, | 1418 const IndexedDBKey& key, |
1385 const IndexedDBValue& value, | 1419 IndexedDBValue& value, |
1420 ScopedVector<webkit_blob::BlobDataHandle>* handles, | |
1386 RecordIdentifier* record_identifier) { | 1421 RecordIdentifier* record_identifier) { |
1387 IDB_TRACE("IndexedDBBackingStore::PutRecord"); | 1422 IDB_TRACE("IndexedDBBackingStore::PutRecord"); |
1388 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1423 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
1389 return InvalidDBKeyStatus(); | 1424 return InvalidDBKeyStatus(); |
1390 DCHECK(key.IsValid()); | 1425 DCHECK(key.IsValid()); |
1391 | 1426 |
1392 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1427 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
1393 int64 version = -1; | 1428 int64 version = -1; |
1394 leveldb::Status s = GetNewVersionNumber( | 1429 leveldb::Status s = GetNewVersionNumber( |
1395 leveldb_transaction, database_id, object_store_id, &version); | 1430 leveldb_transaction, database_id, object_store_id, &version); |
1396 if (!s.ok()) | 1431 if (!s.ok()) |
1397 return s; | 1432 return s; |
1398 DCHECK_GE(version, 0); | 1433 DCHECK_GE(version, 0); |
1399 const std::string object_store_data_key = | 1434 const std::string object_store_data_key = |
1400 ObjectStoreDataKey::Encode(database_id, object_store_id, key); | 1435 ObjectStoreDataKey::Encode(database_id, object_store_id, key); |
1401 | 1436 |
1402 std::string v; | 1437 std::string v; |
1403 EncodeVarInt(version, &v); | 1438 EncodeVarInt(version, &v); |
1404 v.append(value.bits); | 1439 v.append(value.bits); |
1405 | 1440 |
1406 leveldb_transaction->Put(object_store_data_key, &v); | 1441 leveldb_transaction->Put(object_store_data_key, &v); |
1442 transaction->PutBlobInfo(database_id, | |
1443 object_store_id, | |
1444 object_store_data_key, | |
1445 &value.blob_info, | |
1446 handles); | |
1447 DCHECK(!handles->size()); | |
1407 | 1448 |
1408 const std::string exists_entry_key = | 1449 const std::string exists_entry_key = |
1409 ExistsEntryKey::Encode(database_id, object_store_id, key); | 1450 ExistsEntryKey::Encode(database_id, object_store_id, key); |
1410 std::string version_encoded; | 1451 std::string version_encoded; |
1411 EncodeInt(version, &version_encoded); | 1452 EncodeInt(version, &version_encoded); |
1412 leveldb_transaction->Put(exists_entry_key, &version_encoded); | 1453 leveldb_transaction->Put(exists_entry_key, &version_encoded); |
1413 | 1454 |
1414 std::string key_encoded; | 1455 std::string key_encoded; |
1415 EncodeIDBKey(key, &key_encoded); | 1456 EncodeIDBKey(key, &key_encoded); |
1416 record_identifier->Reset(key_encoded, version); | 1457 record_identifier->Reset(key_encoded, version); |
(...skipping 22 matching lines...) Expand all Loading... | |
1439 int64 object_store_id, | 1480 int64 object_store_id, |
1440 const RecordIdentifier& record_identifier) { | 1481 const RecordIdentifier& record_identifier) { |
1441 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); | 1482 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); |
1442 if (!KeyPrefix::ValidIds(database_id, object_store_id)) | 1483 if (!KeyPrefix::ValidIds(database_id, object_store_id)) |
1443 return InvalidDBKeyStatus(); | 1484 return InvalidDBKeyStatus(); |
1444 LevelDBTransaction* leveldb_transaction = transaction->transaction(); | 1485 LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
1445 | 1486 |
1446 const std::string object_store_data_key = ObjectStoreDataKey::Encode( | 1487 const std::string object_store_data_key = ObjectStoreDataKey::Encode( |
1447 database_id, object_store_id, record_identifier.primary_key()); | 1488 database_id, object_store_id, record_identifier.primary_key()); |
1448 leveldb_transaction->Remove(object_store_data_key); | 1489 leveldb_transaction->Remove(object_store_data_key); |
1490 transaction->PutBlobInfo( | |
1491 database_id, object_store_id, object_store_data_key, NULL, NULL); | |
1449 | 1492 |
1450 const std::string exists_entry_key = ExistsEntryKey::Encode( | 1493 const std::string exists_entry_key = ExistsEntryKey::Encode( |
1451 database_id, object_store_id, record_identifier.primary_key()); | 1494 database_id, object_store_id, record_identifier.primary_key()); |
1452 leveldb_transaction->Remove(exists_entry_key); | 1495 leveldb_transaction->Remove(exists_entry_key); |
1453 return leveldb::Status::OK(); | 1496 return leveldb::Status::OK(); |
1454 } | 1497 } |
1455 | 1498 |
1456 leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( | 1499 leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( |
1457 IndexedDBBackingStore::Transaction* transaction, | 1500 IndexedDBBackingStore::Transaction* transaction, |
1458 int64 database_id, | 1501 int64 database_id, |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2760 scoped_ptr<IndexCursorImpl> cursor( | 2803 scoped_ptr<IndexCursorImpl> cursor( |
2761 new IndexCursorImpl(leveldb_transaction, cursor_options)); | 2804 new IndexCursorImpl(leveldb_transaction, cursor_options)); |
2762 if (!cursor->FirstSeek()) | 2805 if (!cursor->FirstSeek()) |
2763 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 2806 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
2764 | 2807 |
2765 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); | 2808 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |
2766 } | 2809 } |
2767 | 2810 |
2768 IndexedDBBackingStore::Transaction::Transaction( | 2811 IndexedDBBackingStore::Transaction::Transaction( |
2769 IndexedDBBackingStore* backing_store) | 2812 IndexedDBBackingStore* backing_store) |
2770 : backing_store_(backing_store) {} | 2813 : backing_store_(backing_store), database_id_(-1) {} |
2771 | 2814 |
2772 IndexedDBBackingStore::Transaction::~Transaction() {} | 2815 IndexedDBBackingStore::Transaction::~Transaction() { |
2816 BlobChangeMap::iterator iter = blob_change_map_.begin(); | |
cmumford
2014/04/10 16:59:43
Can you use STLDeleteContainerPairSecondPointers()
ericu
2014/04/14 23:23:38
Done. Just barely makes it shorter, what with tha
| |
2817 for (; iter != blob_change_map_.end(); ++iter) { | |
2818 delete iter->second; | |
2819 } | |
2820 } | |
2773 | 2821 |
2774 void IndexedDBBackingStore::Transaction::Begin() { | 2822 void IndexedDBBackingStore::Transaction::Begin() { |
2775 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); | 2823 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); |
2776 DCHECK(!transaction_.get()); | 2824 DCHECK(!transaction_.get()); |
2777 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); | 2825 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); |
2778 } | 2826 } |
2779 | 2827 |
2780 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { | 2828 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { |
2781 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); | 2829 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); |
2782 DCHECK(transaction_.get()); | 2830 DCHECK(transaction_.get()); |
2783 leveldb::Status s = transaction_->Commit(); | 2831 leveldb::Status s = transaction_->Commit(); |
2784 transaction_ = NULL; | 2832 transaction_ = NULL; |
2785 if (!s.ok()) | 2833 if (!s.ok()) |
2786 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD); | 2834 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD); |
2787 return s; | 2835 return s; |
2788 } | 2836 } |
2789 | 2837 |
2790 void IndexedDBBackingStore::Transaction::Rollback() { | 2838 void IndexedDBBackingStore::Transaction::Rollback() { |
2791 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); | 2839 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); |
2792 DCHECK(transaction_.get()); | 2840 DCHECK(transaction_.get()); |
2793 transaction_->Rollback(); | 2841 transaction_->Rollback(); |
2794 transaction_ = NULL; | 2842 transaction_ = NULL; |
2795 } | 2843 } |
2796 | 2844 |
2845 | |
2846 void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetBlobInfo( | |
2847 std::vector<IndexedDBBlobInfo>* blob_info) { | |
2848 blob_info_.clear(); | |
2849 if (blob_info) | |
2850 blob_info_.swap(*blob_info); | |
cmumford
2014/04/10 16:59:43
Why swap the blob info vs. operator=()
ericu
2014/04/14 23:23:38
I believe that swapping the innards of a std::vect
| |
2851 } | |
2852 | |
2853 void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetHandles( | |
2854 ScopedVector<webkit_blob::BlobDataHandle>* handles) { | |
2855 handles_.clear(); | |
2856 if (handles) | |
2857 handles_.swap(*handles); | |
2858 } | |
2859 | |
2860 // This is storing an info, even if empty, even if the previous key had no blob | |
2861 // info that we know of. It duplicates a bunch of information stored in the | |
2862 // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the | |
2863 // changes to exists or index keys here. | |
2864 void IndexedDBBackingStore::Transaction::PutBlobInfo( | |
2865 int64 database_id, | |
2866 int64 object_store_id, | |
2867 const std::string& key, | |
2868 std::vector<IndexedDBBlobInfo>* blob_info, | |
2869 ScopedVector<webkit_blob::BlobDataHandle>* handles) { | |
2870 DCHECK_GT(key.size(), 0UL); | |
2871 if (database_id_ < 0) | |
2872 database_id_ = database_id; | |
2873 DCHECK_EQ(database_id_, database_id); | |
2874 | |
2875 BlobChangeMap::iterator it = blob_change_map_.find(key); | |
2876 BlobChangeRecord* record = NULL; | |
2877 if (it == blob_change_map_.end()) { | |
2878 record = new BlobChangeRecord(); | |
2879 blob_change_map_[key] = record; | |
2880 record->set_key(key); | |
2881 record->set_object_store_id(object_store_id); | |
2882 } else { | |
2883 record = it->second; | |
2884 } | |
2885 DCHECK_EQ(record->object_store_id(), object_store_id); | |
2886 record->SetBlobInfo(blob_info); | |
2887 record->SetHandles(handles); | |
2888 DCHECK(!handles || !handles->size()); | |
2889 } | |
2890 | |
2797 } // namespace content | 2891 } // namespace content |
OLD | NEW |