| 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 |