Re: [w3c/IndexedDB] `getAll()` with both key and value (or index key and primary key) (#206)

A few comments:

1) About the form `{ key: value }`, I don't think this will work for [all types of IndexedDB keys](https://www.w3.org/TR/IndexedDB/#key-construct).  For example, binary keys and array keys may cause issues.

2) For consistency, should we add a `record` property to [`IDBCursorWithValue`](https://www.w3.org/TR/IndexedDB/#idbcursorwithvalue)?  This property could return the same type as the equivalent value in the `getAllRecords()` result array?

Here are a few options we could consider for the form of the results:

1) Continuing with `getAllEntries()`, update `IDBIndex::getAllEntries()` to return an array of nested entries:

 `[[ indexKey1, [ primaryKey1, value1]], [ indexKey2, [ primaryKey2, value2]], ... ]`

Advantages:
* Consistency: `getAllEntries()` returns an array of entries for both `IDBObjectStore` and `IDBIndex`.
* Compatible with existing ECMAScript entries. Like @inexorabletash pointed out above, developers may directly use the results to construct [a Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries) or Object.

Disadvantages:
* Duplicate keys exist in the entries array for indexes with non-unique keys.
* Unusual ergonomics.  Like @evanstade pointed out above; to access the value of the second record, developers would use `results[1][1][1]`, which is not very intuitive.

2) Synthesizing the comments above with the [existing IDBCursor interface](https://www.w3.org/TR/IndexedDB/#idbcursor), I propose the following form: 

`[  {  'key': key1, 'primaryKey': primaryKey1, 'value': value1 }, {  'key': key2, 'primaryKey': primaryKey2, 'value': value2}, ... ]`

Like an `IDBCursor`, for `IDBObjectStore`, `key` and `primaryKey` return the same value, which is the record's primary key.  For `IDBIndex`, `key` returns the index key while `primaryKey` returns the record's primary key.

Continuing the example above, developers would use the following to access the value of the second record: `results[1].value`.

Like @inexorabletash pointed out above, developers have a lot of flexibility when using Array.map() with destructuring.  For example, developers can construct a `Map`:
```
// Transform the results from `getAllRecords()` into an array of entries: 
// [ [ primaryKey1, { 'value': value1, 'indexKey': indexKey1 }], [ primaryKey2, { 'value': value2, 'indexKey': indexKey2 }], ... ]
const map = new Map(get_all_records_results.map(({primaryKey, value, key}) => [primaryKey, { value, 'indexKey': key}]));

// Use the map to access record values and index keys.
const value = map.get(primaryKey).value; 
const indexKey = map.get(primaryKey).indexKey; 
```

I plan to update the explainer and prototype to use this format, but feedback is very welcome!  I'm happy to continue to iterate.  

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3c/IndexedDB/issues/206#issuecomment-2430128633
You are receiving this because you are subscribed to this thread.

Message ID: <w3c/IndexedDB/issues/206/2430128633@github.com>

Received on Tuesday, 22 October 2024 19:53:20 UTC