| 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" |
| 18 #include "content/browser/indexed_db/indexed_db_blob_info.h" | 19 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
| 19 #include "content/browser/indexed_db/indexed_db_connection.h" | 20 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 20 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 21 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 21 #include "content/browser/indexed_db/indexed_db_cursor.h" | 22 #include "content/browser/indexed_db/indexed_db_cursor.h" |
| 22 #include "content/browser/indexed_db/indexed_db_factory.h" | 23 #include "content/browser/indexed_db/indexed_db_factory.h" |
| 23 #include "content/browser/indexed_db/indexed_db_index_writer.h" | 24 #include "content/browser/indexed_db/indexed_db_index_writer.h" |
| 24 #include "content/browser/indexed_db/indexed_db_pending_connection.h" | 25 #include "content/browser/indexed_db/indexed_db_pending_connection.h" |
| 25 #include "content/browser/indexed_db/indexed_db_return_value.h" | 26 #include "content/browser/indexed_db/indexed_db_return_value.h" |
| 26 #include "content/browser/indexed_db/indexed_db_tracing.h" | 27 #include "content/browser/indexed_db/indexed_db_tracing.h" |
| 27 #include "content/browser/indexed_db/indexed_db_transaction.h" | 28 #include "content/browser/indexed_db/indexed_db_transaction.h" |
| 28 #include "content/browser/indexed_db/indexed_db_value.h" | 29 #include "content/browser/indexed_db/indexed_db_value.h" |
| 30 #include "content/common/indexed_db/indexed_db_constants.h" |
| 29 #include "content/common/indexed_db/indexed_db_key_path.h" | 31 #include "content/common/indexed_db/indexed_db_key_path.h" |
| 30 #include "content/common/indexed_db/indexed_db_key_range.h" | 32 #include "content/common/indexed_db/indexed_db_key_range.h" |
| 31 #include "storage/browser/blob/blob_data_handle.h" | 33 #include "storage/browser/blob/blob_data_handle.h" |
| 32 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" | 34 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" |
| 33 #include "third_party/leveldatabase/env_chromium.h" | 35 #include "third_party/leveldatabase/env_chromium.h" |
| 34 | 36 |
| 35 using base::ASCIIToUTF16; | 37 using base::ASCIIToUTF16; |
| 36 using base::Int64ToString16; | 38 using base::Int64ToString16; |
| 37 using blink::WebIDBKeyTypeNumber; | 39 using blink::WebIDBKeyTypeNumber; |
| 38 | 40 |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 void IndexedDBDatabase::Abort(int64 transaction_id, | 526 void IndexedDBDatabase::Abort(int64 transaction_id, |
| 525 const IndexedDBDatabaseError& error) { | 527 const IndexedDBDatabaseError& error) { |
| 526 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); | 528 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); |
| 527 // If the transaction is unknown, then it has already been aborted by the | 529 // 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. | 530 // backend before this call so it is safe to ignore it. |
| 529 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 531 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 530 if (transaction) | 532 if (transaction) |
| 531 transaction->Abort(error); | 533 transaction->Abort(error); |
| 532 } | 534 } |
| 533 | 535 |
| 536 void IndexedDBDatabase::GetAll(int64 transaction_id, |
| 537 int64 object_store_id, |
| 538 scoped_ptr<IndexedDBKeyRange> key_range, |
| 539 int64 max_count, |
| 540 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 541 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); |
| 542 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 543 if (!transaction) |
| 544 return; |
| 545 |
| 546 if (!ValidateObjectStoreId(object_store_id)) |
| 547 return; |
| 548 |
| 549 transaction->ScheduleTask( |
| 550 base::Bind(&IndexedDBDatabase::GetAllOperation, this, object_store_id, |
| 551 Passed(&key_range), max_count, callbacks)); |
| 552 } |
| 553 |
| 534 void IndexedDBDatabase::Get(int64 transaction_id, | 554 void IndexedDBDatabase::Get(int64 transaction_id, |
| 535 int64 object_store_id, | 555 int64 object_store_id, |
| 536 int64 index_id, | 556 int64 index_id, |
| 537 scoped_ptr<IndexedDBKeyRange> key_range, | 557 scoped_ptr<IndexedDBKeyRange> key_range, |
| 538 bool key_only, | 558 bool key_only, |
| 539 scoped_refptr<IndexedDBCallbacks> callbacks) { | 559 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 540 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); | 560 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); |
| 541 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 561 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 542 if (!transaction) | 562 if (!transaction) |
| 543 return; | 563 return; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 return; | 730 return; |
| 711 } | 731 } |
| 712 if (object_store_metadata.auto_increment && | 732 if (object_store_metadata.auto_increment && |
| 713 !object_store_metadata.key_path.IsNull()) { | 733 !object_store_metadata.key_path.IsNull()) { |
| 714 value.primary_key = *primary_key; | 734 value.primary_key = *primary_key; |
| 715 value.key_path = object_store_metadata.key_path; | 735 value.key_path = object_store_metadata.key_path; |
| 716 } | 736 } |
| 717 callbacks->OnSuccess(&value); | 737 callbacks->OnSuccess(&value); |
| 718 } | 738 } |
| 719 | 739 |
| 740 void IndexedDBDatabase::GetAllOperation( |
| 741 int64 object_store_id, |
| 742 scoped_ptr<IndexedDBKeyRange> key_range, |
| 743 int64 max_count, |
| 744 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 745 IndexedDBTransaction* transaction) { |
| 746 IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id()); |
| 747 |
| 748 DCHECK_GE(max_count, 0); |
| 749 if (!max_count) |
| 750 max_count = std::numeric_limits<decltype(max_count)>::max(); |
| 751 |
| 752 DCHECK(metadata_.object_stores.find(object_store_id) != |
| 753 metadata_.object_stores.end()); |
| 754 const IndexedDBObjectStoreMetadata& object_store_metadata = |
| 755 metadata_.object_stores[object_store_id]; |
| 756 |
| 757 leveldb::Status s; |
| 758 |
| 759 scoped_ptr<IndexedDBBackingStore::Cursor> cursor = |
| 760 backing_store_->OpenObjectStoreCursor( |
| 761 transaction->BackingStoreTransaction(), id(), object_store_id, |
| 762 *key_range, blink::WebIDBCursorDirectionNext, &s); |
| 763 |
| 764 if (!s.ok()) { |
| 765 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); |
| 766 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 767 "Internal error in GetAllOperation"); |
| 768 callbacks->OnError(error); |
| 769 if (s.IsCorruption()) { |
| 770 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), |
| 771 error); |
| 772 } |
| 773 return; |
| 774 } |
| 775 |
| 776 std::vector<IndexedDBReturnValue> found_values; |
| 777 if (!cursor) { |
| 778 callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path); |
| 779 return; |
| 780 } |
| 781 |
| 782 bool did_first_seek = false; |
| 783 bool generated_key = object_store_metadata.auto_increment && |
| 784 !object_store_metadata.key_path.IsNull(); |
| 785 |
| 786 size_t response_size = kMaxIDBMessageOverhead; |
| 787 do { |
| 788 bool cursor_valid; |
| 789 if (did_first_seek) { |
| 790 cursor_valid = cursor->Continue(&s); |
| 791 } else { |
| 792 cursor_valid = cursor->FirstSeek(&s); |
| 793 did_first_seek = true; |
| 794 } |
| 795 if (!s.ok()) { |
| 796 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 797 "Internal error in GetAllOperation."); |
| 798 callbacks->OnError(error); |
| 799 |
| 800 if (s.IsCorruption()) |
| 801 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), |
| 802 error); |
| 803 return; |
| 804 } |
| 805 |
| 806 if (!cursor_valid) |
| 807 break; |
| 808 |
| 809 IndexedDBReturnValue return_value; |
| 810 return_value.swap(*cursor->value()); |
| 811 |
| 812 size_t value_estimated_size = return_value.SizeEstimate(); |
| 813 |
| 814 if (generated_key) { |
| 815 return_value.primary_key = cursor->primary_key(); |
| 816 value_estimated_size += return_value.primary_key.size_estimate(); |
| 817 } |
| 818 |
| 819 if (response_size + value_estimated_size > |
| 820 IPC::Channel::kMaximumMessageSize) { |
| 821 // TODO(cmumford): Reach this limit in more gracefully (crbug.com/478949) |
| 822 break; |
| 823 } |
| 824 |
| 825 found_values.push_back(return_value); |
| 826 response_size += value_estimated_size; |
| 827 } while (found_values.size() < static_cast<size_t>(max_count)); |
| 828 |
| 829 callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path); |
| 830 } |
| 831 |
| 720 static scoped_ptr<IndexedDBKey> GenerateKey( | 832 static scoped_ptr<IndexedDBKey> GenerateKey( |
| 721 IndexedDBBackingStore* backing_store, | 833 IndexedDBBackingStore* backing_store, |
| 722 IndexedDBTransaction* transaction, | 834 IndexedDBTransaction* transaction, |
| 723 int64 database_id, | 835 int64 database_id, |
| 724 int64 object_store_id) { | 836 int64 object_store_id) { |
| 725 const int64 max_generator_value = | 837 const int64 max_generator_value = |
| 726 9007199254740992LL; // Maximum integer storable as ECMAScript number. | 838 9007199254740992LL; // Maximum integer storable as ECMAScript number. |
| 727 int64 current_number; | 839 int64 current_number; |
| 728 leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( | 840 leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( |
| 729 transaction->BackingStoreTransaction(), | 841 transaction->BackingStoreTransaction(), |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 IndexedDBTransaction* transaction) { | 1925 IndexedDBTransaction* transaction) { |
| 1814 DCHECK(!transaction); | 1926 DCHECK(!transaction); |
| 1815 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", | 1927 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", |
| 1816 "txn.id", | 1928 "txn.id", |
| 1817 transaction->id()); | 1929 transaction->id()); |
| 1818 metadata_.version = previous_version; | 1930 metadata_.version = previous_version; |
| 1819 metadata_.int_version = previous_int_version; | 1931 metadata_.int_version = previous_int_version; |
| 1820 } | 1932 } |
| 1821 | 1933 |
| 1822 } // namespace content | 1934 } // namespace content |
| OLD | NEW |