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->Clone().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& target_map = backing_store_->incognito_blob_map_; |
| 3437 BlobChangeMap::iterator iter; |
| 3438 for (iter = blob_change_map_.begin(); iter != blob_change_map_.end(); |
| 3439 ++iter) { |
| 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::Clone() 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 |