glindex/cursor
Cursor-based iteration over store or index records.
Cursors let you walk through a range of records one at a time, optionally
mutating or deleting each one as you go. They are opened via
glindex/store.open_cursor and
glindex/index.open_cursor.
The iteration model is accumulator-based: your handler receives the current
accumulator and the cursor, and returns a Promise of the new accumulator
paired with a navigation instruction. Use cursor.continue() to advance,
cursor.stop() to finish early, or cursor.advance(n) to skip ahead.
The final accumulator is returned as the Result of the cursor call.
Transaction lifetime warning: the same rule as for regular operations
applies inside a cursor handler - do not await anything unrelated to the
database (HTTP requests, timers, etc.) between cursor steps, or the
transaction will auto-close and the next step will fail with
TransactionInactiveError.
Example
use result <- promise.await(
store.open_cursor(tx, s, glindex.All, cursor.Next, [], fn(acc, cur) {
case cursor.cursor_value(cur) {
Ok(track) -> promise.resolve(#([track, ..acc], cursor.continue()))
Error(_) -> promise.resolve(#(acc, cursor.stop()))
}
}),
)
Types
The cursor handle passed to your iteration handler.
pub type Cursor(has_value, mode, source, t, p, k)
The direction in which the cursor walks through the records.
Next- ascending key order, visiting all records.Prev- descending key order, visiting all records.NextUnique- ascending key order, skipping duplicate index keys.PrevUnique- descending key order, skipping duplicate index keys.
pub type CursorDirection {
Next
Prev
NextUnique
PrevUnique
}
Constructors
-
Next -
Prev -
NextUnique -
PrevUnique
Errors that can occur inside a cursor handler.
pub type CursorError {
UnableToDecode(List(decode.DecodeError))
CursorUnknownError(String)
}
Constructors
-
UnableToDecode(List(decode.DecodeError)) -
CursorUnknownError(String)
Opaque instruction returned from a cursor handler to control iteration.
Construct one with continue, advance, stop, continue_key, or
continue_primary_key.
pub opaque type CursorNext(source, p, k)
Values
pub fn advance(n: Int) -> CursorNext(source, p, k)
Skip forward n records from the current position.
pub fn continue() -> CursorNext(source, p, k)
Advance to the next record in the current direction.
pub fn continue_key(key: k) -> CursorNext(source, p, k)
Jump to the first record whose key is greater than or equal to key.
pub fn continue_primary_key(
key: k,
primary_key: p,
) -> CursorNext(@internal IndexCursor, p, k)
Jump to the record with the given index key and primary key.
Only valid for index cursors (IndexCursor). Useful for efficiently
seeking within a sorted index without visiting every intermediate record.
pub fn cursor_delete(
cursor: Cursor(
@internal WithValue,
@internal ReadWrite,
source,
t,
p,
k,
),
) -> promise.Promise(Result(Nil, CursorError))
Delete the record at the current cursor position.
Only available on read-write cursors (ReadWrite) that carry a value
(WithValue).
pub fn cursor_direction(
cursor: Cursor(value, mode, source, t, p, k),
) -> CursorDirection
Return the direction the cursor is walking.
pub fn cursor_key(
cursor: Cursor(value, mode, source, t, p, k),
) -> Result(k, CursorError)
Return the key of the record at the current cursor position.
pub fn cursor_primary_key(
cursor: Cursor(value, mode, source, t, p, k),
) -> Result(p, CursorError)
Return the primary key of the record at the current cursor position.
For store cursors this is the same as cursor_key. For index cursors it
is the underlying record key in the object store, which may differ from
the indexed key.
pub fn cursor_update(
cursor: Cursor(
@internal WithValue,
@internal ReadWrite,
source,
t,
p,
k,
),
value: t,
) -> promise.Promise(Result(Nil, CursorError))
Replace the record at the current cursor position with value.
Only available on read-write cursors (ReadWrite) that carry a value
(WithValue). The key of the record does not change. value is serialized
using the to_value function from the store definition.
pub fn cursor_value(
cursor: Cursor(@internal WithValue, mode, source, t, p, k),
) -> Result(t, CursorError)
Decode and return the record at the current cursor position.
Only available on cursors opened with store.open_cursor or
index.open_cursor (WithValue). Key-only cursors do not carry the record
value and cannot call this function.
pub fn stop() -> CursorNext(source, p, k)
Stop iteration and return the current accumulator.