Chromium Code Reviews| 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/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { | 595 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { |
| 596 ChildProcessSecurityPolicyImpl* policy = | 596 ChildProcessSecurityPolicyImpl* policy = |
| 597 ChildProcessSecurityPolicyImpl::GetInstance(); | 597 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 598 std::set<int>::const_iterator iter; | 598 std::set<int>::const_iterator iter; |
| 599 for (iter = child_process_ids_granted_.begin(); | 599 for (iter = child_process_ids_granted_.begin(); |
| 600 iter != child_process_ids_granted_.end(); | 600 iter != child_process_ids_granted_.end(); |
| 601 ++iter) { | 601 ++iter) { |
| 602 policy->RevokeAllPermissionsForFile(*iter, blob_path_); | 602 policy->RevokeAllPermissionsForFile(*iter, blob_path_); |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), | |
| 606 incognito_blob_map_.end()); | |
| 605 // db_'s destructor uses comparator_. The order of destruction is important. | 607 // db_'s destructor uses comparator_. The order of destruction is important. |
| 606 db_.reset(); | 608 db_.reset(); |
| 607 comparator_.reset(); | 609 comparator_.reset(); |
| 608 } | 610 } |
| 609 | 611 |
| 610 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( | 612 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( |
| 611 const std::string& primary_key, | 613 const std::string& primary_key, |
| 612 int64 version) | 614 int64 version) |
| 613 : primary_key_(primary_key), version_(version) { | 615 : primary_key_(primary_key), version_(version) { |
| 614 DCHECK(!primary_key.empty()); | 616 DCHECK(!primary_key.empty()); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1009 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); | 1011 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); |
| 1010 | 1012 |
| 1011 DCHECK(found_names.empty()); | 1013 DCHECK(found_names.empty()); |
| 1012 | 1014 |
| 1013 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); | 1015 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| 1014 for (*s = it->Seek(start_key); | 1016 for (*s = it->Seek(start_key); |
| 1015 s->ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; | 1017 s->ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| 1016 *s = it->Next()) { | 1018 *s = it->Next()) { |
| 1017 StringPiece slice(it->Key()); | 1019 StringPiece slice(it->Key()); |
| 1018 DatabaseNameKey database_name_key; | 1020 DatabaseNameKey database_name_key; |
| 1019 if (!DatabaseNameKey::Decode(&slice, &database_name_key)) { | 1021 if (!DatabaseNameKey::Decode(&slice, &database_name_key) || |
| 1022 !slice.empty()) { | |
| 1020 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); | 1023 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); |
| 1021 continue; | 1024 continue; |
| 1022 } | 1025 } |
| 1023 found_names.push_back(database_name_key.database_name()); | 1026 found_names.push_back(database_name_key.database_name()); |
| 1024 } | 1027 } |
| 1025 | 1028 |
| 1026 if (!s->ok()) | 1029 if (!s->ok()) |
| 1027 INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES); | 1030 INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES); |
| 1028 | 1031 |
| 1029 return found_names; | 1032 return found_names; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1249 const std::string stop_key = | 1252 const std::string stop_key = |
| 1250 ObjectStoreMetaDataKey::EncodeMaxKey(database_id); | 1253 ObjectStoreMetaDataKey::EncodeMaxKey(database_id); |
| 1251 | 1254 |
| 1252 DCHECK(object_stores->empty()); | 1255 DCHECK(object_stores->empty()); |
| 1253 | 1256 |
| 1254 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); | 1257 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| 1255 leveldb::Status s = it->Seek(start_key); | 1258 leveldb::Status s = it->Seek(start_key); |
| 1256 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { | 1259 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { |
| 1257 StringPiece slice(it->Key()); | 1260 StringPiece slice(it->Key()); |
| 1258 ObjectStoreMetaDataKey meta_data_key; | 1261 ObjectStoreMetaDataKey meta_data_key; |
| 1259 bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key); | 1262 bool ok = |
| 1263 ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key) && slice.empty(); | |
| 1260 DCHECK(ok); | 1264 DCHECK(ok); |
| 1261 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { | 1265 if (!ok || meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { |
| 1262 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); | 1266 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| 1263 // Possible stale metadata, but don't fail the load. | 1267 // Possible stale metadata, but don't fail the load. |
| 1264 s = it->Next(); | 1268 s = it->Next(); |
| 1265 if (!s.ok()) | 1269 if (!s.ok()) |
| 1266 break; | 1270 break; |
| 1267 continue; | 1271 continue; |
| 1268 } | 1272 } |
| 1269 | 1273 |
| 1270 int64 object_store_id = meta_data_key.ObjectStoreId(); | 1274 int64 object_store_id = meta_data_key.ObjectStoreId(); |
| 1271 | 1275 |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1757 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); | 1761 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); |
| 1758 | 1762 |
| 1759 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); | 1763 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); |
| 1760 int64 max_numeric_key = 0; | 1764 int64 max_numeric_key = 0; |
| 1761 | 1765 |
| 1762 for (s = it->Seek(start_key); | 1766 for (s = it->Seek(start_key); |
| 1763 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; | 1767 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| 1764 s = it->Next()) { | 1768 s = it->Next()) { |
| 1765 StringPiece slice(it->Key()); | 1769 StringPiece slice(it->Key()); |
| 1766 ObjectStoreDataKey data_key; | 1770 ObjectStoreDataKey data_key; |
| 1767 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) { | 1771 if (!ObjectStoreDataKey::Decode(&slice, &data_key) || !slice.empty()) { |
| 1768 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); | 1772 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); |
| 1769 return InternalInconsistencyStatus(); | 1773 return InternalInconsistencyStatus(); |
| 1770 } | 1774 } |
| 1771 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); | 1775 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); |
| 1772 if (user_key->type() == blink::WebIDBKeyTypeNumber) { | 1776 if (user_key->type() == blink::WebIDBKeyTypeNumber) { |
| 1773 int64 n = static_cast<int64>(user_key->number()); | 1777 int64 n = static_cast<int64>(user_key->number()); |
| 1774 if (n > max_numeric_key) | 1778 if (n > max_numeric_key) |
| 1775 max_numeric_key = n; | 1779 max_numeric_key = n; |
| 1776 } | 1780 } |
| 1777 } | 1781 } |
| (...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3391 scoped_ptr<IndexCursorImpl> cursor( | 3395 scoped_ptr<IndexCursorImpl> cursor( |
| 3392 new IndexCursorImpl(leveldb_transaction, cursor_options)); | 3396 new IndexCursorImpl(leveldb_transaction, cursor_options)); |
| 3393 if (!cursor->FirstSeek(s)) | 3397 if (!cursor->FirstSeek(s)) |
| 3394 return scoped_ptr<IndexedDBBackingStore::Cursor>(); | 3398 return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| 3395 | 3399 |
| 3396 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); | 3400 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |
| 3397 } | 3401 } |
| 3398 | 3402 |
| 3399 IndexedDBBackingStore::Transaction::Transaction( | 3403 IndexedDBBackingStore::Transaction::Transaction( |
| 3400 IndexedDBBackingStore* backing_store) | 3404 IndexedDBBackingStore* backing_store) |
| 3401 : backing_store_(backing_store), database_id_(-1) {} | 3405 : backing_store_(backing_store), database_id_(-1) { |
| 3406 } | |
| 3402 | 3407 |
| 3403 IndexedDBBackingStore::Transaction::~Transaction() { | 3408 IndexedDBBackingStore::Transaction::~Transaction() { |
| 3404 STLDeleteContainerPairSecondPointers( | 3409 STLDeleteContainerPairSecondPointers( |
| 3405 blob_change_map_.begin(), blob_change_map_.end()); | 3410 blob_change_map_.begin(), blob_change_map_.end()); |
| 3411 STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), | |
| 3412 incognito_blob_map_.end()); | |
| 3406 } | 3413 } |
| 3407 | 3414 |
| 3408 void IndexedDBBackingStore::Transaction::Begin() { | 3415 void IndexedDBBackingStore::Transaction::Begin() { |
| 3409 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); | 3416 IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); |
| 3410 DCHECK(!transaction_.get()); | 3417 DCHECK(!transaction_.get()); |
| 3411 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); | 3418 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); |
| 3419 | |
| 3420 // If incognito, this snapshots blobs just as the above transaction_ | |
| 3421 // constructor snapshots the leveldb. | |
| 3422 BlobChangeMap::const_iterator iter; | |
| 3423 for (iter = backing_store_->incognito_blob_map_.begin(); | |
| 3424 iter != backing_store_->incognito_blob_map_.end(); | |
| 3425 ++iter) | |
| 3426 incognito_blob_map_[iter->first] = iter->second->Copy().release(); | |
| 3412 } | 3427 } |
| 3413 | 3428 |
| 3414 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { | 3429 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { |
| 3415 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); | 3430 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); |
| 3416 DCHECK(transaction_.get()); | 3431 DCHECK(transaction_.get()); |
| 3417 leveldb::Status s = transaction_->Commit(); | 3432 leveldb::Status s = transaction_->Commit(); |
| 3418 transaction_ = NULL; | 3433 transaction_ = NULL; |
| 3434 | |
| 3435 if (s.ok() && backing_store_->is_incognito() && !blob_change_map_.empty()) { | |
| 3436 BlobChangeMap::iterator iter; | |
| 3437 for (iter = blob_change_map_.begin(); iter != blob_change_map_.end(); | |
| 3438 ++iter) { | |
| 3439 BlobChangeMap& target_map = backing_store_->incognito_blob_map_; | |
|
jsbell
2014/05/05 22:21:23
nit: move this out of the for() loop.
ericu
2014/05/05 23:03:20
Done.
| |
| 3440 BlobChangeMap::iterator target_record = target_map.find(iter->first); | |
| 3441 if (target_record != target_map.end()) { | |
| 3442 delete target_record->second; | |
| 3443 target_map.erase(target_record); | |
| 3444 } | |
| 3445 if (iter->second) { | |
| 3446 target_map[iter->first] = iter->second; | |
| 3447 iter->second = NULL; | |
| 3448 } | |
| 3449 } | |
| 3450 } | |
| 3419 if (!s.ok()) | 3451 if (!s.ok()) |
| 3420 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD); | 3452 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD); |
| 3421 return s; | 3453 return s; |
| 3422 } | 3454 } |
| 3423 | 3455 |
| 3424 | 3456 |
| 3425 class IndexedDBBackingStore::Transaction::BlobWriteCallbackWrapper | 3457 class IndexedDBBackingStore::Transaction::BlobWriteCallbackWrapper |
| 3426 : public IndexedDBBackingStore::BlobWriteCallback { | 3458 : public IndexedDBBackingStore::BlobWriteCallback { |
| 3427 public: | 3459 public: |
| 3428 BlobWriteCallbackWrapper(IndexedDBBackingStore::Transaction* transaction, | 3460 BlobWriteCallbackWrapper(IndexedDBBackingStore::Transaction* transaction, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3471 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); | 3503 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); |
| 3472 DCHECK(transaction_.get()); | 3504 DCHECK(transaction_.get()); |
| 3473 if (chained_blob_writer_) { | 3505 if (chained_blob_writer_) { |
| 3474 chained_blob_writer_->Abort(); | 3506 chained_blob_writer_->Abort(); |
| 3475 chained_blob_writer_ = NULL; | 3507 chained_blob_writer_ = NULL; |
| 3476 } | 3508 } |
| 3477 transaction_->Rollback(); | 3509 transaction_->Rollback(); |
| 3478 transaction_ = NULL; | 3510 transaction_ = NULL; |
| 3479 } | 3511 } |
| 3480 | 3512 |
| 3481 IndexedDBBackingStore::Transaction::BlobChangeRecord::BlobChangeRecord( | 3513 IndexedDBBackingStore::BlobChangeRecord::BlobChangeRecord( |
| 3482 const std::string& key, int64 object_store_id) | 3514 const std::string& key, |
| 3515 int64 object_store_id) | |
| 3483 : key_(key), object_store_id_(object_store_id) { | 3516 : key_(key), object_store_id_(object_store_id) { |
| 3484 } | 3517 } |
| 3485 | 3518 |
| 3486 IndexedDBBackingStore::Transaction::BlobChangeRecord::~BlobChangeRecord() { | 3519 IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() { |
| 3487 } | 3520 } |
| 3488 | 3521 |
| 3489 void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetBlobInfo( | 3522 void IndexedDBBackingStore::BlobChangeRecord::SetBlobInfo( |
| 3490 std::vector<IndexedDBBlobInfo>* blob_info) { | 3523 std::vector<IndexedDBBlobInfo>* blob_info) { |
| 3491 blob_info_.clear(); | 3524 blob_info_.clear(); |
| 3492 if (blob_info) | 3525 if (blob_info) |
| 3493 blob_info_.swap(*blob_info); | 3526 blob_info_.swap(*blob_info); |
| 3494 } | 3527 } |
| 3495 | 3528 |
| 3496 void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetHandles( | 3529 void IndexedDBBackingStore::BlobChangeRecord::SetHandles( |
| 3497 ScopedVector<webkit_blob::BlobDataHandle>* handles) { | 3530 ScopedVector<webkit_blob::BlobDataHandle>* handles) { |
| 3498 handles_.clear(); | 3531 handles_.clear(); |
| 3499 if (handles) | 3532 if (handles) |
| 3500 handles_.swap(*handles); | 3533 handles_.swap(*handles); |
| 3501 } | 3534 } |
| 3502 | 3535 |
| 3536 scoped_ptr<IndexedDBBackingStore::BlobChangeRecord> | |
| 3537 IndexedDBBackingStore::BlobChangeRecord::Copy() const { | |
| 3538 scoped_ptr<IndexedDBBackingStore::BlobChangeRecord> record( | |
| 3539 new BlobChangeRecord(key_, object_store_id_)); | |
| 3540 record->blob_info_ = blob_info_; | |
| 3541 | |
| 3542 ScopedVector<webkit_blob::BlobDataHandle>::const_iterator iter; | |
| 3543 for (iter = handles_.begin(); iter != handles_.end(); ++iter) | |
| 3544 record->handles_.push_back(new webkit_blob::BlobDataHandle(**iter)); | |
| 3545 return record.Pass(); | |
| 3546 } | |
| 3547 | |
| 3503 // This is storing an info, even if empty, even if the previous key had no blob | 3548 // This is storing an info, even if empty, even if the previous key had no blob |
| 3504 // info that we know of. It duplicates a bunch of information stored in the | 3549 // info that we know of. It duplicates a bunch of information stored in the |
| 3505 // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the | 3550 // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the |
| 3506 // changes to exists or index keys here. | 3551 // changes to exists or index keys here. |
| 3507 void IndexedDBBackingStore::Transaction::PutBlobInfo( | 3552 void IndexedDBBackingStore::Transaction::PutBlobInfo( |
| 3508 int64 database_id, | 3553 int64 database_id, |
| 3509 int64 object_store_id, | 3554 int64 object_store_id, |
| 3510 const std::string& key, | 3555 const std::string& object_store_data_key, |
| 3511 std::vector<IndexedDBBlobInfo>* blob_info, | 3556 std::vector<IndexedDBBlobInfo>* blob_info, |
| 3512 ScopedVector<webkit_blob::BlobDataHandle>* handles) { | 3557 ScopedVector<webkit_blob::BlobDataHandle>* handles) { |
| 3513 DCHECK_GT(key.size(), 0UL); | 3558 DCHECK_GT(object_store_data_key.size(), 0UL); |
| 3514 if (database_id_ < 0) | 3559 if (database_id_ < 0) |
| 3515 database_id_ = database_id; | 3560 database_id_ = database_id; |
| 3516 DCHECK_EQ(database_id_, database_id); | 3561 DCHECK_EQ(database_id_, database_id); |
| 3517 | 3562 |
| 3518 BlobChangeMap::iterator it = blob_change_map_.find(key); | 3563 BlobChangeMap::iterator it = blob_change_map_.find(object_store_data_key); |
| 3519 BlobChangeRecord* record = NULL; | 3564 BlobChangeRecord* record = NULL; |
| 3520 if (it == blob_change_map_.end()) { | 3565 if (it == blob_change_map_.end()) { |
| 3521 record = new BlobChangeRecord(key, object_store_id); | 3566 record = new BlobChangeRecord(object_store_data_key, object_store_id); |
| 3522 blob_change_map_[key] = record; | 3567 blob_change_map_[object_store_data_key] = record; |
| 3523 } else { | 3568 } else { |
| 3524 record = it->second; | 3569 record = it->second; |
| 3525 } | 3570 } |
| 3526 DCHECK_EQ(record->object_store_id(), object_store_id); | 3571 DCHECK_EQ(record->object_store_id(), object_store_id); |
| 3527 record->SetBlobInfo(blob_info); | 3572 record->SetBlobInfo(blob_info); |
| 3528 record->SetHandles(handles); | 3573 record->SetHandles(handles); |
| 3529 DCHECK(!handles || !handles->size()); | 3574 DCHECK(!handles || !handles->size()); |
| 3530 } | 3575 } |
| 3531 | 3576 |
| 3532 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( | 3577 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( |
| 3533 const GURL& url, | 3578 const GURL& url, |
| 3534 int64_t key) | 3579 int64_t key) |
| 3535 : is_file_(false), url_(url), key_(key) {} | 3580 : is_file_(false), url_(url), key_(key) {} |
| 3536 | 3581 |
| 3537 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( | 3582 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( |
| 3538 const FilePath& file_path, | 3583 const FilePath& file_path, |
| 3539 int64_t key) | 3584 int64_t key) |
| 3540 : is_file_(true), file_path_(file_path), key_(key) {} | 3585 : is_file_(true), file_path_(file_path), key_(key) {} |
| 3541 | 3586 |
| 3542 } // namespace content | 3587 } // namespace content |
| OLD | NEW |