Chromium Code Reviews| Index: content/browser/indexed_db/indexed_db_backing_store.cc |
| diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc |
| index 1e1d85b4cbbf9e277f005c83fe55a180ce7f00b9..45be2dc753327728fa10ac43dd24303a61045e32 100644 |
| --- a/content/browser/indexed_db/indexed_db_backing_store.cc |
| +++ b/content/browser/indexed_db/indexed_db_backing_store.cc |
| @@ -1884,11 +1884,13 @@ leveldb::Status IndexedDBBackingStore::PutRecord( |
| v.append(value.bits); |
| leveldb_transaction->Put(object_store_data_key, &v); |
| - transaction->PutBlobInfo(database_id, |
| - object_store_id, |
| - object_store_data_key, |
| - &value.blob_info, |
| - handles); |
| + s = transaction->PutBlobInfoIfNeeded(database_id, |
| + object_store_id, |
| + object_store_data_key, |
| + &value.blob_info, |
| + handles); |
| + if (!s.ok()) |
| + return s; |
| DCHECK(!handles->size()); |
| const std::string exists_entry_key = |
| @@ -1937,8 +1939,10 @@ leveldb::Status IndexedDBBackingStore::DeleteRecord( |
| const std::string object_store_data_key = ObjectStoreDataKey::Encode( |
| database_id, object_store_id, record_identifier.primary_key()); |
| leveldb_transaction->Remove(object_store_data_key); |
| - transaction->PutBlobInfo( |
| + leveldb::Status s = transaction->PutBlobInfoIfNeeded( |
| database_id, object_store_id, object_store_data_key, NULL, NULL); |
| + if (!s.ok()) |
| + return s; |
| const std::string exists_entry_key = ExistsEntryKey::Encode( |
| database_id, object_store_id, record_identifier.primary_key()); |
| @@ -4145,6 +4149,36 @@ IndexedDBBackingStore::BlobChangeRecord::Clone() const { |
| return record.Pass(); |
| } |
| +leveldb::Status IndexedDBBackingStore::Transaction::PutBlobInfoIfNeeded( |
| + int64 database_id, |
| + int64 object_store_id, |
| + const std::string& object_store_data_key, |
| + std::vector<IndexedDBBlobInfo>* blob_info, |
| + ScopedVector<webkit_blob::BlobDataHandle>* handles) { |
| + if (!blob_info || blob_info->empty()) { |
| + blob_change_map_.erase(object_store_data_key); |
| + incognito_blob_map_.erase(object_store_data_key); |
| + |
| + BlobEntryKey blob_entry_key; |
| + StringPiece leveldb_key_piece(object_store_data_key); |
| + if (!BlobEntryKey::FromObjectStoreDataKey(&leveldb_key_piece, |
| + &blob_entry_key)) { |
| + NOTREACHED(); |
| + return InternalInconsistencyStatus(); |
| + } |
| + scoped_ptr<LevelDBIterator> it = transaction()->CreateIterator(); |
|
jsbell
2014/06/10 22:16:32
Why an iterator instead of just a Get?
ericu
2014/06/10 22:30:48
Copypasta. Fixed.
|
| + std::string encoded_key = blob_entry_key.Encode(); |
| + leveldb::Status s = it->Seek(encoded_key); |
| + if (!s.ok()) |
| + return s; |
| + if (!it->IsValid() || CompareKeys(it->Key(), encoded_key) != 0) |
| + return leveldb::Status::OK(); |
| + } |
| + PutBlobInfo( |
| + database_id, object_store_id, object_store_data_key, blob_info, handles); |
| + return leveldb::Status::OK(); |
| +} |
| + |
| // This is storing an info, even if empty, even if the previous key had no blob |
| // info that we know of. It duplicates a bunch of information stored in the |
| // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the |