diff options
author | cmumford <cmumford@chromium.org> | 2015-05-14 07:50:39 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-14 14:50:46 +0000 |
commit | b86405eb7d5712e42f96012724b975fbad6a74bb (patch) | |
tree | 06018d3938a02dc53c28cf8f9875b6d8044202bb | |
parent | 9bea0b509c9ef43fb6585fba6070a93b58499333 (diff) | |
download | chromium_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.cc | 61 | ||||
-rw-r--r-- | content/browser/indexed_db/indexed_db_callbacks.h | 4 | ||||
-rw-r--r-- | content/browser/indexed_db/indexed_db_cursor.cc | 1 | ||||
-rw-r--r-- | content/browser/indexed_db/indexed_db_database.cc | 112 | ||||
-rw-r--r-- | content/browser/indexed_db/indexed_db_database.h | 10 | ||||
-rw-r--r-- | content/browser/indexed_db/indexed_db_dispatcher_host.cc | 18 | ||||
-rw-r--r-- | content/browser/indexed_db/indexed_db_dispatcher_host.h | 2 | ||||
-rw-r--r-- | content/child/indexed_db/indexed_db_dispatcher.cc | 74 | ||||
-rw-r--r-- | content/child/indexed_db/indexed_db_dispatcher.h | 9 | ||||
-rw-r--r-- | content/child/indexed_db/indexed_db_dispatcher_unittest.cc | 3 | ||||
-rw-r--r-- | content/child/indexed_db/webidbdatabase_impl.cc | 19 | ||||
-rw-r--r-- | content/child/indexed_db/webidbdatabase_impl.h | 7 | ||||
-rw-r--r-- | content/common/indexed_db/indexed_db_constants.h | 2 | ||||
-rw-r--r-- | content/common/indexed_db/indexed_db_key_range.cc | 6 | ||||
-rw-r--r-- | content/common/indexed_db/indexed_db_key_range.h | 1 | ||||
-rw-r--r-- | content/common/indexed_db/indexed_db_messages.h | 29 |
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, + ¶ms->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(¶ms, 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) |