indexeddb: Implement openCursor and openKeyCursor for object store (#39080)

Continue on implementing indexeddb's cursor.

This patch focuses on implementing the `openCursor` [1] and
`openKeyCursor` [2] methods of the `IDBObjectStore` interface, which
create and initialize cursors by running the iterate-a-cursor algorithm
[3].

It also adds struct `IndexedDBRecord` to
`components/shared/net/indexeddb_thread.rs`. This struct can later be
used to implement the new `IDBRecord` interface [4].

[1] https://www.w3.org/TR/IndexedDB-2/#dom-idbobjectstore-opencursor
[2] https://www.w3.org/TR/IndexedDB-2/#dom-idbobjectstore-openkeycursor
[3] https://www.w3.org/TR/IndexedDB-2/#iterate-a-cursor
[4] https://w3c.github.io/IndexedDB/#record-interface

Testing: Pass WPT tests that were expected to fail.
Fixes: Part of #38111

---------

Signed-off-by: Kingsley Yung <kingsley@kkoyung.dev>
This commit is contained in:
Kingsley Yung 2025-09-13 00:54:07 +08:00 committed by GitHub
parent 1f63116bdd
commit 250c4cda00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 580 additions and 279 deletions

View file

@ -1,7 +1,4 @@
[idbcursor-advance-exception-order.any.worker.html]
[IDBCursor.advance exception order: TypeError vs. TransactionInactiveError]
expected: FAIL
[IDBCursor.advance exception order: TransactionInactiveError vs. InvalidStateError #1]
expected: FAIL
@ -13,9 +10,6 @@
expected: ERROR
[idbcursor-advance-exception-order.any.html]
[IDBCursor.advance exception order: TypeError vs. TransactionInactiveError]
expected: FAIL
[IDBCursor.advance exception order: TransactionInactiveError vs. InvalidStateError #1]
expected: FAIL

View file

@ -1,39 +1,9 @@
[idbcursor-direction.any.worker.html]
[IDBCursor.direction - undefined]
expected: FAIL
[IDBCursor.direction - next]
expected: FAIL
[IDBCursor.direction - prev]
expected: FAIL
[IDBCursor.direction - nextunique]
expected: FAIL
[IDBCursor.direction - prevunique]
expected: FAIL
[idbcursor-direction.any.serviceworker.html]
expected: ERROR
[idbcursor-direction.any.html]
[IDBCursor.direction - undefined]
expected: FAIL
[IDBCursor.direction - next]
expected: FAIL
[IDBCursor.direction - prev]
expected: FAIL
[IDBCursor.direction - nextunique]
expected: FAIL
[IDBCursor.direction - prevunique]
expected: FAIL
[idbcursor-direction.any.sharedworker.html]
expected: ERROR

View file

@ -2,23 +2,11 @@
expected: ERROR
[idbcursor-key.any.worker.html]
[IDBCursor.key]
expected: FAIL
[IDBCursor.key 1]
expected: FAIL
[IDBCursor.key 2]
expected: FAIL
[idbcursor-key.any.html]
[IDBCursor.key]
expected: FAIL
[IDBCursor.key 1]
expected: FAIL
[IDBCursor.key 2]
expected: FAIL

View file

@ -5,9 +5,6 @@
[object store - iterate cursor number of times specified by count]
expected: FAIL
[Calling advance() with count argument 0 should throw TypeError.]
expected: FAIL
[Calling advance() should throws an exception TransactionInactiveError when the transaction is not active]
expected: FAIL
@ -22,9 +19,6 @@
[object store - iterate cursor number of times specified by count]
expected: FAIL
[Calling advance() with count argument 0 should throw TypeError.]
expected: FAIL
[Calling advance() should throws an exception TransactionInactiveError when the transaction is not active]
expected: FAIL

View file

@ -20,9 +20,6 @@
[Throw DataCloneError]
expected: FAIL
[No argument]
expected: FAIL
[Throw DataError]
expected: FAIL
@ -49,9 +46,6 @@
[Throw DataCloneError]
expected: FAIL
[No argument]
expected: FAIL
[Throw DataError]
expected: FAIL

View file

@ -5,18 +5,3 @@
[Cross-realm IDBObjectStore::add() method from detached <iframe> works as expected]
expected: FAIL
[Cross-realm IDBObjectStore::delete() method from detached <iframe> works as expected]
expected: FAIL
[Cross-realm IDBObjectStore::clear() method from detached <iframe> works as expected]
expected: FAIL
[Cross-realm IDBObjectStore::count() method from detached <iframe> works as expected]
expected: FAIL
[Cross-realm IDBObjectStore::openCursor() method from detached <iframe> works as expected]
expected: FAIL
[Cross-realm IDBObjectStore::openKeyCursor() method from detached <iframe> works as expected]
expected: FAIL

View file

@ -11,15 +11,9 @@
[IDBObjectStore.count exception order: TransactionInactiveError vs. DataError]
expected: FAIL
[IDBObjectStore.openCursor exception order: InvalidStateError vs. TransactionInactiveError]
expected: FAIL
[IDBObjectStore.openCursor exception order: TransactionInactiveError vs. DataError]
expected: FAIL
[IDBObjectStore.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError]
expected: FAIL
[IDBObjectStore.openKeyCursor exception order: TransactionInactiveError vs. DataError]
expected: FAIL
@ -40,15 +34,9 @@
[IDBObjectStore.count exception order: TransactionInactiveError vs. DataError]
expected: FAIL
[IDBObjectStore.openCursor exception order: InvalidStateError vs. TransactionInactiveError]
expected: FAIL
[IDBObjectStore.openCursor exception order: TransactionInactiveError vs. DataError]
expected: FAIL
[IDBObjectStore.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError]
expected: FAIL
[IDBObjectStore.openKeyCursor exception order: TransactionInactiveError vs. DataError]
expected: FAIL

View file

@ -2,37 +2,8 @@
expected: ERROR
[idbobjectstore-request-source.any.worker.html]
[The source of the request from store => store.getAll() is the object store itself]
expected: FAIL
[The source of the request from store => store.getAllKeys() is the object store itself]
expected: FAIL
[The source of the request from store => store.count() is the object store itself]
expected: FAIL
[The source of the request from store => store.openCursor() is the object store itself]
expected: FAIL
[The source of the request from store => store.openKeyCursor() is the object store itself]
expected: FAIL
[idbobjectstore-request-source.any.sharedworker.html]
expected: ERROR
[idbobjectstore-request-source.any.html]
[The source of the request from store => store.getAll() is the object store itself]
expected: FAIL
[The source of the request from store => store.getAllKeys() is the object store itself]
expected: FAIL
[The source of the request from store => store.count() is the object store itself]
expected: FAIL
[The source of the request from store => store.openCursor() is the object store itself]
expected: FAIL
[The source of the request from store => store.openKeyCursor() is the object store itself]
expected: FAIL

View file

@ -1,7 +1,4 @@
[idbobjectstore_count.any.worker.html]
[Returns the number of records in the object store ]
expected: FAIL
[Returns the number of records that have keys with the key]
expected: FAIL
@ -10,9 +7,6 @@
expected: ERROR
[idbobjectstore_count.any.html]
[Returns the number of records in the object store ]
expected: FAIL
[Returns the number of records that have keys with the key]
expected: FAIL

View file

@ -2,8 +2,13 @@
expected: ERROR
[idbobjectstore_get.any.html]
[When an invalid key is used, throw DataError]
expected: FAIL
[idbobjectstore_get.any.serviceworker.html]
expected: ERROR
[idbobjectstore_get.any.worker.html]
[When an invalid key is used, throw DataError]
expected: FAIL

View file

@ -2,18 +2,9 @@
[Single item get (generated key)]
expected: FAIL
[getAll on empty object store]
expected: FAIL
[Get all values]
expected: FAIL
[Get all with large values]
expected: FAIL
[Test maxCount]
expected: FAIL
[Get upper excluded]
expected: FAIL
@ -23,15 +14,6 @@
[Get bound range (generated) with maxCount]
expected: FAIL
[zero maxCount]
expected: FAIL
[Max value count]
expected: FAIL
[Get all values with transaction.commit()]
expected: FAIL
[Get all values with invalid query keys]
expected: FAIL
@ -43,18 +25,9 @@
[Single item get (generated key)]
expected: FAIL
[getAll on empty object store]
expected: FAIL
[Get all values]
expected: FAIL
[Get all with large values]
expected: FAIL
[Test maxCount]
expected: FAIL
[Get upper excluded]
expected: FAIL
@ -64,15 +37,6 @@
[Get bound range (generated) with maxCount]
expected: FAIL
[zero maxCount]
expected: FAIL
[Max value count]
expected: FAIL
[Get all values with transaction.commit()]
expected: FAIL
[Get all values with invalid query keys]
expected: FAIL

View file

@ -5,12 +5,6 @@
[Single item get (generated key)]
expected: FAIL
[getAllKeys on empty object store]
expected: FAIL
[Get all keys]
expected: FAIL
[Test maxCount]
expected: FAIL
@ -76,12 +70,6 @@
[Single item get (generated key)]
expected: FAIL
[getAllKeys on empty object store]
expected: FAIL
[Get all keys]
expected: FAIL
[Test maxCount]
expected: FAIL

View file

@ -5,52 +5,22 @@
expected: ERROR
[idbobjectstore_getAllKeys.any.worker.html]
[getAllKeys on empty object store]
expected: FAIL
[Get all keys]
expected: FAIL
[Test maxCount]
expected: FAIL
[Get upper excluded]
expected: FAIL
[Get lower excluded]
expected: FAIL
[zero maxCount]
expected: FAIL
[Max value count]
expected: FAIL
[Get all keys with invalid query keys]
expected: FAIL
[idbobjectstore_getAllKeys.any.html]
[getAllKeys on empty object store]
expected: FAIL
[Get all keys]
expected: FAIL
[Test maxCount]
expected: FAIL
[Get upper excluded]
expected: FAIL
[Get lower excluded]
expected: FAIL
[zero maxCount]
expected: FAIL
[Max value count]
expected: FAIL
[Get all keys with invalid query keys]
expected: FAIL

View file

@ -48,6 +48,9 @@
[IDBObjectStore.getKey() - key generator and key path - range - no match]
expected: FAIL
[IDBObjectStore.getKey() - invalid parameters]
expected: FAIL
[idbobjectstore_getKey.any.html]
expected: TIMEOUT
@ -98,3 +101,6 @@
[IDBObjectStore.getKey() - key generator and key path - range - no match]
expected: FAIL
[IDBObjectStore.getKey() - invalid parameters]
expected: FAIL

View file

@ -5,12 +5,6 @@
[IDBFactory interface: operation databases()]
expected: FAIL
[IDBObjectStore interface: operation openCursor(optional any, optional IDBCursorDirection)]
expected: FAIL
[IDBObjectStore interface: operation openKeyCursor(optional any, optional IDBCursorDirection)]
expected: FAIL
[IDBObjectStore interface: operation index(DOMString)]
expected: FAIL
@ -109,12 +103,6 @@
[IDBFactory interface: operation databases()]
expected: FAIL
[IDBObjectStore interface: operation openCursor(optional any, optional IDBCursorDirection)]
expected: FAIL
[IDBObjectStore interface: operation openKeyCursor(optional any, optional IDBCursorDirection)]
expected: FAIL
[IDBObjectStore interface: operation index(DOMString)]
expected: FAIL

View file

@ -2,19 +2,8 @@
expected: ERROR
[nested-cloning-basic.any.worker.html]
[small typed array]
expected: FAIL
[blob]
expected: FAIL
[nested-cloning-basic.any.serviceworker.html]
expected: ERROR
[nested-cloning-basic.any.html]
[small typed array]
expected: FAIL
[blob]
expected: FAIL

View file

@ -2,21 +2,12 @@
[large typed array]
expected: FAIL
[blob with large typed array]
expected: FAIL
[blob with large typed array with key generator]
expected: FAIL
[array of blobs and large typed arrays]
expected: FAIL
[array of blobs and large typed arrays with key generator]
expected: FAIL
[object with blobs and large typed arrays]
expected: FAIL
[object with blobs and large typed arrays with key generator]
expected: FAIL
@ -28,21 +19,12 @@
[large typed array]
expected: FAIL
[blob with large typed array]
expected: FAIL
[blob with large typed array with key generator]
expected: FAIL
[array of blobs and large typed arrays]
expected: FAIL
[array of blobs and large typed arrays with key generator]
expected: FAIL
[object with blobs and large typed arrays]
expected: FAIL
[object with blobs and large typed arrays with key generator]
expected: FAIL

View file

@ -1,19 +1,10 @@
[nested-cloning-small.any.html]
[blob with small typed array]
expected: FAIL
[blob with small typed array with key generator]
expected: FAIL
[blob array]
expected: FAIL
[blob array with key generator]
expected: FAIL
[array of blobs and small typed arrays]
expected: FAIL
[array of blobs and small typed arrays with key generator]
expected: FAIL
@ -25,20 +16,11 @@
expected: ERROR
[nested-cloning-small.any.worker.html]
[blob with small typed array]
expected: FAIL
[blob with small typed array with key generator]
expected: FAIL
[blob array]
expected: FAIL
[blob array with key generator]
expected: FAIL
[array of blobs and small typed arrays]
expected: FAIL
[array of blobs and small typed arrays with key generator]
expected: FAIL