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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/indexed_db/indexed_db_database.cc
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index b72ee73b9a5d275743233d109ab8c44d1a3dcc08..aa17f48a526e87576c0ad056a1142333c41a19fa 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -5,6 +5,7 @@
#include "content/browser/indexed_db/indexed_db_database.h"
#include <math.h>
+#include <limits>
#include <set>
#include "base/auto_reset.h"
@@ -491,6 +492,24 @@ void IndexedDBDatabase::Abort(int64 transaction_id,
transaction->Abort(error);
}
+void IndexedDBDatabase::GetAll(int64 transaction_id,
+ int64 object_store_id,
+ scoped_ptr<IndexedDBKeyRange> key_range,
+ int64 max_count,
+ scoped_refptr<IndexedDBCallbacks> callbacks) {
+ IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id);
+ IndexedDBTransaction* transaction = GetTransaction(transaction_id);
+ if (!transaction)
+ return;
+
+ if (!ValidateObjectStoreId(object_store_id))
+ return;
+
+ transaction->ScheduleTask(
+ base::Bind(&IndexedDBDatabase::GetAllOperation, this, object_store_id,
+ Passed(&key_range), max_count, callbacks));
+}
+
void IndexedDBDatabase::Get(int64 transaction_id,
int64 object_store_id,
int64 index_id,
@@ -677,6 +696,103 @@ void IndexedDBDatabase::GetOperation(
callbacks->OnSuccess(&value);
}
+void IndexedDBDatabase::GetAllOperation(
+ int64 object_store_id,
+ scoped_ptr<IndexedDBKeyRange> key_range,
+ int64 max_count,
+ scoped_refptr<IndexedDBCallbacks> callbacks,
+ IndexedDBTransaction* transaction) {
+ IDB_TRACE1("IndexedDBDatabase::GetAllOperation", "txn.id", transaction->id());
+
+ DCHECK_GE(max_count, 0);
+ if (!max_count)
+ max_count = std::numeric_limits<decltype(max_count)>::max();
+
+ DCHECK(metadata_.object_stores.find(object_store_id) !=
+ metadata_.object_stores.end());
+ const IndexedDBObjectStoreMetadata& object_store_metadata =
+ metadata_.object_stores[object_store_id];
+
+ leveldb::Status s;
+
+ scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
+ if (key_range->IsEmpty()) {
+ backing_store_cursor = backing_store_->OpenObjectStoreCursor(
+ transaction->BackingStoreTransaction(), id(), object_store_id,
+ *key_range, blink::WebIDBCursorDirectionNext, &s);
+ } else {
+ backing_store_cursor = backing_store_->OpenObjectStoreCursor(
+ transaction->BackingStoreTransaction(), id(), object_store_id,
+ *key_range, blink::WebIDBCursorDirectionNext, &s);
+ }
+
+ if (!s.ok()) {
+ DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
+ IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
+ "Internal error in GetAllOperation");
+ if (s.IsCorruption()) {
+ factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
+ error);
+ }
+ }
+
+ std::vector<IndexedDBReturnValue> found_values;
+ if (!backing_store_cursor) {
+ callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path);
+ return;
+ }
+
+ bool did_first_seek = false;
+ bool generated_key = object_store_metadata.auto_increment &&
+ !object_store_metadata.key_path.IsNull();
+
+ 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!
+ int64_t response_size = 0;
+ do {
+ bool cursor_valid;
+ if (did_first_seek) {
+ cursor_valid = backing_store_cursor->Continue(&s);
+ } else {
+ cursor_valid = backing_store_cursor->FirstSeek(&s);
+ did_first_seek = true;
+ }
+ if (!s.ok()) {
+ IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
+ "Internal error in GetAllOperation.");
+ callbacks->OnError(error);
+
+ if (s.IsCorruption())
+ factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
+ error);
+ return;
+ }
+
+ if (!cursor_valid)
+ break;
+
+ IndexedDBReturnValue return_value;
+ return_value.swap(*backing_store_cursor->value());
+
+ size_t value_estimated_size = return_value.SizeEstimate();
+
+ if (generated_key) {
+ return_value.primary_key = backing_store_cursor->primary_key();
+ value_estimated_size += return_value.primary_key.size_estimate();
+ }
+
+ if (response_size + value_estimated_size > max_size_estimate) {
+ // TODO(cmumford): Caller needs to know that the response was truncated.
+ break;
+ }
+
+ 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.
+ response_size += value_estimated_size;
+
+ } while (found_values.size() < static_cast<size_t>(max_count));
+
+ callbacks->OnSuccessArray(&found_values, object_store_metadata.key_path);
+}
+
static scoped_ptr<IndexedDBKey> GenerateKey(
IndexedDBBackingStore* backing_store,
IndexedDBTransaction* transaction,

Powered by Google App Engine
This is Rietveld 408576698