pub struct Cursor<'a, E, X> { /* private fields */ }Expand description
A forward-only keyset cursor for streaming large tables.
Rather than OFFSET (which the database must scan past, getting slower
deeper in) or loading the whole table, the cursor remembers the last
primary key it saw and asks for WHERE pk > ? ORDER BY pk LIMIT page_size.
Every page is an index seek, so cost stays flat however deep you walk —
and only one page is in memory at a time. This is the only iteration
strategy that is also correct on D1-over-HTTP, which cannot hold a
streaming server-side cursor.
let mut cur = repo::cursor::<User, _>(&exec, 500);
while let Some(page) = cur.next_page().await? {
for user in page { /* ... */ }
}Implementations§
Source§impl<'a, E, X> Cursor<'a, E, X>
impl<'a, E, X> Cursor<'a, E, X>
Sourcepub fn after(self, pk: impl Into<Value>) -> Cursor<'a, E, X>
pub fn after(self, pk: impl Into<Value>) -> Cursor<'a, E, X>
Resume from a known primary key — the next page starts strictly after
pk. Lets a walk be checkpointed and continued across requests (e.g.
one D1 HTTP call per invocation).
Sourcepub async fn next_page(&mut self) -> Result<Option<Vec<E>>, Error>
pub async fn next_page(&mut self) -> Result<Option<Vec<E>>, Error>
Fetch the next page. Returns None once the table is exhausted. A
final short page (fewer than page_size rows) marks the end, so the
following call returns None without a wasted round-trip.
Sourcepub fn checkpoint(&self) -> Option<&Value>
pub fn checkpoint(&self) -> Option<&Value>
The primary key the next page will start strictly after, if a page has
been read. Persist this to resume the walk later via after.