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_database.h" | 5 #include "content/browser/indexed_db/indexed_db_database.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <limits> | |
| 8 #include <set> | 9 #include <set> |
| 9 | 10 |
| 10 #include "base/auto_reset.h" | 11 #include "base/auto_reset.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/memory/scoped_vector.h" | 14 #include "base/memory/scoped_vector.h" |
| 14 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 16 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 524 void IndexedDBDatabase::Abort(int64 transaction_id, | 525 void IndexedDBDatabase::Abort(int64 transaction_id, |
| 525 const IndexedDBDatabaseError& error) { | 526 const IndexedDBDatabaseError& error) { |
| 526 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); | 527 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); |
| 527 // If the transaction is unknown, then it has already been aborted by the | 528 // If the transaction is unknown, then it has already been aborted by the |
| 528 // backend before this call so it is safe to ignore it. | 529 // backend before this call so it is safe to ignore it. |
| 529 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 530 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 530 if (transaction) | 531 if (transaction) |
| 531 transaction->Abort(error); | 532 transaction->Abort(error); |
| 532 } | 533 } |
| 533 | 534 |
| 535 void IndexedDBDatabase::GetAll(int64 transaction_id, | |
| 536 int64 object_store_id, | |
| 537 scoped_ptr<IndexedDBKeyRange> key_range, | |
| 538 int64 max_count, | |
| 539 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
| 540 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); | |
| 541 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 542 if (!transaction) | |
| 543 return; | |
| 544 | |
| 545 if (!ValidateObjectStoreId(object_store_id)) | |
| 546 return; | |
| 547 | |
| 548 transaction->ScheduleTask( | |
| 549 base::Bind(&IndexedDBDatabase::GetAllOperation, this, object_store_id, | |
| 550 Passed(&key_range), max_count, callbacks)); | |
| 551 } | |
| 552 | |
| 534 void IndexedDBDatabase::Get(int64 transaction_id, | 553 void IndexedDBDatabase::Get(int64 transaction_id, |
| 535 int64 object_store_id, | 554 int64 object_store_id, |
| 536 int64 index_id, | 555 int64 index_id, |
| 537 scoped_ptr<IndexedDBKeyRange> key_range, | 556 scoped_ptr<IndexedDBKeyRange> key_range, |
| 538 bool key_only, | 557 bool key_only, |
| 539 scoped_refptr<IndexedDBCallbacks> callbacks) { | 558 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 540 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); | 559 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); |
| 541 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 560 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 542 if (!transaction) | 561 if (!transaction) |
| 543 return; | 562 return; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 return; | 729 return; |
| 711 } | 730 } |
| 712 if (object_store_metadata.auto_increment && | 731 if (object_store_metadata.auto_increment && |
| 713 !object_store_metadata.key_path.IsNull()) { | 732 !object_store_metadata.key_path.IsNull()) { |
| 714 value.primary_key = *primary_key; | 733 value.primary_key = *primary_key; |
| 715 value.key_path = object_store_metadata.key_path; | 734 value.key_path = object_store_metadata.key_path; |
| 716 } | 735 } |
| 717 callbacks->OnSuccess(&value); | 736 callbacks->OnSuccess(&value); |
| 718 } | 737 } |
| 719 | 738 |
| 739 void IndexedDBDatabase::GetAllOperation( | |
| 740 int64 object_store_id, | |
| 741 scoped_ptr<IndexedDBKeyRange> key_range, | |
| 742 int64 max_count, | |
| 743 scoped_refptr<IndexedDBCallbacks> callbacks, | |
| 744 IndexedDBTransaction* transaction) { | |
| 745 IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id()); | |
| 746 | |
| 747 DCHECK_GE(max_count, 0); | |
| 748 if (!max_count) | |
| 749 max_count = std::numeric_limits<decltype(max_count)>::max(); | |
| 750 | |
| 751 DCHECK(metadata_.object_stores.find(object_store_id) != | |
| 752 metadata_.object_stores.end()); | |
| 753 const IndexedDBObjectStoreMetadata& object_store_metadata = | |
| 754 metadata_.object_stores[object_store_id]; | |
| 755 | |
| 756 leveldb::Status s; | |
| 757 | |
| 758 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; | |
|
jsbell
2015/04/30 17:28:18
Could just call this `cursor` to reduce clutter. N
cmumford
2015/04/30 22:30:12
Done.
| |
| 759 if (key_range->IsEmpty()) { | |
| 760 backing_store_cursor = backing_store_->OpenObjectStoreCursor( | |
| 761 transaction->BackingStoreTransaction(), id(), object_store_id, | |
| 762 *key_range, blink::WebIDBCursorDirectionNext, &s); | |
| 763 } else { | |
| 764 backing_store_cursor = backing_store_->OpenObjectStoreCursor( | |
|
jsbell
2015/04/30 17:28:18
The `else` block looks identical to the `if` block
cmumford
2015/04/30 22:30:12
True that! :$
| |
| 765 transaction->BackingStoreTransaction(), id(), object_store_id, | |
| 766 *key_range, blink::WebIDBCursorDirectionNext, &s); | |
| 767 } | |
| 768 | |
| 769 if (!s.ok()) { | |
| 770 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); | |
| 771 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | |
|
jsbell
2015/04/30 17:28:18
Call callbacks->OnError() here?
| |
| 772 "Internal error in GetAllOperation"); | |
| 773 if (s.IsCorruption()) { | |
| 774 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | |
| 775 error); | |
| 776 } | |
|
jsbell
2015/04/30 17:28:18
Should return at end of !s.ok() block?
cmumford
2015/04/30 22:30:12
Yes, you are correct (on both). Pointing this out
| |
| 777 } | |
| 778 | |
| 779 std::vector<IndexedDBReturnValue> found_values; | |
| 780 if (!backing_store_cursor) { | |
| 781 callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path); | |
| 782 return; | |
| 783 } | |
| 784 | |
| 785 bool did_first_seek = false; | |
| 786 bool generated_key = object_store_metadata.auto_increment && | |
| 787 !object_store_metadata.key_path.IsNull(); | |
| 788 | |
| 789 size_t response_size = 0; | |
| 790 do { | |
| 791 bool cursor_valid; | |
| 792 if (did_first_seek) { | |
| 793 cursor_valid = backing_store_cursor->Continue(&s); | |
| 794 } else { | |
| 795 cursor_valid = backing_store_cursor->FirstSeek(&s); | |
| 796 did_first_seek = true; | |
| 797 } | |
| 798 if (!s.ok()) { | |
| 799 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | |
| 800 "Internal error in GetAllOperation."); | |
| 801 callbacks->OnError(error); | |
| 802 | |
| 803 if (s.IsCorruption()) | |
| 804 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | |
| 805 error); | |
| 806 return; | |
| 807 } | |
| 808 | |
| 809 if (!cursor_valid) | |
| 810 break; | |
| 811 | |
| 812 IndexedDBReturnValue return_value; | |
| 813 return_value.swap(*backing_store_cursor->value()); | |
| 814 | |
| 815 size_t value_estimated_size = return_value.SizeEstimate(); | |
| 816 | |
| 817 if (generated_key) { | |
| 818 return_value.primary_key = backing_store_cursor->primary_key(); | |
| 819 value_estimated_size += return_value.primary_key.size_estimate(); | |
| 820 } | |
| 821 | |
| 822 if (response_size + value_estimated_size > | |
| 823 IPC::Channel::kMaximumMessageSize) { | |
|
jsbell
2015/04/30 17:28:18
Since the estimate is approximate, can you add in
| |
| 824 // TODO(cmumford): Reach this limit in more gracefully (crbug.com/478949) | |
| 825 break; | |
| 826 } | |
| 827 | |
| 828 found_values.push_back(return_value); | |
| 829 response_size += value_estimated_size; | |
| 830 | |
| 831 } while (found_values.size() < static_cast<size_t>(max_count)); | |
| 832 | |
| 833 callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path); | |
| 834 } | |
| 835 | |
| 720 static scoped_ptr<IndexedDBKey> GenerateKey( | 836 static scoped_ptr<IndexedDBKey> GenerateKey( |
| 721 IndexedDBBackingStore* backing_store, | 837 IndexedDBBackingStore* backing_store, |
| 722 IndexedDBTransaction* transaction, | 838 IndexedDBTransaction* transaction, |
| 723 int64 database_id, | 839 int64 database_id, |
| 724 int64 object_store_id) { | 840 int64 object_store_id) { |
| 725 const int64 max_generator_value = | 841 const int64 max_generator_value = |
| 726 9007199254740992LL; // Maximum integer storable as ECMAScript number. | 842 9007199254740992LL; // Maximum integer storable as ECMAScript number. |
| 727 int64 current_number; | 843 int64 current_number; |
| 728 leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( | 844 leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( |
| 729 transaction->BackingStoreTransaction(), | 845 transaction->BackingStoreTransaction(), |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1813 IndexedDBTransaction* transaction) { | 1929 IndexedDBTransaction* transaction) { |
| 1814 DCHECK(!transaction); | 1930 DCHECK(!transaction); |
| 1815 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", | 1931 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", |
| 1816 "txn.id", | 1932 "txn.id", |
| 1817 transaction->id()); | 1933 transaction->id()); |
| 1818 metadata_.version = previous_version; | 1934 metadata_.version = previous_version; |
| 1819 metadata_.int_version = previous_int_version; | 1935 metadata_.int_version = previous_int_version; |
| 1820 } | 1936 } |
| 1821 | 1937 |
| 1822 } // namespace content | 1938 } // namespace content |
| OLD | NEW |