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:
Ben Turner 2013-09-24 10:14:16 -07:00
Родитель 47815586d7
Коммит 287f33192d
16 изменённых файлов: 542 добавлений и 22 удалений

Просмотреть файл

@ -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,
@ -319,7 +326,7 @@ public:
already_AddRefed<IDBIndex>
CreateIndex(JSContext* aCx, const nsAString& aName,
const Sequence<nsString >& aKeyPath,
const Sequence<nsString>& aKeyPath,
const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
already_AddRefed<IDBIndex>
@ -334,7 +341,11 @@ public:
already_AddRefed<IDBRequest>
GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
const Optional<uint32_t >& aLimit, ErrorResult& aRv);
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();

Просмотреть файл

@ -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);
};