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/stl_util.h" | 15 #include "base/stl_util.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "content/browser/indexed_db/indexed_db_blob_info.h" | 18 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 void IndexedDBDatabase::Abort(int64 transaction_id, | 485 void IndexedDBDatabase::Abort(int64 transaction_id, |
| 485 const IndexedDBDatabaseError& error) { | 486 const IndexedDBDatabaseError& error) { |
| 486 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); | 487 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); |
| 487 // If the transaction is unknown, then it has already been aborted by the | 488 // If the transaction is unknown, then it has already been aborted by the |
| 488 // backend before this call so it is safe to ignore it. | 489 // backend before this call so it is safe to ignore it. |
| 489 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 490 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 490 if (transaction) | 491 if (transaction) |
| 491 transaction->Abort(error); | 492 transaction->Abort(error); |
| 492 } | 493 } |
| 493 | 494 |
| 495 void IndexedDBDatabase::GetAll(int64 transaction_id, | |
| 496 int64 object_store_id, | |
| 497 scoped_ptr<IndexedDBKeyRange> key_range, | |
| 498 int64 max_count, | |
| 499 scoped_refptr<IndexedDBCallbacks> callbacks) { | |
| 500 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); | |
| 501 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 502 if (!transaction) | |
| 503 return; | |
| 504 | |
| 505 if (!ValidateObjectStoreId(object_store_id)) | |
| 506 return; | |
| 507 | |
| 508 transaction->ScheduleTask( | |
| 509 base::Bind(&IndexedDBDatabase::GetAllOperation, this, object_store_id, | |
| 510 Passed(&key_range), max_count, callbacks)); | |
| 511 } | |
| 512 | |
| 494 void IndexedDBDatabase::Get(int64 transaction_id, | 513 void IndexedDBDatabase::Get(int64 transaction_id, |
| 495 int64 object_store_id, | 514 int64 object_store_id, |
| 496 int64 index_id, | 515 int64 index_id, |
| 497 scoped_ptr<IndexedDBKeyRange> key_range, | 516 scoped_ptr<IndexedDBKeyRange> key_range, |
| 498 bool key_only, | 517 bool key_only, |
| 499 scoped_refptr<IndexedDBCallbacks> callbacks) { | 518 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 500 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); | 519 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); |
| 501 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 520 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 502 if (!transaction) | 521 if (!transaction) |
| 503 return; | 522 return; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 670 return; | 689 return; |
| 671 } | 690 } |
| 672 if (object_store_metadata.auto_increment && | 691 if (object_store_metadata.auto_increment && |
| 673 !object_store_metadata.key_path.IsNull()) { | 692 !object_store_metadata.key_path.IsNull()) { |
| 674 value.primary_key = *primary_key; | 693 value.primary_key = *primary_key; |
| 675 value.key_path = object_store_metadata.key_path; | 694 value.key_path = object_store_metadata.key_path; |
| 676 } | 695 } |
| 677 callbacks->OnSuccess(&value); | 696 callbacks->OnSuccess(&value); |
| 678 } | 697 } |
| 679 | 698 |
| 699 void IndexedDBDatabase::GetAllOperation( | |
| 700 int64 object_store_id, | |
| 701 scoped_ptr<IndexedDBKeyRange> key_range, | |
| 702 int64 max_count, | |
| 703 scoped_refptr<IndexedDBCallbacks> callbacks, | |
| 704 IndexedDBTransaction* transaction) { | |
| 705 IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id()); | |
| 706 | |
| 707 DCHECK_GE(max_count, 0); | |
| 708 if (!max_count) | |
| 709 max_count = std::numeric_limits<decltype(max_count)>::max(); | |
| 710 | |
| 711 DCHECK(metadata_.object_stores.find(object_store_id) != | |
| 712 metadata_.object_stores.end()); | |
| 713 const IndexedDBObjectStoreMetadata& object_store_metadata = | |
| 714 metadata_.object_stores[object_store_id]; | |
| 715 | |
| 716 leveldb::Status s; | |
| 717 | |
| 718 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; | |
| 719 if (key_range->IsEmpty()) { | |
| 720 backing_store_cursor = backing_store_->OpenObjectStoreCursor( | |
| 721 transaction->BackingStoreTransaction(), id(), object_store_id, | |
| 722 *key_range, blink::WebIDBCursorDirectionNext, &s); | |
| 723 } else { | |
| 724 backing_store_cursor = backing_store_->OpenObjectStoreCursor( | |
| 725 transaction->BackingStoreTransaction(), id(), object_store_id, | |
| 726 *key_range, blink::WebIDBCursorDirectionNext, &s); | |
| 727 } | |
| 728 | |
| 729 if (!s.ok()) { | |
| 730 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); | |
| 731 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | |
| 732 "Internal error in GetAllOperation"); | |
| 733 if (s.IsCorruption()) { | |
| 734 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | |
| 735 error); | |
| 736 } | |
| 737 } | |
| 738 | |
| 739 std::vector<IndexedDBReturnValue> found_values; | |
| 740 if (!backing_store_cursor) { | |
| 741 callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path); | |
| 742 return; | |
| 743 } | |
| 744 | |
| 745 bool did_first_seek = false; | |
| 746 bool generated_key = object_store_metadata.auto_increment && | |
| 747 !object_store_metadata.key_path.IsNull(); | |
| 748 | |
| 749 const size_t max_size_estimate = 10 * 1024 * 1024; | |
|
jsbell
2015/04/28 00:06:53
Can you add a TODO here to replace this with IPC-b
cmumford
2015/04/29 23:17:46
Any reason why I shouldn't just use IPC::Channel::
jsbell
2015/04/30 00:01:15
Doing the full-blown IPC-based fix is fine, too!
| |
| 750 int64_t response_size = 0; | |
| 751 do { | |
| 752 bool cursor_valid; | |
| 753 if (did_first_seek) { | |
| 754 cursor_valid = backing_store_cursor->Continue(&s); | |
| 755 } else { | |
| 756 cursor_valid = backing_store_cursor->FirstSeek(&s); | |
| 757 did_first_seek = true; | |
| 758 } | |
| 759 if (!s.ok()) { | |
| 760 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | |
| 761 "Internal error in GetAllOperation."); | |
| 762 callbacks->OnError(error); | |
| 763 | |
| 764 if (s.IsCorruption()) | |
| 765 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(), | |
| 766 error); | |
| 767 return; | |
| 768 } | |
| 769 | |
| 770 if (!cursor_valid) | |
| 771 break; | |
| 772 | |
| 773 IndexedDBReturnValue return_value; | |
| 774 return_value.swap(*backing_store_cursor->value()); | |
| 775 | |
| 776 size_t value_estimated_size = return_value.SizeEstimate(); | |
| 777 | |
| 778 if (generated_key) { | |
| 779 return_value.primary_key = backing_store_cursor->primary_key(); | |
| 780 value_estimated_size += return_value.primary_key.size_estimate(); | |
| 781 } | |
| 782 | |
| 783 if (response_size + value_estimated_size > max_size_estimate) { | |
| 784 // TODO(cmumford): Caller needs to know that the response was truncated. | |
| 785 break; | |
| 786 } | |
| 787 | |
| 788 found_values.push_back(return_value); | |
|
jsbell
2015/04/28 00:06:54
So here if the first value found is > 10MB there w
cmumford
2015/04/29 23:17:46
Yes, if I use IPC then we should be good (right),
jsbell
2015/04/30 00:01:15
Acknowledged.
| |
| 789 response_size += value_estimated_size; | |
| 790 | |
| 791 } while (found_values.size() < static_cast<size_t>(max_count)); | |
| 792 | |
| 793 callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path); | |
| 794 } | |
| 795 | |
| 680 static scoped_ptr<IndexedDBKey> GenerateKey( | 796 static scoped_ptr<IndexedDBKey> GenerateKey( |
| 681 IndexedDBBackingStore* backing_store, | 797 IndexedDBBackingStore* backing_store, |
| 682 IndexedDBTransaction* transaction, | 798 IndexedDBTransaction* transaction, |
| 683 int64 database_id, | 799 int64 database_id, |
| 684 int64 object_store_id) { | 800 int64 object_store_id) { |
| 685 const int64 max_generator_value = | 801 const int64 max_generator_value = |
| 686 9007199254740992LL; // Maximum integer storable as ECMAScript number. | 802 9007199254740992LL; // Maximum integer storable as ECMAScript number. |
| 687 int64 current_number; | 803 int64 current_number; |
| 688 leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( | 804 leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( |
| 689 transaction->BackingStoreTransaction(), | 805 transaction->BackingStoreTransaction(), |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1773 IndexedDBTransaction* transaction) { | 1889 IndexedDBTransaction* transaction) { |
| 1774 DCHECK(!transaction); | 1890 DCHECK(!transaction); |
| 1775 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", | 1891 IDB_TRACE1("IndexedDBDatabase::VersionChangeAbortOperation", |
| 1776 "txn.id", | 1892 "txn.id", |
| 1777 transaction->id()); | 1893 transaction->id()); |
| 1778 metadata_.version = previous_version; | 1894 metadata_.version = previous_version; |
| 1779 metadata_.int_version = previous_int_version; | 1895 metadata_.int_version = previous_int_version; |
| 1780 } | 1896 } |
| 1781 | 1897 |
| 1782 } // namespace content | 1898 } // namespace content |
| OLD | NEW |