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

[WIP] Initial algorithms / methods for putAll #343

Draft
wants to merge 2 commits 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
163 changes: 160 additions & 3 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2711,6 +2711,8 @@ interface IDBObjectStore {
readonly attribute boolean autoIncrement;

[NewObject] IDBRequest put(any value, optional any key);
[NewObject] IDBRequest putValues(sequence<any> values);
[NewObject] IDBRequest putEntries(sequence<sequence<any>> entries);
[NewObject] IDBRequest add(any value, optional any key);
[NewObject] IDBRequest delete(any query);
[NewObject] IDBRequest clear();
Expand Down Expand Up @@ -2888,6 +2890,27 @@ and false otherwise.
If successful, |request|'s {{IDBRequest/result}} will be the
[=object-store/record=]'s [=/key=].

: |request| = |store| . {{IDBObjectStore/putValues()|putValues}}(|values|)

::
Adds or updates multiple [=object-store/records=] in |store| with the given array of |values|.

[=/Keys=] can not be explicitly specified using this method, so it can only be used with an [=/object store=] that either has a [=/key generator=] or that uses [=object-store/in-line keys=]. Otherwise, a "{{DataError}}" {{DOMException}} will be thrown.


If any [=/record=] fails to be stored, no updates will be made and the |request| will fail, with |request|'s {{IDBRequest/error!!attribute}} set to an error e.g. a "{{ConstraintError}}" {{DOMException}}.


: |request| = |store| . {{IDBObjectStore/putEntries()|putEntries}}(|entries|)

::
Adds or updates multiple [=object-store/records=] in |store| with the given array of |entries|. Each entry is a two element array with a [=/key=] and [=/value=] for the record.

This method can only be used with an [=/object store=] that uses [=object-store/out-of-line keys=]. Otherwise, a "{{DataError}}" {{DOMException}} will be thrown.

If any [=/record=] fails to be stored, no updates will be made and the |request| will fail, with |request|'s {{IDBRequest/error!!attribute}} set to an error e.g. a "{{ConstraintError}}" {{DOMException}}.


: |request| = |store| .
{{IDBObjectStore/delete()|delete}}(|query|)
::
Expand All @@ -2906,13 +2929,13 @@ and false otherwise.
</div>


The <dfn method for=IDBObjectStore>put(|value|, |key|)</dfn> method steps are to return the result of running [=add or put=] with [=/this=], |value|, |key| and the |no-overwrite flag| false.
The <dfn method for=IDBObjectStore>put(|value|, |key|)</dfn> method steps are to return the result of running [=add or put a single record=] with [=/this=], |value|, |key| and false.

The <dfn method for=IDBObjectStore>add(|value|, |key|)</dfn> method steps are to return the result of running [=add or put=] with [=/this=], |value|, |key| and the |no-overwrite flag| true.
The <dfn method for=IDBObjectStore>add(|value|, |key|)</dfn> method steps are to return the result of running [=add or put a single record=] with [=/this=], |value|, |key| and true.

<div algorithm>

To <dfn>add or put</dfn> with |handle|, |value|, |key|, and |no-overwrite flag|, run these steps:
To <dfn>add or put a single record</dfn> with |handle|, |value|, |key|, and |no-overwrite flag|, run these steps:

1. Let |transaction| be |handle|'s
[=object-store-handle/transaction=].
Expand Down Expand Up @@ -2983,6 +3006,119 @@ To <dfn>add or put</dfn> with |handle|, |value|, |key|, and |no-overwrite flag|,

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

</div>

The <dfn method for=IDBObjectStore>putValues(|values|)</dfn> method steps are to return the result of running [=add or put multiple records=] with [=/this=], |values|, and false.

<div algorithm>

The <dfn method for=IDBObjectStore>putEntries(|entries|)</dfn> method steps are:

1. Let |keys| be a new [=/list=].

1. Let |values| be a new [=/list=].

1. [=list/For each=] |entry| of |entries|:

1. If |entry|'s [=list/size=] is not 2, [=exception/throw=] a {{TypeError}}.

1. [=list/Append=] |entry|[0] to |keys|.

Note: Keys are not [=convert a value to a key|converted=] until a subsequent step.

1. [=list/Append=] |entry|[1] to |values|.

1. Return the result of running [=add or put multiple records=] with [=/this=], |values|, false, and |keys|.

</div>

<div algorithm>

To <dfn>add or put multiple records</dfn> with |handle|, |values|, |no-overwrite flag|, and optional |keys|, run these steps:

1. [=/Assert=]: If |keys| is given, |values| [=list/size=] equals |keys| [=list/size=].

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

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

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

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

1. If |transaction| is a [=transaction/read-only transaction=],
[=exception/throw=] a "{{ReadOnlyError}}" {{DOMException}}.

1. If |store| uses [=object-store/in-line keys=] and |keys| were given,
[=exception/throw=] a "{{DataError}}" {{DOMException}}.

1. If |store| uses [=object-store/out-of-line keys=] and has no [=key
generator=] and |keys| were not given, [=exception/throw=] a
"{{DataError}}" {{DOMException}}.

1. If |keys| were given, then:

1. Let |rs| be a new [=/list=].

1. [=list/For each=] |key| of |keys|:

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

1. If |r| is invalid, [=exception/throw=] a "{{DataError}}" {{DOMException}}.

1. [=list/Append=] |r| to |rs|.

1. Set |keys| to |rs|.

1. Let |targetRealm| be a user-agent defined [=ECMAScript/Realm=].

1. Let |clones| be a new [=/list=].

1. [=list/For each=] |value| of |values|:

1. Let |clone| be a [=clone=] of |value| in |targetRealm| during |transaction|.
Rethrow any exceptions.

<details class=note>
<summary>Why create a copy of the value?</summary>
The value is serialized when stored. Treating it as a copy
here allows other algorithms in this specification to treat it as
an ECMAScript value, but implementations can optimize this
if the difference in behavior is not observable.
</details>

1. [=list/Append=] |clone| to |clones|.

1. If |store| uses [=object-store/in-line keys=], then:

1. Let |keys| be a new [=/list=].

1. [=list/For each=] |clone| of |clones|:

1. Let |key| be undefined.

1. Let |kpk| be the result of [=/extracting a key from a value using a key path=] with |clone| and |store|'s [=object-store/key path=]. Rethrow any exceptions.

1. If |kpk| is invalid, [=exception/throw=] a "{{DataError}}" {{DOMException}}.

1. If |kpk| is not failure, let |key| be |kpk|.

1. Otherwise (|kpk| is failure):

1. If |store| does not have a [=key generator=], [=exception/throw=] a "{{DataError}}" {{DOMException}}.

1. Otherwise, if [=check that a key could be injected into a value=] with |clone| and |store|'s [=object-store/key path=] return false, [=exception/throw=] a "{{DataError}}" {{DOMException}}.

1. [=list/Append=] |key| to |keys|.

1. Let |operation| be an algorithm to run [=store multiple records into an object store=] with |store|, |clones|, |keys|, and |no-overwrite flag|.

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


</div>

Expand Down Expand Up @@ -5626,6 +5762,25 @@ To <dfn>store a record into an object store</dfn> with

</div>

<div algorithm>

To <dfn>store multiple records into an object store</dfn> with |store|, |values|, |keys|, and a |no-overwrite flag|, run these steps:

1. [=/Assert=]: |values| [=list/size=] equals |keys| [=list/size=].

1. Let |results| be a new [=/list=].

1. [=list/For each=] |value| of |values| and |key| of |keys|, respectively:

1. Let |r| be the result of [=/storing a record into an object store=] with |store|, |value|, |key|, and |no-overwrite flag|.

1. If |r| is an error, then undo any changes made to |store| or associated [=/indexes=] by this algorithm, and return |r|.

1. [=list/Append=] |r| to |results|.

1. Return |results|.

</div>

<!-- ============================================================ -->
## Object store retrieval operations ## {#object-store-retrieval-operation}
Expand Down Expand Up @@ -6706,6 +6861,7 @@ For the revision history of the second edition, see [that document's Revision Hi
* 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 a definition for [=transaction/live=] transactions, and renamed "run an upgrade transaction" to [=/upgrade a database=], to disambiguate "running". ([Issue #408](https://github.com/w3c/IndexedDB/issues/408))
* Added {{IDBObjectStore/putValues()}} and {{IDBObjectStore/putEntries()}} methods. ([Issue #69](https://github.com/w3c/IndexedDB/issues/69))

<!-- ============================================================ -->
# Acknowledgements # {#acknowledgements}
Expand Down Expand Up @@ -6769,6 +6925,7 @@ Marcos Cáceres,
Margo Seltzer,
Marijn Kruisselbrink,
Ms2ger,
Numfor Mbiziwo-tiapo,
Odin Omdal,
Olli Pettay,
Pablo Castro,
Expand Down
Loading