-
Notifications
You must be signed in to change notification settings - Fork 62
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
getAll()
with both key and value (or index key and primary key)
#206
Comments
A good name surfaced over in WICG/kv-storage#63 -
... which sort-of aligns with ECMAScript's array iterators: It would produce an array of two-element arrays. |
Which could nicely be fed into |
Object stores are easy:
Indexes are less straightforward:
Having getAllEntries() on an Index produce |
I put a PR up for a straightforward version of |
TPAC 2019 Web Apps breakout:
Follow-up: refine proposal for indexes |
Staring at this a bit more, I'd be tempted to have indexes produce:
i.e. if you only pay attention to the first two elements, this looks just like getAllEntries() and can be used with Map constructor. If you need the index key it's there. |
Sketching this out a bit more: store.getAllEntries({
query: key_or_range,
count: limit,
direction: next_or_prev
});
// yields: [ [ key1, value1 ], [ key2, value2 ], ... ]
index.getAllEntries({
query: key_or_range,
count: limit,
direction: next_or_prev
});
// yields: [ [ primaryKey1, value1, indexKey1 ], [ primaryKey2, value2, indexKey2 ], ... ] Note that this still doesn't allow trivial paging of results i.e. with a "skip".
|
By default IndexedDb seems to store by ascending order, so I guess prev would be descending or reverse order. This should be fairly straightforward to do with leveldb, I have the changes locally (albeit against an earlier version of chromium) if this change has traction, then am willing to go ahead and open a PR for chromium to add it in, need to see what should be done for FF/Webkit browsers though. On a related note, this is something that would be extremely useful with messaging apps, by default we store messages in ascending time order (next cursor) but we often need to show them in descending time order in the UI (latest message first or by using the prev cursor). |
For the index case, in my opinion, option 2 (indexKey, primaryKey) would be best, as this option would allow us to obtain the index keys for a range without the overhead of fetching full values. I am not sure if this is covered by "key" value for the "query" option? Would be great if this could be clarified! |
TPAC 2024: We discussed the getAllEntries() proposal referenced above, which we agreed is a good addition that should not be complex for browsers to implement. We discussed how this proposal addresses some of the limitations reported by developers in this issue, including:
I've published an explainer that goes into more detail. |
the spec consistently uses the term "record" rather than "entry". @inexorabletash wdyt of |
Also, why: |
For both of the above comments (naming, structure) I was heavily influenced by ECMAScript's Map.prototype.entries(), which was designed to play well with the (at the time) newly introduced destructuring syntax i.e.: ... and if I recall correctly, this was before JS supported destructuring of objects, i.e. Revisiting the proposed API to improve ergonomics is fine! Consistency with JS should be a factor, but not foolish consistency. |
+1 about "record" being a better term for |
Fair points by @abhishek-shanthkumar On naming: IDBIndex's On form:
I think we are aligned on that function but perhaps not the form. It seems to me a bit unclean thing to return an array of a particular length where you just have to know which element is which thing, as opposed to an object such as
or
|
A few comments:
Here are a few options we could consider for the form of the results:
Advantages:
Disadvantages:
[
{ 'key': key1, 'primaryKey': primaryKey1, 'value': value1 },
{ 'key': key2, 'primaryKey': primaryKey2, 'value': value2},
...
] Like an Continuing the example above, developers would use the following to access the value of the second record: Like @inexorabletash pointed out above, developers have a lot of flexibility when using Array.map() with destructuring. For example, developers can construct a // Transform the results from `getAllRecords()` into an array of entries:
// [ [ primaryKey1, { 'value': value1, 'indexKey': indexKey1 }], [ primaryKey2, { 'value': value2, ... ], ... ]
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. |
Conclusions above SGTM.
Isn't the IDBCursorWithValue already more or less the record (or a superset of the record)? We could maybe add an |
Is there something that distinguishes an IDB "record" from the "entries" in |
Also, while "record" is a spec term, I don't think it has made it into the API yet so there isn't a consistency argument. |
My main argument here is that the spec and MDN (e.g.) both consistently use the term "record". Other spec terms tend to map directly into the API symbol names. To do otherwise would make it harder to reference the spec or MDN as documentation. But you are correct that if only looking at API symbol names, "record" hasn't been used yet.
Here are a few:
An IDB record is still conceptually a key/value pair, but "record" I think more strongly evokes exactly what it is, i.e. a "row in a database", than does "entry". TBH, either term work, so it feels like a bit of a bike shed and it's probably not possible to make a wrong decision here, but what is the concrete advantage of using "entry"? |
As a cursor replacement,
getAll()
/getAllKeys()
has the issue that you need to pick - you can't get both the key and the value. For object stores this isn't so bad if inline keys are used, but still awkward. For indexes you can't even get the primary key.Here's an example where
getAll()
could help but needs index key and primary keyhttps://stackoverflow.com/questions/44349168/speeding-up-indexeddb-search-with-multiple-workers
The text was updated successfully, but these errors were encountered: