6.7. Cursor Iteration Operation

The steps to iterate a cursor with targetRealm, cursor, an optional key and primaryKey to iterate to, and an optional count are as follows.

  1. Let source be cursor’s source.

  2. Let direction be cursor’s direction.

  3. Assert: if primaryKey is given, source is an index and direction is ["next"](#dom-idbcursordirection-next) or ["prev"](#dom-idbcursordirection-prev).

  4. Let records be the list of records in source.

    records is always sorted in ascending key order. In the case of source being an index, records is secondarily sorted in ascending value order (where the value in an index is the key of the record in the referenced object store).

  5. Let range be cursor’s range.

  6. Let position be cursor’s position.

  7. Let object store position be cursor’s object store position.

  8. If count is not given, let count be 1.

  9. While count is greater than 0:

    1. Switch on direction:

      ["next"](#dom-idbcursordirection-next)

      Let found record be the first record in records which satisfy all of the following requirements:

  1. `["nextunique"](#dom-idbcursordirection-nextunique)`
  2. Let found record be the first record in records which satisfy all of the following requirements:
  3. - If key is defined, the records key is [greater than](#greater-than) or [equal to](#equal-to) key.
  4. - If position is defined, the records key is [greater than](#greater-than) position.
  5. - The records key is [in](#in) range.
  6. `["prev"](#dom-idbcursordirection-prev)`
  7. Let found record be the last record in records which satisfy all of the following requirements:
  8. - If key is defined, the records key is [less than](#less-than) or [equal to](#equal-to) key.
  9. - If primaryKey is defined, the records key is [equal to](#equal-to) key and the records value is [less than](#less-than) or [equal to](#equal-to) primaryKey, or the records key is [less than](#less-than) key.
  10. - If position is defined, and source is an [object store](#object-store), the records key is [less than](#less-than) position.
  11. - If position is defined, and source is an [index](#index-concept), the records key is [equal to](#equal-to) position and the records value is [less than](#less-than) object store position or the records key is [less than](#less-than) position.
  12. - The records key is [in](#in) range.
  13. `["prevunique"](#dom-idbcursordirection-prevunique)`
  14. Let temp record be the last record in records which satisfy all of the following requirements:
  15. - If key is defined, the records key is [less than](#less-than) or [equal to](#equal-to) key.
  16. - If position is defined, the records key is [less than](#less-than) position.
  17. - The records key is [in](#in) range.
  18. If temp record is defined, let found record be the first record in records whose key is [equal to](#equal-to) temp records key.
  19. Iterating with `["prevunique"](#dom-idbcursordirection-prevunique)` visits the same records that `["nextunique"](#dom-idbcursordirection-nextunique)` visits, but in reverse order.
  20. 2. If found record is not defined, then:
  21. 1. Set cursors [key](#cursor-key) to undefined.
  22. 2. If source is an [index](#index-concept), set cursors [object store position](#cursor-object-store-position) to undefined.
  23. 3. If cursors [key only flag](#cursor-key-only-flag) is unset, set cursors [value](#cursor-value) to undefined.
  24. 4. Return null.
  25. 3. Let position be found records key.
  26. 4. If source is an [index](#index-concept), let object store position be found records value.
  27. 5. Decrease count by 1.
  1. Set cursor’s position to position.

  2. If source is an index, set cursor’s object store position to object store position.

  3. Set cursor’s key to found record’s key.

  4. If cursor’s key only flag is unset, then:

    1. Let serialized be found record’s referenced value.

    2. Set cursor’s value to ! StructuredDeserialize(serialized, targetRealm)

  5. Set cursor’s got value flag.

  6. Return cursor.