зеркало из https://github.com/mozilla/gecko-dev.git
Bug 920633 - 'Add getAllKeys() to IDBObjectStore'. r=janv.
--HG-- extra : transplant_source : %F9%EA0%88%91%15%ADW%92Ae%CEY%29%A9%E4%1A%88Qo
This commit is contained in:
Родитель
47815586d7
Коммит
287f33192d
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "nsIIDBKeyRange.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
|
@ -563,6 +564,7 @@ IDBIndex::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit,
|
|||
IDBTransaction* transaction = mObjectStore->Transaction();
|
||||
if (!transaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
|
@ -1367,10 +1369,11 @@ GetHelper::UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
|
|||
nsresult
|
||||
GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_LABEL("IndexedDB", "GetAllKeysHelper::DoDatabaseWork");
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::DoDatabaseWork [IDBIndex.cpp]");
|
||||
|
||||
nsCString tableName;
|
||||
if (mIndex->IsUnique()) {
|
||||
|
@ -1410,7 +1413,7 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mKeys.SetCapacity(50);
|
||||
mKeys.SetCapacity(std::min<uint32_t>(50, mLimit));
|
||||
|
||||
bool hasResult;
|
||||
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
|
@ -1433,7 +1436,12 @@ nsresult
|
|||
GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aVal)
|
||||
{
|
||||
NS_ASSERTION(mKeys.Length() <= mLimit, "Too many results!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mKeys.Length() <= mLimit);
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::GetSuccessResult "
|
||||
"[IDBIndex.cpp]");
|
||||
|
||||
nsTArray<Key> keys;
|
||||
mKeys.SwapElements(keys);
|
||||
|
@ -1475,11 +1483,12 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
|||
nsresult
|
||||
GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::PackArgumentsForParentProcess");
|
||||
"GetAllKeysHelper::PackArgumentsForParentProcess "
|
||||
"[IDBIndex.cpp]");
|
||||
|
||||
GetAllKeysParams params;
|
||||
|
||||
|
@ -1501,11 +1510,12 @@ GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams)
|
|||
AsyncConnectionHelper::ChildProcessSendResult
|
||||
GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::SendResponseToChildProcess");
|
||||
"GetAllKeysHelper::SendResponseToChildProcess "
|
||||
"[IDBIndex.cpp]");
|
||||
|
||||
IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
|
||||
NS_ASSERTION(actor, "How did we get this far without an actor?");
|
||||
|
@ -1531,8 +1541,9 @@ nsresult
|
|||
GetAllKeysHelper::UnpackResponseFromParentProcess(
|
||||
const ResponseValue& aResponseValue)
|
||||
{
|
||||
NS_ASSERTION(aResponseValue.type() == ResponseValue::TGetAllKeysResponse,
|
||||
"Bad response type!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse);
|
||||
|
||||
mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys());
|
||||
return NS_OK;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
@ -441,6 +442,46 @@ private:
|
|||
nsTArray<StructuredCloneReadInfo> mCloneReadInfos;
|
||||
};
|
||||
|
||||
class GetAllKeysHelper MOZ_FINAL : public ObjectStoreHelper
|
||||
{
|
||||
public:
|
||||
GetAllKeysHelper(IDBTransaction* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBObjectStore* aObjectStore,
|
||||
IDBKeyRange* aKeyRange,
|
||||
const uint32_t aLimit)
|
||||
: ObjectStoreHelper(aTransaction, aRequest, aObjectStore),
|
||||
mKeyRange(aKeyRange), mLimit(aLimit)
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
ReleaseMainThreadObjects() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
|
||||
|
||||
virtual ChildProcessSendResult
|
||||
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
~GetAllKeysHelper()
|
||||
{ }
|
||||
|
||||
nsRefPtr<IDBKeyRange> mKeyRange;
|
||||
const uint32_t mLimit;
|
||||
nsTArray<Key> mKeys;
|
||||
};
|
||||
|
||||
class CountHelper : public ObjectStoreHelper
|
||||
{
|
||||
public:
|
||||
|
@ -2081,6 +2122,47 @@ IDBObjectStore::GetAllInternal(IDBKeyRange* aKeyRange,
|
|||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBObjectStore::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mTransaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
if (!request) {
|
||||
NS_WARNING("Failed to generate request!");
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GetAllKeysHelper> helper =
|
||||
new GetAllKeysHelper(mTransaction, request, this, aKeyRange, aLimit);
|
||||
|
||||
nsresult rv = helper->DispatchToTransactionPool();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch!");
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IDB_PROFILER_MARK("IndexedDB Request %llu: "
|
||||
"database(%s).transaction(%s).objectStore(%s)."
|
||||
"getAllKeys(%s, %lu)",
|
||||
"IDBRequest[%llu] MT IDBObjectStore.getAllKeys()",
|
||||
request->GetSerialNumber(),
|
||||
IDB_PROFILER_STRING(Transaction()->Database()),
|
||||
IDB_PROFILER_STRING(Transaction()),
|
||||
IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange),
|
||||
aLimit);
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBObjectStore::DeleteInternal(IDBKeyRange* aKeyRange,
|
||||
ErrorResult& aRv)
|
||||
|
@ -2767,6 +2849,32 @@ IDBObjectStore::Count(JSContext* aCx,
|
|||
return CountInternal(keyRange, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBObjectStore::GetAllKeys(JSContext* aCx,
|
||||
const Optional<JS::HandleValue>& aKey,
|
||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mTransaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
if (aKey.WasPassed()) {
|
||||
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
|
||||
ENSURE_SUCCESS(aRv, nullptr);
|
||||
}
|
||||
|
||||
uint32_t limit = UINT32_MAX;
|
||||
if (aLimit.WasPassed() && aLimit.Value() != 0) {
|
||||
limit = aLimit.Value();
|
||||
}
|
||||
|
||||
return GetAllKeysInternal(keyRange, limit, aRv);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
CopyData(nsIInputStream* aInputStream, nsIOutputStream* aOutputStream)
|
||||
{
|
||||
|
@ -4297,6 +4405,195 @@ GetAllHelper::UnpackResponseFromParentProcess(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::DoDatabaseWork [IDObjectStore.cpp]");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(keyValue, "key_value");
|
||||
|
||||
nsAutoCString keyRangeClause;
|
||||
if (mKeyRange) {
|
||||
mKeyRange->GetBindingClause(keyValue, keyRangeClause);
|
||||
}
|
||||
|
||||
nsAutoCString limitClause;
|
||||
if (mLimit != UINT32_MAX) {
|
||||
limitClause = NS_LITERAL_CSTRING(" LIMIT ");
|
||||
limitClause.AppendInt(mLimit);
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(osid, "osid");
|
||||
|
||||
nsCString query = NS_LITERAL_CSTRING("SELECT ") + keyValue +
|
||||
NS_LITERAL_CSTRING(" FROM object_data WHERE "
|
||||
"object_store_id = :") +
|
||||
osid + keyRangeClause +
|
||||
NS_LITERAL_CSTRING(" ORDER BY key_value ASC") +
|
||||
limitClause;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
|
||||
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
mozStorageStatementScoper scoper(stmt);
|
||||
|
||||
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (mKeyRange) {
|
||||
rv = mKeyRange->BindToStatement(stmt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mKeys.SetCapacity(std::min<uint32_t>(50, mLimit));
|
||||
|
||||
bool hasResult;
|
||||
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
if (mKeys.Capacity() == mKeys.Length()) {
|
||||
mKeys.SetCapacity(mKeys.Capacity() * 2);
|
||||
}
|
||||
|
||||
Key* key = mKeys.AppendElement();
|
||||
NS_ASSERTION(key, "This shouldn't fail!");
|
||||
|
||||
rv = key->SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mKeys.Length() <= mLimit);
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::GetSuccessResult "
|
||||
"[IDBObjectStore.cpp]");
|
||||
|
||||
nsTArray<Key> keys;
|
||||
mKeys.SwapElements(keys);
|
||||
|
||||
JS::RootedObject array(aCx, JS_NewArrayObject(aCx, 0, NULL));
|
||||
if (!array) {
|
||||
NS_WARNING("Failed to make array!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (!keys.IsEmpty()) {
|
||||
if (!JS_SetArrayLength(aCx, array, keys.Length())) {
|
||||
NS_WARNING("Failed to set array length!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0, count = keys.Length(); index < count; index++) {
|
||||
const Key& key = keys[index];
|
||||
MOZ_ASSERT(!key.IsUnset());
|
||||
|
||||
JS::RootedValue value(aCx);
|
||||
nsresult rv = key.ToJSVal(aCx, &value);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get jsval for key!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, array, index, &value)) {
|
||||
NS_WARNING("Failed to set array element!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aVal.setObject(*array);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GetAllKeysHelper::ReleaseMainThreadObjects()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mKeyRange = nullptr;
|
||||
|
||||
ObjectStoreHelper::ReleaseMainThreadObjects();
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::PackArgumentsForParentProcess(
|
||||
ObjectStoreRequestParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::PackArgumentsForParentProcess "
|
||||
"[IDBObjectStore.cpp]");
|
||||
|
||||
GetAllKeysParams params;
|
||||
|
||||
if (mKeyRange) {
|
||||
KeyRange keyRange;
|
||||
mKeyRange->ToSerializedKeyRange(keyRange);
|
||||
params.optionalKeyRange() = keyRange;
|
||||
} else {
|
||||
params.optionalKeyRange() = mozilla::void_t();
|
||||
}
|
||||
|
||||
params.limit() = mLimit;
|
||||
|
||||
aParams = params;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AsyncConnectionHelper::ChildProcessSendResult
|
||||
GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::SendResponseToChildProcess "
|
||||
"[IDBObjectStore.cpp]");
|
||||
|
||||
IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
|
||||
MOZ_ASSERT(actor);
|
||||
|
||||
ResponseValue response;
|
||||
if (NS_FAILED(aResultCode)) {
|
||||
response = aResultCode;
|
||||
}
|
||||
else {
|
||||
GetAllKeysResponse getAllKeysResponse;
|
||||
getAllKeysResponse.keys().AppendElements(mKeys);
|
||||
response = getAllKeysResponse;
|
||||
}
|
||||
|
||||
if (!actor->SendResponse(response)) {
|
||||
return Error;
|
||||
}
|
||||
|
||||
return Success_Sent;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::UnpackResponseFromParentProcess(
|
||||
const ResponseValue& aResponseValue)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse);
|
||||
|
||||
mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CountHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/dom/IDBCursorBinding.h"
|
||||
#include "mozilla/dom/IDBIndexBinding.h"
|
||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||
|
@ -220,6 +221,11 @@ public:
|
|||
uint32_t aLimit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
GetAllKeysInternal(IDBKeyRange* aKeyRange,
|
||||
uint32_t aLimit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
DeleteInternal(IDBKeyRange* aKeyRange,
|
||||
ErrorResult& aRv);
|
||||
|
@ -233,7 +239,8 @@ public:
|
|||
size_t aDirection,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult OpenCursorFromChildProcess(
|
||||
nsresult
|
||||
OpenCursorFromChildProcess(
|
||||
IDBRequest* aRequest,
|
||||
size_t aDirection,
|
||||
const Key& aKey,
|
||||
|
@ -336,6 +343,10 @@ public:
|
|||
GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
|
||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
GetAllKeys(JSContext* aCx, const Optional<JS::HandleValue>& aKey,
|
||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
IDBObjectStore();
|
||||
~IDBObjectStore();
|
||||
|
|
|
@ -1069,6 +1069,9 @@ IndexedDBObjectStoreRequestChild::Recv__delete__(const ResponseValue& aResponse)
|
|||
case ResponseValue::TGetAllResponse:
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
|
||||
break;
|
||||
case ResponseValue::TGetAllKeysResponse:
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
|
||||
break;
|
||||
case ResponseValue::TAddResponse:
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams);
|
||||
break;
|
||||
|
|
|
@ -40,6 +40,12 @@ struct GetAllParams
|
|||
uint32_t limit;
|
||||
};
|
||||
|
||||
struct GetAllKeysParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
uint32_t limit;
|
||||
};
|
||||
|
||||
struct CountParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
|
|
|
@ -1097,6 +1097,9 @@ IndexedDBObjectStoreParent::RecvPIndexedDBRequestConstructor(
|
|||
case ObjectStoreRequestParams::TGetAllParams:
|
||||
return actor->GetAll(aParams.get_GetAllParams());
|
||||
|
||||
case ObjectStoreRequestParams::TGetAllKeysParams:
|
||||
return actor->GetAllKeys(aParams.get_GetAllKeysParams());
|
||||
|
||||
case ObjectStoreRequestParams::TAddParams:
|
||||
return actor->Add(aParams.get_AddParams());
|
||||
|
||||
|
@ -1554,6 +1557,44 @@ IndexedDBObjectStoreRequestParent::GetAll(const GetAllParams& aParams)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IndexedDBObjectStoreRequestParent::GetAllKeys(const GetAllKeysParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
|
||||
MOZ_ASSERT(mObjectStore);
|
||||
|
||||
nsRefPtr<IDBRequest> request;
|
||||
|
||||
const ipc::OptionalKeyRange keyRangeUnion = aParams.optionalKeyRange();
|
||||
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
|
||||
switch (keyRangeUnion.type()) {
|
||||
case ipc::OptionalKeyRange::TKeyRange:
|
||||
keyRange =
|
||||
IDBKeyRange::FromSerializedKeyRange(keyRangeUnion.get_KeyRange());
|
||||
break;
|
||||
|
||||
case ipc::OptionalKeyRange::Tvoid_t:
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown param type!");
|
||||
}
|
||||
|
||||
{
|
||||
AutoSetCurrentTransaction asct(mObjectStore->Transaction());
|
||||
|
||||
ErrorResult rv;
|
||||
request = mObjectStore->GetAllKeysInternal(keyRange, aParams.limit(), rv);
|
||||
ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
|
||||
request->SetActor(this);
|
||||
mRequest.swap(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IndexedDBObjectStoreRequestParent::Add(const AddParams& aParams)
|
||||
{
|
||||
|
|
|
@ -707,6 +707,7 @@ class IndexedDBObjectStoreRequestParent : public IndexedDBRequestParentBase
|
|||
typedef ipc::DeleteParams DeleteParams;
|
||||
typedef ipc::GetParams GetParams;
|
||||
typedef ipc::GetAllParams GetAllParams;
|
||||
typedef ipc::GetAllKeysParams GetAllKeysParams;
|
||||
typedef ipc::CountParams CountParams;
|
||||
typedef ipc::OpenCursorParams OpenCursorParams;
|
||||
|
||||
|
@ -721,6 +722,9 @@ public:
|
|||
bool
|
||||
GetAll(const GetAllParams& aParams);
|
||||
|
||||
bool
|
||||
GetAllKeys(const GetAllKeysParams& aParams);
|
||||
|
||||
bool
|
||||
Add(const AddParams& aParams);
|
||||
|
||||
|
|
|
@ -22,12 +22,6 @@ struct GetKeyParams
|
|||
KeyRange keyRange;
|
||||
};
|
||||
|
||||
struct GetAllKeysParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
uint32_t limit;
|
||||
};
|
||||
|
||||
struct OpenKeyCursorParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
|
|
|
@ -52,6 +52,7 @@ union ObjectStoreRequestParams
|
|||
{
|
||||
GetParams;
|
||||
GetAllParams;
|
||||
GetAllKeysParams;
|
||||
AddParams;
|
||||
PutParams;
|
||||
DeleteParams;
|
||||
|
|
|
@ -36,6 +36,7 @@ tail =
|
|||
[test_names_sorted.js]
|
||||
[test_object_identity.js]
|
||||
[test_objectCursors.js]
|
||||
[test_objectStore_getAllKeys.js]
|
||||
[test_objectStore_inline_autoincrement_key_added_on_put.js]
|
||||
[test_objectStore_remove_values.js]
|
||||
[test_odd_result_order.js]
|
||||
|
|
|
@ -70,6 +70,7 @@ MOCHITEST_FILES = \
|
|||
test_multientry.html \
|
||||
test_names_sorted.html \
|
||||
test_objectCursors.html \
|
||||
test_objectStore_getAllKeys.html \
|
||||
test_objectStore_inline_autoincrement_key_added_on_put.html \
|
||||
test_objectStore_remove_values.html \
|
||||
test_object_identity.html \
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_objectStore_getAllKeys.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
|
@ -38,6 +38,7 @@ MOCHITEST_FILES = \
|
|||
test_names_sorted.js \
|
||||
test_object_identity.js \
|
||||
test_objectCursors.js \
|
||||
test_objectStore_getAllKeys.js \
|
||||
test_objectStore_inline_autoincrement_key_added_on_put.js \
|
||||
test_objectStore_remove_values.js \
|
||||
test_odd_result_order.js \
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
let testGenerator = testSteps();
|
||||
|
||||
function testSteps() {
|
||||
const dbName = this.window ?
|
||||
window.location.pathname :
|
||||
"test_objectStore_getAllKeys";
|
||||
const dbVersion = 1;
|
||||
const objectStoreName = "foo";
|
||||
const keyCount = 200;
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
info("Creating database");
|
||||
|
||||
let db = event.target.result;
|
||||
let objectStore = db.createObjectStore(objectStoreName);
|
||||
for (let i = 0; i < keyCount; i++) {
|
||||
objectStore.add(true, i);
|
||||
}
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
db = event.target.result;
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
|
||||
info("Getting all keys");
|
||||
objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, keyCount, "Got correct array length");
|
||||
|
||||
let match = true;
|
||||
for (let i = 0; i < keyCount; i++) {
|
||||
if (event.target.result[i] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with key range");
|
||||
let keyRange = IDBKeyRange.bound(10, 20, false, true);
|
||||
objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 10, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 10; i < 20; i++) {
|
||||
if (event.target.result[i - 10] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with unmatched key range");
|
||||
keyRange = IDBKeyRange.bound(10000, 200000);
|
||||
objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 0, "Got correct array length");
|
||||
|
||||
info("Getting all keys with limit");
|
||||
objectStore.getAllKeys(null, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 5, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (event.target.result[i] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with key range and limit");
|
||||
keyRange = IDBKeyRange.bound(10, 20, false, true);
|
||||
objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 5, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 10; i < 15; i++) {
|
||||
if (event.target.result[i - 10] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with unmatched key range and limit");
|
||||
keyRange = IDBKeyRange.bound(10000, 200000);
|
||||
objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 0, "Got correct array length");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
|
@ -39,6 +39,7 @@ tail =
|
|||
[test_names_sorted.js]
|
||||
[test_object_identity.js]
|
||||
[test_objectCursors.js]
|
||||
[test_objectStore_getAllKeys.js]
|
||||
[test_objectStore_inline_autoincrement_key_added_on_put.js]
|
||||
[test_objectStore_remove_values.js]
|
||||
[test_odd_result_order.js]
|
||||
|
|
|
@ -65,4 +65,10 @@ partial interface IDBObjectStore {
|
|||
// Success fires IDBTransactionEvent, result == array of values for given keys
|
||||
[Throws]
|
||||
IDBRequest mozGetAll (optional any key, optional unsigned long limit);
|
||||
|
||||
[Pref="dom.indexedDB.experimental", Throws]
|
||||
IDBRequest getAll (optional any key, optional unsigned long limit);
|
||||
|
||||
[Pref="dom.indexedDB.experimental", Throws]
|
||||
IDBRequest getAllKeys (optional any key, optional unsigned long limit);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче