summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcmumford <cmumford@chromium.org>2015-05-14 07:50:39 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-14 14:50:46 +0000
commitb86405eb7d5712e42f96012724b975fbad6a74bb (patch)
tree06018d3938a02dc53c28cf8f9875b6d8044202bb
parent9bea0b509c9ef43fb6585fba6070a93b58499333 (diff)
downloadchromium_src-b86405eb7d5712e42f96012724b975fbad6a74bb.zip
chromium_src-b86405eb7d5712e42f96012724b975fbad6a74bb.tar.gz
chromium_src-b86405eb7d5712e42f96012724b975fbad6a74bb.tar.bz2
IndexedDB: Added IDBObjectStore.getAll() implementation.
This is the experimental IDBObjectStore.getAll implementation for retrieving multiple values in a single request as proposed in https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures In order to use run Chrome with: --enable-experimental-web-platform-features BUG=457450 Review URL: https://codereview.chromium.org/1074493002 Cr-Commit-Position: refs/heads/master@{#329848}
-rw-r--r--content/browser/indexed_db/indexed_db_callbacks.cc61
-rw-r--r--content/browser/indexed_db/indexed_db_callbacks.h4
-rw-r--r--content/browser/indexed_db/indexed_db_cursor.cc1
-rw-r--r--content/browser/indexed_db/indexed_db_database.cc112
-rw-r--r--content/browser/indexed_db/indexed_db_database.h10
-rw-r--r--content/browser/indexed_db/indexed_db_dispatcher_host.cc18
-rw-r--r--content/browser/indexed_db/indexed_db_dispatcher_host.h2
-rw-r--r--content/child/indexed_db/indexed_db_dispatcher.cc74
-rw-r--r--content/child/indexed_db/indexed_db_dispatcher.h9
-rw-r--r--content/child/indexed_db/indexed_db_dispatcher_unittest.cc3
-rw-r--r--content/child/indexed_db/webidbdatabase_impl.cc19
-rw-r--r--content/child/indexed_db/webidbdatabase_impl.h7
-rw-r--r--content/common/indexed_db/indexed_db_constants.h2
-rw-r--r--content/common/indexed_db/indexed_db_key_range.cc6
-rw-r--r--content/common/indexed_db/indexed_db_key_range.h1
-rw-r--r--content/common/indexed_db/indexed_db_messages.h29
16 files changed, 347 insertions, 11 deletions
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc
index aa54973..bfd0a8a 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -285,6 +285,22 @@ static void BlobLookupForCursorPrefetch(
new IndexedDBMsg_CallbacksSuccessCursorPrefetch(*params));
}
+static void BlobLookupForGetAll(
+ IndexedDBMsg_CallbacksSuccessArray_Params* params,
+ scoped_refptr<IndexedDBDispatcherHost> dispatcher_host,
+ const std::vector<IndexedDBReturnValue>& values) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_EQ(values.size(), params->values.size());
+
+ for (size_t i = 0; i < values.size(); ++i) {
+ if (!CreateAllBlobs(values[i].blob_info,
+ &params->values[i].blob_or_file_info, dispatcher_host))
+ return;
+ }
+
+ dispatcher_host->Send(new IndexedDBMsg_CallbacksSuccessArray(*params));
+}
+
static void FillInBlobData(
const std::vector<IndexedDBBlobInfo>& blob_info,
std::vector<IndexedDBMsg_BlobOrFileInfo>* blob_or_file_info) {
@@ -504,6 +520,51 @@ void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) {
dispatcher_host_ = NULL;
}
+void IndexedDBCallbacks::OnSuccessArray(
+ std::vector<IndexedDBReturnValue>* values,
+ const IndexedDBKeyPath& key_path) {
+ DCHECK(dispatcher_host_.get());
+
+ DCHECK_EQ(kNoTransaction, host_transaction_id_);
+ DCHECK_EQ(kNoDatabase, ipc_database_id_);
+ DCHECK_EQ(kNoDatabaseCallbacks, ipc_database_callbacks_id_);
+ DCHECK_EQ(blink::WebIDBDataLossNone, data_loss_);
+
+ scoped_ptr<IndexedDBMsg_CallbacksSuccessArray_Params> params(
+ new IndexedDBMsg_CallbacksSuccessArray_Params());
+ params->ipc_thread_id = ipc_thread_id_;
+ params->ipc_callbacks_id = ipc_callbacks_id_;
+ params->values.resize(values->size());
+
+ bool found_blob_info = false;
+ for (size_t i = 0; i < values->size(); ++i) {
+ IndexedDBMsg_ReturnValue& pvalue = params->values[i];
+ IndexedDBReturnValue& value = (*values)[i];
+ pvalue.bits.swap(value.bits);
+ if (!value.blob_info.empty()) {
+ found_blob_info = true;
+ FillInBlobData(value.blob_info, &pvalue.blob_or_file_info);
+ for (const auto& blob_info : value.blob_info) {
+ if (!blob_info.mark_used_callback().is_null())
+ blob_info.mark_used_callback().Run();
+ }
+ }
+ pvalue.primary_key = value.primary_key;
+ pvalue.key_path = key_path;
+ }
+
+ if (found_blob_info) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(BlobLookupForGetAll, base::Owned(params.release()),
+ dispatcher_host_, *values));
+ } else {
+ dispatcher_host_->Send(
+ new IndexedDBMsg_CallbacksSuccessArray(*params.get()));
+ }
+ dispatcher_host_ = NULL;
+}
+
void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
DCHECK(dispatcher_host_.get());
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h
index 7083bd6..ed61f79 100644
--- a/content/browser/indexed_db/indexed_db_callbacks.h
+++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -90,6 +90,10 @@ class CONTENT_EXPORT IndexedDBCallbacks
// IndexedDBCursor::Advance
virtual void OnSuccess(IndexedDBReturnValue* value);
+ // IndexedDBDatabase::GetAll
+ virtual void OnSuccessArray(std::vector<IndexedDBReturnValue>* values,
+ const IndexedDBKeyPath& key_path);
+
// IndexedDBDatabase::Put / IndexedDBCursor::Update
virtual void OnSuccess(const IndexedDBKey& key);
diff --git a/content/browser/indexed_db/indexed_db_cursor.cc b/content/browser/indexed_db/indexed_db_cursor.cc
index 63ef949..7172dab 100644
--- a/content/browser/indexed_db/indexed_db_cursor.cc
+++ b/content/browser/indexed_db/indexed_db_cursor.cc
@@ -121,6 +121,7 @@ void IndexedDBCursor::CursorPrefetchIterationOperation(
std::vector<IndexedDBValue> found_values;
saved_cursor_.reset();
+ // TODO(cmumford): Use IPC::Channel::kMaximumMessageSize
const size_t max_size_estimate = 10 * 1024 * 1024;
size_t size_estimate = 0;
leveldb::Status s;
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index fe8d8b2..6fbc77f 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"
@@ -26,6 +27,7 @@
#include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/indexed_db_value.h"
+#include "content/common/indexed_db/indexed_db_constants.h"
#include "content/common/indexed_db/indexed_db_key_path.h"
#include "content/common/indexed_db/indexed_db_key_range.h"
#include "storage/browser/blob/blob_data_handle.h"
@@ -531,6 +533,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,
@@ -717,6 +737,98 @@ 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> 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");
+ callbacks->OnError(error);
+ if (s.IsCorruption()) {
+ factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
+ error);
+ }
+ return;
+ }
+
+ std::vector<IndexedDBReturnValue> found_values;
+ if (!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();
+
+ size_t response_size = kMaxIDBMessageOverhead;
+ do {
+ bool cursor_valid;
+ if (did_first_seek) {
+ cursor_valid = cursor->Continue(&s);
+ } else {
+ cursor_valid = 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(*cursor->value());
+
+ size_t value_estimated_size = return_value.SizeEstimate();
+
+ if (generated_key) {
+ return_value.primary_key = cursor->primary_key();
+ value_estimated_size += return_value.primary_key.size_estimate();
+ }
+
+ if (response_size + value_estimated_size >
+ IPC::Channel::kMaximumMessageSize) {
+ // TODO(cmumford): Reach this limit in more gracefully (crbug.com/478949)
+ break;
+ }
+
+ found_values.push_back(return_value);
+ 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,
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index a0390ce..ee941db 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -122,6 +122,11 @@ class CONTENT_EXPORT IndexedDBDatabase
scoped_ptr<IndexedDBKeyRange> key_range,
bool key_only,
scoped_refptr<IndexedDBCallbacks> callbacks);
+ void GetAll(int64 transaction_id,
+ int64 object_store_id,
+ scoped_ptr<IndexedDBKeyRange> key_range,
+ int64 max_count,
+ scoped_refptr<IndexedDBCallbacks> callbacks);
void Put(int64 transaction_id,
int64 object_store_id,
IndexedDBValue* value,
@@ -200,6 +205,11 @@ class CONTENT_EXPORT IndexedDBDatabase
indexed_db::CursorType cursor_type,
scoped_refptr<IndexedDBCallbacks> callbacks,
IndexedDBTransaction* transaction);
+ void GetAllOperation(int64 object_store_id,
+ scoped_ptr<IndexedDBKeyRange> key_range,
+ int64 max_count,
+ scoped_refptr<IndexedDBCallbacks> callbacks,
+ IndexedDBTransaction* transaction);
struct PutOperationParams;
void PutOperation(scoped_ptr<PutOperationParams> params,
IndexedDBTransaction* transaction);
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
index 9119c51..5284af0 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -508,6 +508,7 @@ bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
OnVersionChangeIgnored)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDestroyed, OnDestroyed)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseGet, OnGet)
+ IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseGetAll, OnGetAll)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabasePut, OnPutWrapper)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexKeys, OnSetIndexKeys)
IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexesReady,
@@ -646,6 +647,23 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGet(
callbacks);
}
+void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGetAll(
+ const IndexedDBHostMsg_DatabaseGetAll_Params& params) {
+ DCHECK(
+ parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
+ IndexedDBConnection* connection =
+ parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
+ if (!connection || !connection->IsConnected())
+ return;
+
+ scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
+ parent_, params.ipc_thread_id, params.ipc_callbacks_id));
+ connection->database()->GetAll(
+ parent_->HostTransactionId(params.transaction_id), params.object_store_id,
+ make_scoped_ptr(new IndexedDBKeyRange(params.key_range)),
+ params.max_count, callbacks);
+}
+
void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPutWrapper(
const IndexedDBHostMsg_DatabasePut_Params& params) {
std::vector<storage::BlobDataHandle*> handles;
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.h b/content/browser/indexed_db/indexed_db_dispatcher_host.h
index eb727d152..b576a46 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host.h
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -26,6 +26,7 @@ struct IndexedDBHostMsg_DatabaseCreateObjectStore_Params;
struct IndexedDBHostMsg_DatabaseCreateTransaction_Params;
struct IndexedDBHostMsg_DatabaseDeleteRange_Params;
struct IndexedDBHostMsg_DatabaseGet_Params;
+struct IndexedDBHostMsg_DatabaseGetAll_Params;
struct IndexedDBHostMsg_DatabaseOpenCursor_Params;
struct IndexedDBHostMsg_DatabasePut_Params;
struct IndexedDBHostMsg_DatabaseSetIndexKeys_Params;
@@ -163,6 +164,7 @@ class IndexedDBDispatcherHost : public BrowserMessageFilter {
void OnDestroyed(int32 ipc_database_id);
void OnGet(const IndexedDBHostMsg_DatabaseGet_Params& params);
+ void OnGetAll(const IndexedDBHostMsg_DatabaseGetAll_Params& params);
// OnPutWrapper starts on the IO thread so that it can grab BlobDataHandles
// before posting to the IDB TaskRunner for the rest of the job.
void OnPutWrapper(const IndexedDBHostMsg_DatabasePut_Params& params);
diff --git a/content/child/indexed_db/indexed_db_dispatcher.cc b/content/child/indexed_db/indexed_db_dispatcher.cc
index 12a4d5b..5e524e7 100644
--- a/content/child/indexed_db/indexed_db_dispatcher.cc
+++ b/content/child/indexed_db/indexed_db_dispatcher.cc
@@ -20,6 +20,7 @@
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCallbacks.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseError.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h"
+#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBValue.h"
using blink::WebBlobInfo;
using blink::WebData;
@@ -30,6 +31,7 @@ using blink::WebIDBDatabaseCallbacks;
using blink::WebIDBDatabaseError;
using blink::WebIDBKey;
using blink::WebIDBMetadata;
+using blink::WebIDBValue;
using blink::WebString;
using blink::WebVector;
using base::ThreadLocalPointer;
@@ -45,7 +47,6 @@ IndexedDBDispatcher* const kHasBeenDeleted =
} // unnamed namespace
-const size_t kMaxIDBMessageOverhead = 1024 * 1024; // 1MB; arbitrarily chosen.
const size_t kMaxIDBValueSizeInBytes =
IPC::Channel::kMaximumMessageSize - kMaxIDBMessageOverhead;
@@ -143,6 +144,7 @@ void IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) {
OnSuccessIndexedDBKey)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessStringList,
OnSuccessStringList)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessArray, OnSuccessArray)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessValue, OnSuccessValue)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessInteger, OnSuccessInteger)
IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessUndefined,
@@ -323,6 +325,24 @@ void IndexedDBDispatcher::RequestIDBDatabaseGet(
Send(new IndexedDBHostMsg_DatabaseGet(params));
}
+void IndexedDBDispatcher::RequestIDBDatabaseGetAll(
+ int32 ipc_database_id,
+ int64 transaction_id,
+ int64 object_store_id,
+ const IndexedDBKeyRange& key_range,
+ int64 max_count,
+ WebIDBCallbacks* callbacks) {
+ ResetCursorPrefetchCaches(transaction_id, kAllCursors);
+ IndexedDBHostMsg_DatabaseGetAll_Params params;
+ init_params(&params, callbacks);
+ params.ipc_database_id = ipc_database_id;
+ params.transaction_id = transaction_id;
+ params.object_store_id = object_store_id;
+ params.key_range = key_range;
+ params.max_count = max_count;
+ Send(new IndexedDBHostMsg_DatabaseGetAll(params));
+}
+
void IndexedDBDispatcher::RequestIDBDatabasePut(
int32 ipc_database_id,
int64 transaction_id,
@@ -522,6 +542,30 @@ void IndexedDBDispatcher::OnSuccessStringList(
pending_callbacks_.Remove(ipc_callbacks_id);
}
+static void PrepareWebValue(const IndexedDBMsg_ReturnValue& value,
+ WebIDBValue* web_value) {
+ if (value.bits.empty())
+ return;
+
+ web_value->data.assign(&*value.bits.begin(), value.bits.size());
+ blink::WebVector<WebBlobInfo> local_blob_info(value.blob_or_file_info.size());
+ for (size_t i = 0; i < value.blob_or_file_info.size(); ++i) {
+ const IndexedDBMsg_BlobOrFileInfo& info = value.blob_or_file_info[i];
+ if (info.is_file) {
+ local_blob_info[i] = WebBlobInfo(
+ WebString::fromUTF8(info.uuid.c_str()), info.file_path,
+ info.file_name, info.mime_type, info.last_modified, info.size);
+ } else {
+ local_blob_info[i] = WebBlobInfo(WebString::fromUTF8(info.uuid.c_str()),
+ info.mime_type, info.size);
+ }
+ }
+
+ web_value->webBlobInfo.swap(local_blob_info);
+ web_value->primaryKey = WebIDBKeyBuilder::Build(value.primary_key);
+ web_value->keyPath = WebIDBKeyPathBuilder::Build(value.key_path);
+}
+
static void PrepareWebValueAndBlobInfo(
const IndexedDBMsg_Value& value,
WebData* web_value,
@@ -548,6 +592,19 @@ static void PrepareWebValueAndBlobInfo(
web_blob_info->swap(local_blob_info);
}
+void IndexedDBDispatcher::OnSuccessArray(
+ const IndexedDBMsg_CallbacksSuccessArray_Params& p) {
+ DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId());
+ int32 ipc_callbacks_id = p.ipc_callbacks_id;
+ blink::WebVector<WebIDBValue> web_values(p.values.size());
+ for (size_t i = 0; i < p.values.size(); ++i)
+ PrepareWebValue(p.values[i], &web_values[i]);
+ WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id);
+ DCHECK(callbacks);
+ callbacks->onSuccess(web_values);
+ pending_callbacks_.Remove(ipc_callbacks_id);
+}
+
void IndexedDBDispatcher::OnSuccessValue(
const IndexedDBMsg_CallbacksSuccessValue_Params& params) {
DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId());
@@ -555,17 +612,14 @@ void IndexedDBDispatcher::OnSuccessValue(
pending_callbacks_.Lookup(params.ipc_callbacks_id);
if (!callbacks)
return;
- WebData web_value;
- WebVector<WebBlobInfo> web_blob_info;
- PrepareWebValueAndBlobInfo(params.value, &web_value, &web_blob_info);
+ WebIDBValue web_value;
+ PrepareWebValue(params.value, &web_value);
if (params.value.primary_key.IsValid()) {
- callbacks->onSuccess(web_value, web_blob_info,
- WebIDBKeyBuilder::Build(params.value.primary_key),
- WebIDBKeyPathBuilder::Build(params.value.key_path));
- } else {
- callbacks->onSuccess(web_value, web_blob_info);
- cursor_transaction_ids_.erase(params.ipc_callbacks_id);
+ web_value.primaryKey = WebIDBKeyBuilder::Build(params.value.primary_key);
+ web_value.keyPath = WebIDBKeyPathBuilder::Build(params.value.key_path);
}
+ callbacks->onSuccess(web_value);
+ cursor_transaction_ids_.erase(params.ipc_callbacks_id);
pending_callbacks_.Remove(params.ipc_callbacks_id);
}
diff --git a/content/child/indexed_db/indexed_db_dispatcher.h b/content/child/indexed_db/indexed_db_dispatcher.h
index df6d038..fa69ffb 100644
--- a/content/child/indexed_db/indexed_db_dispatcher.h
+++ b/content/child/indexed_db/indexed_db_dispatcher.h
@@ -25,6 +25,7 @@ struct IndexedDBDatabaseMetadata;
struct IndexedDBMsg_CallbacksSuccessCursorContinue_Params;
struct IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params;
struct IndexedDBMsg_CallbacksSuccessIDBCursor_Params;
+struct IndexedDBMsg_CallbacksSuccessArray_Params;
struct IndexedDBMsg_CallbacksSuccessValue_Params;
struct IndexedDBMsg_CallbacksUpgradeNeeded_Params;
@@ -128,6 +129,13 @@ class CONTENT_EXPORT IndexedDBDispatcher : public WorkerTaskRunner::Observer {
bool key_only,
blink::WebIDBCallbacks* callbacks);
+ void RequestIDBDatabaseGetAll(int32 ipc_database_id,
+ int64 transaction_id,
+ int64 object_store_id,
+ const IndexedDBKeyRange& key_range,
+ int64 max_count,
+ blink::WebIDBCallbacks* callbacks);
+
void RequestIDBDatabasePut(
int32 ipc_database_id,
int64 transaction_id,
@@ -209,6 +217,7 @@ class CONTENT_EXPORT IndexedDBDispatcher : public WorkerTaskRunner::Observer {
int32 ipc_callbacks_id,
const std::vector<base::string16>& value);
void OnSuccessValue(const IndexedDBMsg_CallbacksSuccessValue_Params& p);
+ void OnSuccessArray(const IndexedDBMsg_CallbacksSuccessArray_Params& p);
void OnSuccessInteger(int32 ipc_thread_id,
int32 ipc_callbacks_id,
int64 value);
diff --git a/content/child/indexed_db/indexed_db_dispatcher_unittest.cc b/content/child/indexed_db/indexed_db_dispatcher_unittest.cc
index 1463995..94b9cca 100644
--- a/content/child/indexed_db/indexed_db_dispatcher_unittest.cc
+++ b/content/child/indexed_db/indexed_db_dispatcher_unittest.cc
@@ -25,6 +25,7 @@ using blink::WebIDBCursor;
using blink::WebIDBDatabase;
using blink::WebIDBDatabaseError;
using blink::WebIDBKey;
+using blink::WebIDBValue;
using blink::WebVector;
namespace content {
@@ -141,7 +142,7 @@ class CursorCallbacks : public WebIDBCallbacks {
explicit CursorCallbacks(scoped_ptr<WebIDBCursor>* cursor)
: cursor_(cursor) {}
- void onSuccess(const WebData&, const WebVector<WebBlobInfo>&) override {}
+ void onSuccess(const WebIDBValue&) override {}
void onSuccess(WebIDBCursor* cursor,
const WebIDBKey& key,
const WebIDBKey& primaryKey,
diff --git a/content/child/indexed_db/webidbdatabase_impl.cc b/content/child/indexed_db/webidbdatabase_impl.cc
index cbc7bbb..81ce98a 100644
--- a/content/child/indexed_db/webidbdatabase_impl.cc
+++ b/content/child/indexed_db/webidbdatabase_impl.cc
@@ -115,6 +115,25 @@ void WebIDBDatabaseImpl::get(long long transaction_id,
callbacks);
}
+void WebIDBDatabaseImpl::getAll(long long transaction_id,
+ long long object_store_id,
+ long long index_id,
+ const WebIDBKeyRange& key_range,
+ long long max_count,
+ bool key_only,
+ WebIDBCallbacks* callbacks) {
+ // TODO(cmumford): Remove DCHECK's for index_id/key_only once IDBIndex.getAll
+ // is implemented.
+ static const int64 kInvalidId = -1;
+ DCHECK_EQ(kInvalidId, index_id);
+ DCHECK(!key_only);
+ IndexedDBDispatcher* dispatcher =
+ IndexedDBDispatcher::ThreadSpecificInstance(thread_safe_sender_.get());
+ dispatcher->RequestIDBDatabaseGetAll(
+ ipc_database_id_, transaction_id, object_store_id,
+ IndexedDBKeyRangeBuilder::Build(key_range), max_count, callbacks);
+}
+
void WebIDBDatabaseImpl::put(long long transaction_id,
long long object_store_id,
const blink::WebData& value,
diff --git a/content/child/indexed_db/webidbdatabase_impl.h b/content/child/indexed_db/webidbdatabase_impl.h
index 1e6350d..0d9d7ab 100644
--- a/content/child/indexed_db/webidbdatabase_impl.h
+++ b/content/child/indexed_db/webidbdatabase_impl.h
@@ -50,6 +50,13 @@ class WebIDBDatabaseImpl : public blink::WebIDBDatabase {
const blink::WebIDBKeyRange&,
bool keyOnly,
blink::WebIDBCallbacks*);
+ virtual void getAll(long long transactionId,
+ long long objectStoreId,
+ long long indexId,
+ const blink::WebIDBKeyRange&,
+ long long maxCount,
+ bool keyOnly,
+ blink::WebIDBCallbacks*);
virtual void put(long long transactionId,
long long objectStoreId,
const blink::WebData& value,
diff --git a/content/common/indexed_db/indexed_db_constants.h b/content/common/indexed_db/indexed_db_constants.h
index 5c7377b..b6c6363 100644
--- a/content/common/indexed_db/indexed_db_constants.h
+++ b/content/common/indexed_db/indexed_db_constants.h
@@ -9,6 +9,8 @@ namespace content {
const int32 kNoDatabase = -1;
+const size_t kMaxIDBMessageOverhead = 1024 * 1024; // 1MB; arbitrarily chosen.
+
} // namespace content
#endif // CONTENT_COMMON_INDEXED_DB_INDEXED_DB_CONSTANTS_H_
diff --git a/content/common/indexed_db/indexed_db_key_range.cc b/content/common/indexed_db/indexed_db_key_range.cc
index c2aca9f..f1938bf 100644
--- a/content/common/indexed_db/indexed_db_key_range.cc
+++ b/content/common/indexed_db/indexed_db_key_range.cc
@@ -32,8 +32,14 @@ IndexedDBKeyRange& IndexedDBKeyRange::operator=(
bool IndexedDBKeyRange::IsOnlyKey() const {
if (lower_open_ || upper_open_)
return false;
+ if (IsEmpty())
+ return false;
return lower_.Equals(upper_);
}
+bool IndexedDBKeyRange::IsEmpty() const {
+ return !lower_.IsValid() && !upper_.IsValid();
+}
+
} // namespace content
diff --git a/content/common/indexed_db/indexed_db_key_range.h b/content/common/indexed_db/indexed_db_key_range.h
index 19a440b..8bf6fb3 100644
--- a/content/common/indexed_db/indexed_db_key_range.h
+++ b/content/common/indexed_db/indexed_db_key_range.h
@@ -29,6 +29,7 @@ class CONTENT_EXPORT IndexedDBKeyRange {
bool upper_open() const { return upper_open_; }
bool IsOnlyKey() const;
+ bool IsEmpty() const;
private:
IndexedDBKey lower_ = IndexedDBKey(blink::WebIDBKeyTypeNull);
diff --git a/content/common/indexed_db/indexed_db_messages.h b/content/common/indexed_db/indexed_db_messages.h
index 6ab89fb..9e92e98 100644
--- a/content/common/indexed_db/indexed_db_messages.h
+++ b/content/common/indexed_db/indexed_db_messages.h
@@ -126,6 +126,22 @@ IPC_STRUCT_BEGIN(IndexedDBHostMsg_DatabaseGet_Params)
IPC_STRUCT_MEMBER(bool, key_only)
IPC_STRUCT_END()
+IPC_STRUCT_BEGIN(IndexedDBHostMsg_DatabaseGetAll_Params)
+ IPC_STRUCT_MEMBER(int32, ipc_thread_id)
+ // The id any response should contain.
+ IPC_STRUCT_MEMBER(int32, ipc_callbacks_id)
+ // The database the object store belongs to.
+ IPC_STRUCT_MEMBER(int32, ipc_database_id)
+ // The transaction its associated with.
+ IPC_STRUCT_MEMBER(int64, transaction_id)
+ // The object store's id.
+ IPC_STRUCT_MEMBER(int64, object_store_id)
+ // The serialized key range.
+ IPC_STRUCT_MEMBER(content::IndexedDBKeyRange, key_range)
+ // The max number of values to retrieve.
+ IPC_STRUCT_MEMBER(int64, max_count)
+IPC_STRUCT_END()
+
IPC_STRUCT_BEGIN(IndexedDBMsg_BlobOrFileInfo)
IPC_STRUCT_MEMBER(bool, is_file)
IPC_STRUCT_MEMBER(std::string, uuid)
@@ -287,6 +303,12 @@ IPC_STRUCT_BEGIN(IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params)
IPC_STRUCT_MEMBER(std::vector<IndexedDBMsg_Value>, values)
IPC_STRUCT_END()
+IPC_STRUCT_BEGIN(IndexedDBMsg_CallbacksSuccessArray_Params)
+ IPC_STRUCT_MEMBER(int32, ipc_thread_id)
+ IPC_STRUCT_MEMBER(int32, ipc_callbacks_id)
+ IPC_STRUCT_MEMBER(std::vector<IndexedDBMsg_ReturnValue>, values)
+IPC_STRUCT_END()
+
IPC_STRUCT_BEGIN(IndexedDBMsg_CallbacksSuccessValue_Params)
IPC_STRUCT_MEMBER(int32, ipc_thread_id)
IPC_STRUCT_MEMBER(int32, ipc_callbacks_id)
@@ -349,6 +371,9 @@ IPC_MESSAGE_CONTROL1(IndexedDBMsg_CallbacksSuccessCursorAdvance,
IPC_MESSAGE_CONTROL1(IndexedDBMsg_CallbacksSuccessCursorPrefetch,
IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params)
+IPC_MESSAGE_CONTROL1(IndexedDBMsg_CallbacksSuccessArray,
+ IndexedDBMsg_CallbacksSuccessArray_Params)
+
IPC_MESSAGE_CONTROL5(IndexedDBMsg_CallbacksSuccessIDBDatabase,
int32 /* ipc_thread_id */,
int32 /* ipc_callbacks_id */,
@@ -484,6 +509,10 @@ IPC_MESSAGE_CONTROL1(IndexedDBHostMsg_DatabaseDestroyed,
IPC_MESSAGE_CONTROL1(IndexedDBHostMsg_DatabaseGet,
IndexedDBHostMsg_DatabaseGet_Params)
+// WebIDBDatabase::getAll() message.
+IPC_MESSAGE_CONTROL1(IndexedDBHostMsg_DatabaseGetAll,
+ IndexedDBHostMsg_DatabaseGetAll_Params)
+
// WebIDBDatabase::put() message.
IPC_MESSAGE_CONTROL1(IndexedDBHostMsg_DatabasePut,
IndexedDBHostMsg_DatabasePut_Params)