Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Side by Side Diff: content/browser/indexed_db/indexed_db_database.cc

Issue 1074493002: IndexedDB: Added IDBObjectStore.getAll() implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Limiting response size to 10 MB Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698