Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speculative getAllEntries() spec #280

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 143 additions & 71 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2726,6 +2726,7 @@ interface IDBObjectStore {
optional [EnforceRange] unsigned long count);
[NewObject] IDBRequest getAllKeys(optional any query,
optional [EnforceRange] unsigned long count);
[NewObject] IDBRequest getAllEntries(optional IDBGetAllEntriesOptions options = {});
[NewObject] IDBRequest count(optional any query);

[NewObject] IDBRequest openCursor(optional any query,
Expand All @@ -2745,6 +2746,12 @@ dictionary IDBIndexParameters {
boolean unique = false;
boolean multiEntry = false;
};

dictionary IDBGetAllEntriesOptions {
any query = null;
[EnforceRange] unsigned long count;
IDBCursorDirection direction = "next";
};
</xmp>

<div class="domintro note">
Expand Down Expand Up @@ -3097,6 +3104,14 @@ The <dfn method for=IDBObjectStore>clear()</dfn> method steps are:
If successful, |request|'s {{IDBRequest/result}} will
be an {{Array}} of the [=/keys=].

: |request| = |store| . {{IDBObjectStore/getAllEntries()|getAllEntries}}(|options|)
::
Retrieves multiple [=/keys=] and [=/values=] of [=object-store/records=].

The |query| option specifies a [=/key=] or [=key range=] to match. The |count| option limits the number or records matched. Set the |direction| option to "{{IDBCursorDirection/next}}" to retrieve the first |count| records, or "{{IDBCursorDirection/prev}}" to return the last |count| records.

If successful, |request|'s {{IDBRequest/result}} will be an {{Array}}, with each member being an {{Array}} with a [=/key=] [=/value=] pair.

: |request| = |store| .
{{IDBObjectStore/count()|count}}(|query|)
::
Expand Down Expand Up @@ -3193,8 +3208,7 @@ The <dfn method for=IDBObjectStore>getAll(|query|, |count|)</dfn> method steps a
[=/converting a value to a key range=] with |query|.
Rethrow any exceptions.

1. Let |operation| be an algorithm to run [=retrieve multiple values from an object store=] with [=ECMAScript/the current Realm record=], |store|, |range|, and |count| if given.

1. Let |operation| be an algorithm to run [=retrieve multiple items from an object store=] with [=ECMAScript/the current Realm record=], |store|, |range|, "value", and |count| if given.

1. Return the result (an {{IDBRequest}}) of running [=asynchronously execute a request=] with [=/this=] and |operation|.

Expand Down Expand Up @@ -3227,7 +3241,7 @@ The <dfn method for=IDBObjectStore>getAllKeys(|query|, |count|)</dfn> method ste
[=/converting a value to a key range=] with |query|.
Rethrow any exceptions.

1. Let |operation| be an algorithm to run [=retrieve multiple keys from an object store=] with |store|, |range|, and |count| if given.
1. Let |operation| be an algorithm to run [=retrieve multiple items from an object store=] with [=ECMAScript/the current Realm record=], |store|, |range|, "key", and |count| if given.

1. Return the result (an {{IDBRequest}}) of running [=asynchronously execute a request=] with [=/this=] and |operation|.

Expand All @@ -3242,6 +3256,37 @@ will be retrieved.
</aside>


<div algorithm>

The <dfn method for=IDBObjectStore>getAllEntries(|query|, |count|)</dfn> method steps are:

1. Let |transaction| be [=/this=]'s [=object-store-handle/transaction=].

1. Let |store| be [=/this=]'s [=object-store-handle/object store=].

1. If |store| has been deleted, then [=exception/throw=] an "{{InvalidStateError}}" {{DOMException}}.

1. If |transaction|'s [=transaction/state=] is not [=transaction/active=], then [=exception/throw=] a "{{TransactionInactiveError}}" {{DOMException}}.

1. Let |range| be the result of [=/converting a value to a key range=] with |query|. Rethrow any exceptions.

1. Let |operation| be an algorithm to run [=retrieve multiple items from an object store=] with [=ECMAScript/the current Realm record=], |store|, |range|, "key+value", and |count| if given.

1. Return the result (an {{IDBRequest}}) of running [=asynchronously execute a request=] with [=/this=] and |operation|.

</div>

<aside class=note>
The |query| parameter can be a [=/key=] or [=key range=] (an {{IDBKeyRange}}) identifying the [=object-store/records=] to be retrieved. If null or not given, an [=unbounded key range=] is used. If |count| is specified and there are more than |count| keys in range, only the first |count| will be retrieved.
</aside>

<aside class=advisement>
&#x1F6A7;
The {{IDBObjectStore/getAllEntries()}} method is new in this edition.
&#x1F6A7;
</aside>


<div algorithm>

The <dfn method for=IDBObjectStore>count(|query|)</dfn> method steps are:
Expand Down Expand Up @@ -3617,6 +3662,7 @@ interface IDBIndex {
optional [EnforceRange] unsigned long count);
[NewObject] IDBRequest getAllKeys(optional any query,
optional [EnforceRange] unsigned long count);
[NewObject] IDBRequest getAllEntries(optional IDBGetAllEntriesOptions options = {});
[NewObject] IDBRequest count(optional any query);

[NewObject] IDBRequest openCursor(optional any query,
Expand Down Expand Up @@ -3765,6 +3811,13 @@ return [=/this=]'s [=index-handle/index=]'s [=index/unique flag=].
If successful, |request|'s {{IDBRequest/result}} will be an
{{Array}} of the [=/keys=].


: |request| = |index| . {{IDBIndex/getAllEntries()|getAllEntries}}(|query| [, |count|])
::
Retrieves the [=/keys=], [=/values=], and index [=/keys=] of [=object-store/records=] matching the given [=/key=] or [=key range=] in |query| (up to |count| if given).

If successful, |request|'s {{IDBRequest/result}} will be an {{Array}}, with each member being an {{Array}} with [=/key=], [=/value=], and index [=/key=].

: |request| = |index| .
{{IDBIndex/count()|count}}(|query|)
::
Expand Down Expand Up @@ -3862,7 +3915,7 @@ The <dfn method for=IDBIndex>getAll(|query|, |count|)</dfn> method steps are:
[=/converting a value to a key range=] with |query|.
Rethrow any exceptions.

1. Let |operation| be an algorithm to run [=retrieve multiple referenced values from an index=] with [=ECMAScript/the current Realm record=], |index|, |range|, and |count| if given.
1. Let |operation| be an algorithm to run [=retrieve multiple items from an index=] with [=ECMAScript/the current Realm record=], |index|, |range|, "value", and |count| if given.

1. Return the result (an {{IDBRequest}}) of running [=asynchronously execute a request=] with [=/this=] and |operation|.

Expand Down Expand Up @@ -3895,7 +3948,7 @@ The <dfn method for=IDBIndex>getAllKeys(|query|, |count|)</dfn> method steps are
[=/converting a value to a key range=] with |query|.
Rethrow any exceptions.

1. Let |operation| be an algorithm to run [=retrieve multiple values from an index=] with |index|, |range|, and |count| if given.
1. Let |operation| be an algorithm to run [=retrieve multiple items from an index=] with [=ECMAScript/the current Realm record=], |index|, |range|, "key", and |count| if given.

1. Return the result (an {{IDBRequest}}) of running [=asynchronously execute a request=] with [=/this=] and |operation|.

Expand All @@ -3910,6 +3963,37 @@ will be retrieved.
</aside>


<div algorithm>

The <dfn method for=IDBIndex>getAllEntries(|query|, |count|)</dfn> method steps are:

1. Let |transaction| be [=/this=]'s [=index-handle/transaction=].

1. Let |index| be [=/this=]'s [=index-handle/index=].

1. If |index| or |index|'s [=/object store=] has been deleted, then [=exception/throw=] an "{{InvalidStateError}}" {{DOMException}}.

1. If |transaction|'s [=transaction/state=] is not [=transaction/active=], then [=exception/throw=] a "{{TransactionInactiveError}}" {{DOMException}}.

1. Let |range| be the result of [=/converting a value to a key range=] with |query|. Rethrow any exceptions.

1. Let |operation| be an algorithm to run [=retrieve multiple items from an index=] with [=ECMAScript/the current Realm record=], |index|, |range|, "key+value+indexKey", and |count| if given.

1. Return the result (an {{IDBRequest}}) of running [=asynchronously execute a request=] with [=/this=] and |operation|.

</div>

<aside class=note>
The |query| parameter can be a [=/key=] or [=key range=] (an {{IDBKeyRange}}) identifying the [=object-store/records=] to be retrieved. If null or not given, an [=unbounded key range=] is used. If |count| is specified and there are more than |count| keys in range, only the first |count| will be retrieved.
</aside>

<aside class=advisement>
&#x1F6A7;
The {{IDBIndex/getAllEntries()}} method is new in this edition.
&#x1F6A7;
</aside>


<div algorithm>

The <dfn method for=IDBIndex>count(|query|)</dfn> method steps are:
Expand Down Expand Up @@ -5717,30 +5801,6 @@ To <dfn>retrieve a value from an object store</dfn> with
</div>


<div algorithm>

To <dfn>retrieve multiple values from an object
store</dfn> with |targetRealm|, |store|, |range| and optional |count|, run these steps:

1. If |count| is not given or is 0 (zero), let |count| be infinity.

1. Let |records| be a [=/list=] containing the first |count| [=object-store/records=]
in |store|'s [=object-store/list of records=] whose [=/key=] is
[=in=] |range|.

1. Let |list| be an empty [=/list=].

1. [=list/For each=] |record| of |records|:

1. Let |serialized| be |record|'s [=/value=].
1. Let |entry| be [=ECMAScript/!=] [$StructuredDeserialize$](|serialized|, |targetRealm|).
1. Append |entry| to |list|.

1. Return |list| converted to a <code>[=/sequence=]&lt;{{any}}&gt;</code>.

</div>


<div algorithm>

To <dfn>retrieve a key from an object store</dfn>
Expand All @@ -5760,24 +5820,38 @@ with |store| and |range|, run these steps:

<div algorithm>

To <dfn>retrieve multiple keys from an object store</dfn>
with |store|, |range| and optional |count|, run these steps:
To <dfn>retrieve multiple items from an object store</dfn> with |targetRealm|, |store|, |range|, |kind| and optional |count|, run these steps:

1. If |count| is not given or is 0 (zero), let |count| be infinity.

1. Let |records| be a list containing the first |count| [=object-store/records=]
in |store|'s [=object-store/list of records=] whose [=/key=] is
[=in=] |range|.
1. Let |records| be a list containing the first |count| [=object-store/records=] in |store|'s [=object-store/list of records=] whose [=/key=] is [=in=] |range|.

1. Let |list| be an empty [=/list=].

1. [=list/For each=] |record| of |records|:
1. [=list/For each=] |record| of |records|, switching on |kind|:

1. Let |entry| be the result of [=/converting a
key to a value=] with |record|'s key.
1. Append |entry| to |list|.
<dl class=switch>
: "key"
::
1. Let |key| be the result of [=/converting a key to a value=] with |record|'s key.
1. [=list/Append=] |key| to |list|.

: "value"
::
1. Let |serialized| be |record|'s [=/value=].
1. Let |value| be [=ECMAScript/!=] [$StructuredDeserialize$](|serialized|, |targetRealm|).
1. [=list/Append=] |value| to |list|.

1. Return |list| converted to a <code>[=/sequence=]&lt;{{any}}&gt;</code>.
: "key+value"
::
1. Let |key| be the result of [=/converting a key to a value=] with |record|'s key.
1. Let |serialized| be |record|'s [=/value=].
1. Let |value| be [=ECMAScript/!=] [$StructuredDeserialize$](|serialized|, |targetRealm|).
1. [=list/Append=] « |key|, |value| » to |list|.

</dl>

1. Return |list|.

</div>

Expand All @@ -5802,29 +5876,6 @@ with |targetRealm|, |index| and |range|, run these steps:

</div>


<div algorithm>

To <dfn>retrieve multiple referenced values from an
index</dfn> with |targetRealm|, |index|, |range| and optional |count|, run these steps:

1. If |count| is not given or is 0 (zero), let |count| be infinity.

1. Let |records| be a list containing the first |count| [=object-store/records=]
in |index|'s [=index/list of records=] whose [=index/key=] is [=in=] |range|.

1. Let |list| be an empty [=/list=].

1. [=list/For each=] |record| of |records|:

1. Let |serialized| be |record|'s [=index/referenced value=].
1. Let |entry| be [=ECMAScript/!=] [$StructuredDeserialize$](|serialized|, |targetRealm|).
1. Append |entry| to |list|.

1. Return |list| converted to a <code>[=/sequence=]&lt;{{any}}&gt;</code>.

</div>

<aside class=note>
The [=index/values=] of an [=index/record=] in an index are the keys of
[=object-store/records=] in the [=index/referenced=] object store.
Expand All @@ -5848,26 +5899,46 @@ To <dfn>retrieve a value from an index</dfn> with

<div algorithm>

To <dfn>retrieve multiple values from an index</dfn> with
|index|, |range| and optional |count|, run these steps:
To <dfn>retrieve multiple items from an index</dfn> with |targetRealm|, |index|, |range|, |kind| and optional |count|, run these steps:

1. If |count| is not given or is 0 (zero), let |count| be infinity.

1. Let |records| be a list containing the first |count| [=index/records=] in
|index|'s [=index/list of records=] whose [=index/key=] is [=in=] |range|.
1. Let |records| be a list containing the first |count| [=object-store/records=] in |index|'s [=index/list of records=] whose [=index/key=] is [=in=] |range|.

1. Let |list| be an empty [=/list=].

1. [=list/For each=] |record| of |records|:
1. [=list/For each=] |record| of |records|, switching on |kind|:

1. Let |entry| be the result of [=/converting a
key to a value=] with |record|'s value.
1. Append |entry| to |list|.
<dl class=switch>
: "key"
::
1. Let |key| be the result of [=/converting a key to a value=] with |record|'s value.
1. [=list/Append=] |key| to |list|.

1. Return |list| converted to a <code>[=/sequence=]&lt;{{any}}&gt;</code>.
: "value"
::
1. Let |serialized| be |record|'s [=index/referenced value=].
1. Let |value| be [=ECMAScript/!=] [$StructuredDeserialize$](|serialized|, |targetRealm|).
1. [=list/Append=] |value| to |list|.

: "key+value+indexKey"
::
1. Let |key| be the result of [=/converting a key to a value=] with |record|'s value.
1. Let |indexKey| be the result of [=/converting a key to a value=] with |record|'s key.
1. Let |serialized| be |record|'s [=index/referenced value=].
1. Let |value| be [=ECMAScript/!=] [$StructuredDeserialize$](|serialized|, |targetRealm|).
1. [=list/Append=] « |key|, |value|, |indexKey| » to |list|.

</dl>

1. Return |list|.

</div>

<aside class=note>
The [=index/values=] of a [=index/record=] in an index are the keys of [=object-store/records=] in the [=index/referenced=] object store.
</aside>


<!-- ============================================================ -->
## Object store deletion operation ## {#object-store-deletion-operation}
Expand Down Expand Up @@ -6781,6 +6852,7 @@ For the revision history of the second edition, see [that document's Revision Hi
* Specified [[#transaction-scheduling]] more precisely and disallow starting read/write transactions while read-only transactions with overlapping scope are running. ([Issue #253](https://github.com/w3c/IndexedDB/issues/253))
* Added <a href="#accessibility">Accessibility considerations</a> section. ([Issue #327](https://github.com/w3c/IndexedDB/issues/327))
* Used [[infra]]'s list sorting definition. ([Issue #346](https://github.com/w3c/IndexedDB/issues/346))
* Added object store {{IDBObjectStore/getAllEntries()}} and index {{IDBIndex/getAllEntries()}} methods. ([Issue #206](https://github.com/w3c/IndexedDB/issues/206))

<!-- ============================================================ -->
# Acknowledgements # {#acknowledgements}
Expand Down