You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[IndexedDB] Update getAllRecords explainer to add direction to getAll and getAllKeys (#1040)
* [IndexedDB] Update getAllRecords explainer to add direction to getAll and getAllKeys
* Address code review feedback. Update strings to use single quotes. Fix dicionary syntax error. Clarify extra count argument.
* Add Evan to acknowledgements
Copy file name to clipboardExpand all lines: IndexedDbGetAllEntries/explainer.md
+72-12Lines changed: 72 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -7,23 +7,38 @@
7
7
## Participate
8
8
9
9
-https://github.com/w3c/IndexedDB/issues/206
10
+
-https://github.com/w3c/IndexedDB/issues/130
10
11
11
12
## Introduction
12
13
13
14
[`IndexedDB`](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) is a transactional database for client-side storage. Each record in the database contains a key-value pair. [`getAll()`](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAll) enumerates database record values sorted by key in ascending order. [`getAllKeys()`](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAllKeys) enumerates database record primary keys sorted by key in ascending order.
14
15
15
16
This explainer proposes a new operation, `getAllRecords()`, which combines [`getAllKeys()`](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAllKeys) with [`getAll()`](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/getAll) to enumerate both primary keys and values at the same time. For an [`IDBIndex`](https://developer.mozilla.org/en-US/docs/Web/API/IDBIndex), `getAllRecords()` also provides the record's index key in addition to the primary key and value. Lastly, `getAllRecords()` offers a new direction option to enumerate records sorted by key in descending order.
16
17
18
+
To add the direction option to the existing `getAll()` and `getAllKeys()` operations, this explainer proposes new function overloads that accept the same argument as `getAllRecords()`: the `IDBGetAllOptions` dictionary.
19
+
17
20
## Goals
18
21
19
22
Decrease the latency of database read operations. By retrieving the primary key, value and index key for database records through a single operation, `getAllRecords()` reduces the number of JavaScript events required to read records. Each JavaScript event runs as a task on the main JavaScript thread. These tasks can introduce overhead when reading records requires a sequence of tasks that go back and forth between the main JavaScript thread and the IndexedDB I/O thread.
20
23
21
24
For batched record iteration, for example, retrieving *N* records at a time, the primary and index keys provided by `getAllRecords()` can eliminate the need for an [`IDBCursor`](https://developer.mozilla.org/en-US/docs/Web/API/IDBCursor), which further reduces the number of JavaScript events required. To read the next *N* records, instead of advancing a cursor to determine the range of the next batch, getAllRecords() can use the primary key or the index key retrieved by the results from the previous batch.
22
25
26
+
Update the existing operations `getAll()` and `getAllKeys()` to support the same query options as `getAllRecords()`, which adds direction. For some scenarios, `getAll()` and `getAllKeys()` may suffice. For example, developers may use `getAllKeys()` to defer loading values until needed. For records with inline keys, `getAll()` already retrieves both key and value.
27
+
23
28
## `IDBObject::getAllRecords()` and `IDBIndex::getAllRecords()`
24
29
25
30
This explainer proposes adding `getAllRecords()` to both [`IDBObjectStore`](https://www.w3.org/TR/IndexedDB/#idbobjectstore) and [`IDBIndex`](https://www.w3.org/TR/IndexedDB/#idbindex). `getAllRecords()` creates a new `IDBRequest` that queries its `IDBObjectStore` or `IDBIndex` owner. The `IDBRequest` completes with an array of `IDBRecord` results. Each `IDBRecord` contains the `key`, `primaryKey` and `value` attributes. For `IDBIndex`, `key` is the record's index key. For `IDBObjectStore`, both `key` and `primaryKey` return the same value. The pre-existing [`IDBCursorWithValue`](https://www.w3.org/TR/IndexedDB/#idbcursorwithvalue) interface contains the same attributes and values for both `IDBObjectStore` and `IDBIndex`. However, unlike `getAllRecords()`, a cursor may only read one record at a time.
26
31
32
+
## Adding direction to `getAll()` and `getAllKeys()`
33
+
34
+
This explainer proposes using `getAllRecords()` as feature detection for direction support in `getAllKeys()` and `getAll()`. `getAllRecords()` introduces the `IDBGetAllOptions` dictionary, which developers may also use with `getAll()` and `getAllKeys()`. Before using `IDBGetAllOptions`, developers must check for the existence of `getAllRecords()` in `IDBObjectStore` or `IDBIndex`. If developers provide both the `IDBGetAllOptions` argument and the `count` argument, the extra `count` argument is ignored like any other extra argument. The `count` property in `IDBGetAllOptions` is used instead.
35
+
36
+
## Compatibility risk
37
+
38
+
Overloading `getAll()` and `getAllKeys()` to accept the `IDBGetAllOptions` dictionary introduces compatibility risk. Prior to this proposal, when passed a dictionary argument, both `getAll()` and `getAllKeys()` throw an exception after [failing to convert the dictionary to a key range](https://w3c.github.io/IndexedDB/#convert-a-value-to-a-key-range). After the overload, `getAllKeys()` and `getAll()` will no longer throw for dictionary input. When the `IDBGetAllOptions` dictionary initializes with its default values, it creates a query that retrieves all of the keys or values from the entire database.
39
+
40
+
Since using a dictionary with `getAll()` and `getAllKeys()` is a programming error, we believe compat risk is low.
41
+
27
42
## Key scenarios
28
43
29
44
### Read multiple database records through a single request
@@ -43,7 +58,7 @@ async function get_all_records_with_promise(
43
58
// Create a read-only transaction.
44
59
constread_transaction=database.transaction(
45
60
object_store_name,
46
-
"readonly"
61
+
'readonly'
47
62
);
48
63
49
64
// Get the object store or index to query.
@@ -78,7 +93,7 @@ const records = await get_all_records_with_promise(
### Use direction with `getAllKeys()` after feature detection
201
+
202
+
`getAllRecords()` introduces the `IDBGetAllOptions` dictionary, which developers may also use with `getAll()` and `getAllKeys()`. Before using `IDBGetAllOptions`, developers must check for the existence of `getAllRecords()` in `IDBObjectStore` or `IDBIndex`.
// Fallback to a cursor with direction: 'prev' for this query.
218
+
}
219
+
```
220
+
185
221
## Considered alternatives
186
222
187
223
### `getAllEntries()`
@@ -194,14 +230,10 @@ Similar to `getAllRecords()` but [provides results as an array of entries](https
194
230
195
231
Developers may directly use the entry results to construct a `Map` or `Object` since the entry results are inspired by ECMAScript's [Map.prototype.entries()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries). However, `getAllEntries()` has unusual ergonomics, requiring indices like `0` and `1` to access the record properties like `key` and `value`. Also, IndexedDB database records do not map cleanly to ECMAScript entries. For `IDBIndex`, the results contain a third element for index key. For an alternate form, `[[ indexKey1, [ primaryKey1, value1]], [ indexKey2, [ primaryKey2, value2]], ... ]`, the index key cannot always serve as the entry's key since the index key may not be unique across all records.
196
232
197
-
### Adding direction to `getAll()` and `getAllKeys()`
198
-
199
-
This will be pursued separately. Join the discussion at https://github.com/w3c/IndexedDB/issues/130. Providing the direction option on `getAllKeys()` might be useful for reverse iteration scenarios that don't need to load every value enumerated.
200
-
201
233
## WebIDL
202
234
203
235
```js
204
-
dictionary IDBGetAllRecordsOptions {
236
+
dictionary IDBGetAllOptions {
205
237
// A key or an `IDBKeyRange` identifying the records to retrieve.
0 commit comments