2.10. Cursor

A cursor is used to iterate over a range of records in an index or an object store in a specific direction.

A cursor has a transaction, the transaction that was active when the cursor was created.

A cursor has a range of records in either an index or an object store.

A cursor has a source that indicates which index or an object store is associated with the records over which the cursor is iterating.

A cursor has a direction that determines whether it moves in monotonically increasing or decreasing order of the record keys when iterated, and if it skips duplicated values when iterating indexes. The direction of a cursor also determines if the cursor initial position is at the start of its source or at its end. A cursor’s direction is one of the following:

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

This direction causes the cursor to be opened at the start of the source. When iterated, the cursor should yield all records, including duplicates, in monotonically increasing order of keys.

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

This direction causes the cursor to be opened at the start of the source. When iterated, the cursor should not yield records with the same key, but otherwise yield all records, in monotonically increasing order of keys. For every key with duplicate values, only the first record is yielded. When the source is an object store or an index with the unique flag set, this direction has exactly the same behavior as ["next"](#dom-idbcursordirection-next).

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

This direction causes the cursor to be opened at the end of the source. When iterated, the cursor should yield all records, including duplicates, in monotonically decreasing order of keys.

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

This direction causes the cursor to be opened at the end of the source. When iterated, the cursor should not yield records with the same key, but otherwise yield all records, in monotonically decreasing order of keys. For every key with duplicate values, only the first record is yielded. When the source is an object store or an index with the unique flag set, this direction has exactly the same behavior as ["prev"](#dom-idbcursordirection-prev).

A cursor has a position within its range. It is possible for the list of records which the cursor is iterating over to change before the full range of the cursor has been iterated. In order to handle this, cursors maintain their position not as an index, but rather as a key of the previously returned record. For a forward iterating cursor, the next time the cursor is asked to iterate to the next record it returns the record with the lowest key greater than the one previously returned. For a backwards iterating cursor, the situation is opposite and it returns the record with the highest key less than the one previously returned.

For cursors iterating indexes the situation is a little bit more complicated since multiple records can have the same key and are therefore also sorted by value. When iterating indexes the cursor also has an object store position, which indicates the value of the previously found record in the index. Both position and the object store position are used when finding the next appropriate record.

A cursor has a key and a value which represent the key and the value of the last iterated record.

A cursor has a got value flag. When this flag unset, the cursor is either in the process of loading the next value or it has reached the end of its range. When it is set, it indicates that the cursor is currently holding a value and that it is ready to iterate to the next one.

If the source of a cursor is an object store, the effective object store of the cursor is that object store and the effective key of the cursor is the cursor’s position. If the source of a cursor is an index, the effective object store of the cursor is that index’s referenced object store and the effective key is the cursor’s object store position.

A cursor also has a key only flag, that indicates whether the cursor’s value is exposed via the API. Unless stated otherwise it is unset.