Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

Side by Side Diff: content/browser/indexed_db/indexed_db_backing_store.cc

Issue 232343004: Pass blob info through from the IPC to the backing store on put. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix some nits Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698