async_postgres/pg_client/cursor

Server-side portal-based cursors: openCursor, fetchNext, close, and the scoped withCursor template.

Internal module: not part of the public API. Import the pg_client hub instead; what it re-exports is the supported surface (see tests/api_surface.golden).

Types

Cursor = ref object
  conn*: PgConnection
  fields*: seq[FieldDescription]
  exhausted*: bool
A server-side portal for incremental row fetching via declareCursor/fetch.

Procs

proc close(cursor: Cursor): Future[void] {....stackTrace: false, raises: [
    Exception, PgStateError, ValueError, PgQueryError, PgTypeError,
    PgProtocolError, PgConnectionError, CatchableError, PgTimeoutError,
    CancelledError, AsyncTimeoutError], tags: [RootEffect, TimeEffect],
    forbids: [].}
Close the cursor and return the connection to ready state. On timeout, the connection is retired (csClosed) unless the wire had settled (asyncdispatch always retires: the timed-out op stays on the socket). Concurrent fetchNext/close on the same cursor raises PgStateError.
proc columnIndex(cursor: Cursor; name: string): int {....raises: [PgTypeError],
    tags: [], forbids: [].}
Find the index of a column by name in a cursor.
proc fetchNext(cursor: Cursor): Future[seq[Row]] {....stackTrace: false, raises: [
    Exception, ValueError, PgStateError, PgConnectionError, PgQueryError,
    PgTypeError, PgProtocolError, CatchableError, PgTimeoutError,
    CancelledError, AsyncTimeoutError], tags: [RootEffect, TimeEffect],
    forbids: [].}
Fetch the next chunk of rows from the cursor. Returns an empty seq when the cursor is exhausted. On timeout, the connection is retired (csClosed) unless the wire had settled (asyncdispatch always retires: the timed-out op stays on the socket). A closed connection raises PgStateError after a deliberate close(), PgConnectionError after a lost one. Concurrent fetchNext/close on the same cursor raises PgStateError.
proc openCursor(conn: PgConnection; sql: string; params: seq[PgParam] = @[];
                resultFormat: ResultFormat = rfAuto; chunkSize: int32 = 100;
                timeout: Duration = ZeroDuration): Future[Cursor] {.
    ...stackTrace: false, raises: [Exception, ValueError, PgQueryError,
                                PgStateError, PgConnectionError, PgTypeError,
                                PgMessageTooLargeError, PgProtocolError,
                                CatchableError, PgTimeoutError, CancelledError,
                                AsyncTimeoutError],
    tags: [RootEffect, TimeEffect], forbids: [].}
Open a server-side cursor for streaming rows in chunks. On timeout, the connection is retired (csClosed) unless the wire had settled (asyncdispatch always retires: the timed-out op stays on the socket). Raises PgStateError / PgConnectionError on a closed connection as fetchNext does.

Templates

template withCursor(conn: PgConnection; sql: string; chunks: int32;
                    cursorName, body: untyped;
                    cursorTimeout: Duration = ZeroDuration)

Open a cursor, execute body, then close the cursor automatically. The cursor is available as cursorName inside the body.

A failure in the automatic close never masks an exception raised by body: the body error is captured and re-raised after the close attempt. (A finally block cannot be used here — on asyncdispatch a failing await in a finally replaces the in-flight exception, silently discarding the body's error.) If body succeeds, a close failure propagates to the caller.