Sign in

    #Postgres Pool

    Single-event-loop PostgreSQL connection pooling for MoonBit.

    Package path: moonbit-community/postgres/pgpool.

    The package supports native and classic wasm. WasmGC is intentionally excluded because pooled clients require the socket/TLS transport.

    Each physical @client.Client is single-flight. The pool supplies concurrency by checking out different sessions, while preserving FIFO execution within one callback-scoped Session.

    #Quick Start

    For ordinary fully consumed operations, call the pool directly:

    ///|
    async fn _pool_quick_start(
    host : String,
    user : String,
    database : String,
    password : String,
    ) -> Unit {
    @async.with_task_group(group => {
    let config = @pgpool.Config::Config(
    [@pgpool.ConnectionTarget(host~)],
    user~,
    dbname=database,
    password~,
    application_name="my-service",
    pool=PoolConfig(4),
    )
    let (pool, executor) = @pgpool.Pool::create(config)
    let task = group.spawn(no_wait=true, () => executor.run())
    pool.ready()
    let value : Int32 = pool
    .query_one("select 1::int4 as value")
    .get_name("value")
    ignore(value)
    pool.close()
    task.wait()
    })
    }

    Pool-level operations automatically checkout, use, and return a connection:

    • query_all, query_one, query_opt, and query_typed_all
    • execute and batch_execute
    • check_connection
    • with_transaction

    There is no manual get / release / detach_raw API.

    #Session-Scoped Work

    Use Pool::with_session when several operations must use the same PostgreSQL session:

    ///|
    async fn _session_example(pool : @pgpool.Pool) -> Int32 {
    pool.with_session(session => {
    session.batch_execute("set application_name = 'pool-example'")
    session.query_one("select 42::int4 as value").get_name("value")
    })
    }

    Session replaces the former pooled Client name. A session is valid only during its callback. Captured handles used afterwards raise PoolError::ScopeExpired.

    Calls submitted through one Session execute FIFO. A prepared-statement callback may use the same Session for other SQL or nested with_prepared calls. Transaction, streaming/COPY, and cancellable callbacks keep an exclusive session operation until their protocol work finishes, so use the capability passed to those callbacks.

    Pool, Session, Transaction, Operation, PreparedStatement, and GenericClient::execute return affected row counts as UInt64. COPY IN finish() and QuerySummary.row_count also use UInt64. Commands without a count return zero; missing, invalid, or overflowing counted command tags propagate ClientError::Protocol from the client.

    #Transactions

    Pool and session transaction helpers reserve one physical connection for the callback:

    ///|
    async fn _pool_transaction(pool : @pgpool.Pool) -> Unit {
    pool.with_transaction(tx => {
    ignore(tx.execute("update accounts set active = true"))
    ()
    })
    }

    Pool transaction options use the client isolation enum re-exported as @pgpool.IsolationLevel. Use its ReadUncommitted, ReadCommitted, RepeatableRead, or Serializable constructors directly, selecting from four fixed SQL spellings:

    ///|
    async fn _pool_serializable_transaction(pool : @pgpool.Pool) -> Unit {
    pool.with_transaction(
    _tx => (),
    options=@pgpool.TransactionOptions(
    isolation_level=@pgpool.IsolationLevel::Serializable,
    ),
    )
    }

    On normal callback return, the helper commits only if the transaction is still open; an explicit commit or rollback prevents a second completion. If the callback raises or is cancelled, it rolls back best-effort when the transaction is still open. Nested transactions use savepoints. Rollback cleanup is protected from cancellation, including the wait for in-flight operations. A captured Transaction is expired when its callback completes.

    with_savepoint(name, ...) quotes name as a case-sensitive PostgreSQL identifier. Spaces, double quotes, semicolons, and Unicode are supported. Empty names and names containing NUL raise the client's InvalidSavepointName error before SQL is sent; the parent remains usable.

    Cancellation received while SQL is waiting for a response propagates after protected protocol cleanup and before automatic commit. This includes nested savepoints. If cancellation arrives during BEGIN or SAVEPOINT, successful creation is rolled back before releasing the session or parent scope. A COMMIT already sent still completes according to PostgreSQL's response.

    #Streaming And COPY

    Low-level protocol handles are callback-scoped so the pool can restore the connection before reuse:

    • Session::with_stream and with_typed_stream receive @client.RowStream
    • Session::with_simple_query receives @client.SimpleQueryStream
    • Session::with_copy_in receives @client.CopyInSink
    • Session::with_copy_out receives @client.CopyOutStream

    The callbacks may consume, finish, abort, or detach their handles. They remain cancellable while waiting for application work. On callback exit, the pool drains streams or aborts unfinished COPY input before recycling the connection; task cancellation may therefore wait for an in-flight database response. There are no duplicate pgpool stream, portal, or COPY wrapper types.

    An aborted connection's detached drain saves ClientError::Closed, which an explicit finish() rethrows. Expected closure does not fail other connections in the same task group; unexpected protocol errors still propagate.

    #Prepared Statements And Cache

    Session::with_prepared and with_prepared_typed provide a scoped PreparedStatement. It supports fully consumed query/execute helpers and with_stream; explicit bind, pooled portals, and manual close are not exposed. Inspect inferred parameter and result metadata through its read-only params() and columns() views. Use to_owned() for an editable copy. The callback remains cancellable and does not hold the Session operation lock. On exit, the scope rejects new calls, waits for calls already started, then closes a temporary or evicted statement. Transaction-scoped prepared callbacks remain exclusive to their transaction.

    Ordinary query, execute, and streaming helpers use prepared statements cached automatically per physical connection. Configure the LRU capacity through PoolConfig::PoolConfig:

    ///|
    fn _pool_config() -> @pgpool.PoolConfig raise {
    PoolConfig(
    8,
    statement_cache_capacity=100,
    timeouts=Timeouts(wait_ms=Some(500)),
    queue_mode=@pgpool.QueueMode::fifo(),
    recycling_method=@pgpool.RecyclingMethod::verified(),
    )
    }

    The default capacity is 100. Set it to 0 to disable caching; negative values raise PoolError::InvalidConfig. Cache entries are local to one physical connection. Typed parameter arrays are copied when inserted, so later caller mutation cannot rewrite a cache key. There are no public cache-manager or cache-handle APIs. Clean recycling preserves prepared statements and their cached plans, keeping the connection-local cache reusable across checkouts.

    Invalid-statement SQLSTATE 26000 and unsupported-plan SQLSTATE 0A000 invalidate the affected entry and propagate the original database error. The pool does not retry automatically inside a transaction.

    #Operation-Scoped Cancellation

    Use Session::run_cancellable when cancellation must be tied to one pooled operation:

    ///|
    async fn _cancellable(pool : @pgpool.Pool) -> Unit {
    @async.with_task_group(group => {
    ignore(
    pool.with_session(session => {
    session.run_cancellable((op, token) => {
    group.spawn_bg(no_wait=true, () => {
    @async.sleep(50)
    token.cancel()
    })
    let value : Int32 = op
    .query_one("select pg_sleep(5), 1::int4 as value")
    .get_name("value")
    ignore(value)
    })
    }),
    ) catch {
    _ => ()
    }
    })
    }

    OperationCancelToken is best-effort and becomes inert when its callback ends, preventing a stale token from cancelling work performed by a later borrower.

    The run_cancellable callback remains cancellable while waiting for application work. Before releasing its exclusive session operation, the scope waits for in-flight requests and any cancel packet already being sent.

    Queued requests keep FIFO order while waiting for a previous cancel send to finish. The next request is marked active only after that wait, so a delayed cancel cannot spill into the next request. Cancelling a waiter releases its place and any acquired operation lock.

    Ordinary task cancellation waits for required protocol cleanup and rollback; it does not automatically send a PostgreSQL cancellation request or retry SQL. Cancellation is checked again when the outermost protected operation ends. Explicit caller protection defers cancellation further. Use explicit abort() on a raw client when the physical connection must be stopped immediately.

    #Configuration

    pgpool.Config takes a non-empty array of ConnectionTarget records. Each record supplies a host, a hostaddr, or both, plus its own port (default 5432). If both addresses are present, the client connects to hostaddr and uses host for TLS hostname verification. The order of records is the order of connection attempts unless host load balancing is enabled.

    Config::Config validates every address and port, the user and database names, and TLS settings before the pool is created. A target needs at least one non-empty address, and its port must be in 1..65535. Errors identify the zero-based target index. The constructor copies the supplied array; targets() returns a read-only view of that snapshot. Common authentication, TLS, startup, TargetSessionAttrs, host load balancing, and PoolConfig options stay on the outer config. The Debug output for a config shows <hidden> in place of a configured password; a missing password remains None.

    PoolConfig controls:

    • max_size
    • checkout/create/recycle timeouts
    • FIFO or LIFO idle-connection selection
    • fast, verified, clean, or custom recycling
    • per-connection statement-cache capacity
    • shared asynchronous-message capacity (256 by default)

    Read the current timeout settings from pool.config().timeouts.

    The default Fast mode sends no cleanup SQL when an idle connection is checked out. On every Session return, the pool checks the client's latest ReadyForQuery status. A connection still in an active (T) or failed (E) transaction is discarded, along with its statement cache, instead of being offered to the next borrower. The pool does not issue an automatic ROLLBACK. Idle connections retain session state such as SET values and LISTEN subscriptions under Fast; select Clean when that state must be cleared.

    Dangerous operation: changing client_encoding away from UTF-8 can cause decode failures or silently store incorrect text. Keep it at UTF-8 throughout each pooled session's lifetime. The client currently does not reject encoding changes; see the client encoding warning.

    PoolOptions provides post_create, pre_recycle, and post_recycle hooks. Hooks receive an Operation that expires when the callback ends. Queries and commands issued through it finish before the next borrower uses the connection. Hooks must leave the connection transaction idle. A post_create hook that leaves a transaction open raises PoolError::HookLeftOpenTransaction and discards the connection; recycle hooks discard the connection and retry with a new one. Custom Connector remains a low-level entry that returns a raw Client.

    Pool::next_message() reads notices, notifications, and parameter changes from one shared bounded buffer. Each PoolAsyncMessage includes a unique physical connection_id and the message. Use one consumer. When the buffer fills, the oldest message is discarded and Pool::dropped_async_messages() increases. PoolConfig::PoolConfig accepts a positive async_message_capacity; the default is 256. After Pool::close(), buffered messages can still be read, then next_message() returns None. An idle listening connection delivers notifications without another checkout.

    Create and recycle deadlines are hard for client I/O: when either expires, the pool first calls Client::abort() on the candidate physical connection and then reports PoolError::Timeout(Create) or retires the timed-out recycle candidate. Custom connector code before it returns a Client, and hook code that does not perform client I/O, must still cooperate with ordinary task cancellation.

    If checkout is cancelled during recycling, including either recycle hook, the pool discards that connection and its statement cache and restores the reserved capacity slot. A later checkout can open a replacement connection.

    A custom Connector receives a @client.Config and returns a (@client.Client, @client.ClientExecutor) pair. The pool executor starts the physical executor and checkout waits for client.ready().

    #Lifecycle And Errors

    Pool::create() does not open a socket. Spawn the single-use PoolExecutor::run() and await pool.ready() before use. A repeated run() raises PoolError::ExecutorAlreadyStarted. Pool::close() rejects new operations and closes idle connections. Active callbacks are allowed to finish; their physical connections close instead of returning to the idle set. Await the executor task to know that all connections have stopped. Pool executor cancellation or an unexpected pool maintenance failure closes the whole pool. An individual physical connection failure closes that client; the pool discards it on return or on its next checkout and can create a replacement.

    Pool::resize() never interrupts checked-out sessions. When shrinking cannot remove enough currently available capacity tokens, the pool records resize debt; later failed checkouts and session returns repay that debt before making tokens available. Expanding first cancels debt and adds only the remaining capacity, preventing shrink/expand races from exceeding the configured maximum.

    PoolError is limited to pool lifecycle:

    • Closed
    • ExecutorAlreadyStarted
    • Timeout
    • ScopeExpired
    • InvalidConfig

    Database, decoding, and row-count errors are propagated as @client.ClientError.

    IsolationLevel

    Re-export the client isolation level for pooled transaction options.

    GenericClient

    pub(open) trait GenericClient {
    async fn query_all(Self, String, params? : Array[&
    ToSql
    ]) -> Array[
    Row
    ]
    async fn query_one(Self, String, params? : Array[&
    ToSql
    ]) ->
    Row

    async fn query_opt(Self, String, params? : Array[&
    ToSql
    ]) ->
    Row
    ?
    async fn query_typed_all(Self, String, Array[
    Type
    ], params? : Array[&
    ToSql
    ]) -> Array[
    Row
    ]
    async fn execute(Self, String, params? : Array[&
    ToSql
    ]) -> UInt64
    async fn batch_execute(Self, String) -> Unit
    async fn check_connection(Self) -> Unit
    }

    Shared high-level query surface implemented by pools, sessions, and pooled transactions.

    Implementors provide fully materialized query helpers that are safe to use without handling raw protocol streams directly.

    ConfigError

    pub suberror ConfigError {
    UsernameEmpty
    DbnameEmpty
    InvalidConfig(String)
    } derive(Eq,
    Debug
    )

    Failures raised while validating declarative pool input.

    These errors are reported before the pool opens any physical connection.

    PoolError

    pub suberror PoolError {
    Closed
    ExecutorAlreadyStarted
    Timeout(TimeoutKind)
    ScopeExpired
    HookLeftOpenTransaction
    InvalidConfig(String)
    } derive(Eq,
    Debug
    )

    Failures raised by pool lifecycle, checkout, and scoped-handle operations.

    ScopeExpired reports use-after-scope on pooled handles, Closed rejects new checkouts after Pool::close(), and Timeout identifies the checkout phase that expired.

    Config

    pub struct Config {
    user : String
    password : String?
    dbname : String
    options : String?
    application_name : String
    ssl_mode :
    SslMode
    ?
    ssl_root_cert : String?
    channel_binding :
    ChannelBinding
    ?
    connect_timeout_ms : Int?
    keepalives : Bool?
    keepalives_idle_s : Int?
    target_session_attrs : TargetSessionAttrs?
    load_balance_hosts : LoadBalanceHosts?
    pool : PoolConfig
    // private fields
    } derive(Eq)

    Declarative input used to derive one pool and its connection targets.

    The constructor validates all endpoints and common connection settings. Its Debug representation replaces a configured password with <hidden>.
    impl Debug for Config

    Config::Config

    fn Config::Config(targets : Array[ConnectionTarget], user~ : String, dbname? : String, password? : String, ssl_mode? :
    SslMode
    , ssl_root_cert? : String, channel_binding? :
    ChannelBinding
    , application_name~ : String, options? : String, connect_timeout_ms? : Int, keepalives? : Bool, keepalives_idle_s? : Int, target_session_attrs? : TargetSessionAttrs, load_balance_hosts? : LoadBalanceHosts, pool~ : PoolConfig) -> Config raise

    Build a pool config from an ordered, non-empty list of endpoints.

    The target array is copied. Defaults keep the secure client path: ssl_mode = VerifyFull and dbname = user.

    Config::get_connection_targets

    Build one client config per endpoint, preserving the configured order.

    Each target connects to its own address and port. When both addresses are present, the client connects to hostaddr and verifies TLS against host.

    Config::get_pool_config

    fn Config::get_pool_config(self : Config) -> PoolConfig raise

    Return the validated pool-capacity config for this declarative input.

    Config::targets

    fn Config::targets(self : Config) -> ArrayView[ConnectionTarget]

    Return a read-only view of the configured endpoints in connection order.

    ConnectionTarget

    pub struct ConnectionTarget {
    host : String?
    hostaddr : String?
    port : Int
    } derive(Eq,
    Debug
    )

    One PostgreSQL endpoint. When both addresses are set, the client connects to hostaddr and uses host for TLS hostname verification.

    ConnectionTarget::ConnectionTarget

    fn ConnectionTarget::ConnectionTarget(host? : String, hostaddr? : String, port? : Int) -> ConnectionTarget

    Construct one endpoint. Config::Config validates its address and port.

    Connector

    type Connector

    Wrapper around the callback that opens one physical PostgreSQL connection.

    Pool options can replace the default @client.Client::create path during tests or custom integration.

    Connector::Connector

    Wrap a custom connection-opening callback for pool construction.

    The callback constructs a client and its executor for each physical session.

    LoadBalanceHosts

    pub(all) enum LoadBalanceHosts {
    Disable
    Random
    } derive(Eq,
    Debug
    )

    Host-ordering strategy used before opening a new physical connection.

    This affects only the order in which candidate targets are tried for a new connection. It does not reshuffle already-open idle connections, and it does not move a checked-out client from one target to another.

    Operation

    type Operation

    Exclusive cancellable request scope created by Session::run_cancellable.

    Unlike plain Client operations, an Operation allows only one request at a time so the paired cancel token can target a single in-flight request.

    Operation::batch_execute

    async fn Operation::batch_execute(self : Operation, sql : String) -> Unit

    Execute one or more SQL commands inside the cancellable scope.

    Operation::check_connection

    async fn Operation::check_connection(self : Operation) -> Unit

    Perform a lightweight health check inside the cancellable scope.

    Operation::execute

    async fn Operation::execute(self : Operation, sql : String, params? : Array[&
    ToSql
    ]) -> UInt64

    Execute one command in the cancellable scope and return its affected row count as UInt64.

    Operation::query_all

    Run one request in the cancellable scope and collect all rows.

    Preconditions: the surrounding run_cancellable scope must still be active. Only one request may be in flight on the Operation at a time.

    Operation::query_one

    Run one request in the cancellable scope and require exactly one row.

    Operation::query_opt

    Run one request in the cancellable scope and allow zero or one rows.

    Operation::query_typed_all

    Run one typed request in the cancellable scope and collect all rows.

    OperationCancelToken

    type OperationCancelToken

    Best-effort cancel handle paired with one Operation scope.

    The token is valid only while the owning run_cancellable callback is still active. After that it becomes inert instead of affecting a later borrower of the same physical connection.

    OperationCancelToken::cancel

    async fn OperationCancelToken::cancel(self : OperationCancelToken) -> Unit

    Best-effort cancel the request currently running inside the paired Operation.

    Edge cases: if the scope is already closing, no request is in flight, or the current request was already cancelled through this token, the call is a no-op. Any backend error while sending the cancel packet is suppressed.

    Pool

    type Pool

    Public handle to one connection-pool instance.

    A Pool owns capacity accounting, idle connections, and the policies used to create and recycle physical PostgreSQL sessions.

    Pool::batch_execute

    async fn Pool::batch_execute(self : Pool, sql : String) -> Unit

    Execute one or more commands on an automatically managed pooled session.

    Pool::check_connection

    async fn Pool::check_connection(self : Pool) -> Unit

    Check one automatically managed pooled connection.

    Pool::close

    fn Pool::close(self : Pool) -> Unit

    Stop accepting new checkouts and schedule every idle connection for closure.

    Existing checked-out clients are not revoked. They can keep running until released, at which point their physical connections are closed instead of being returned to the idle queue. Repeated calls are idempotent.

    Pool::config

    fn Pool::config(self : Pool) -> PoolConfig

    Return the full pool config currently used by this pool.

    Pool::create

    fn Pool::create(config : Config, options? : PoolOptions) -> (Pool, PoolExecutor) raise

    Create a pool from declarative config and runtime options.

    This allocates bookkeeping state and checkout slots only. It does not open any physical PostgreSQL connection, so network failures still happen later during checkout.

    Pool::dropped_async_messages

    fn Pool::dropped_async_messages(self : Pool) -> Int64

    Number of oldest asynchronous messages discarded when the pool buffer filled.

    Pool::execute

    async fn Pool::execute(self : Pool, sql : String, params? : Array[&
    ToSql
    ]) -> UInt64

    Execute one command on an automatically managed pooled session and return its affected row count as UInt64.

    Pool::is_closed

    fn Pool::is_closed(self : Pool) -> Bool

    Return whether close() has started for this pool.

    Once this becomes true, new checkouts fail with PoolError::Closed.

    Pool::next_message

    async fn Pool::next_message(self : Pool) -> PoolAsyncMessage?

    Receive one asynchronous message from any physical pool connection. A single consumer should call this method; buffered messages remain readable after the pool closes.

    Pool::query_all

    Run one query on an automatically managed pooled session and collect all rows.

    Pool::query_one

    Run one query on an automatically managed pooled session and require one row.

    Pool::query_opt

    Run one query on an automatically managed pooled session and allow zero or one rows.

    Pool::query_typed_all

    Run one typed query on an automatically managed pooled session.

    Pool::ready

    async fn Pool::ready(self : Pool) -> Unit

    Wait until the pool's maintenance workers can accept requests.

    Pool::resize

    fn Pool::resize(self : Pool, max_size : Int) -> Unit raise

    Change the pool's maximum number of live physical connections.

    Preconditions: max_size must be at least 1. Shrinking the pool retires idle connections immediately until the new limit is respected or no idle connections remain. Checked-out clients are not interrupted; when they are later released above the new limit, they are closed instead of returning to the idle queue. Calling this after close() is a no-op.

    Pool::status

    fn Pool::status(self : Pool) -> Status

    Return a point-in-time snapshot of pool bookkeeping counters.

    The returned record is not live and may already be stale by the time the caller inspects it.

    Pool::with_session

    async fn[T] Pool::with_session(self : Pool, f : async (Session) -> T) -> T

    Borrow one pooled session for the duration of a callback.

    The lease is released in a defer, so it is returned to the pool on normal completion and also when the callback raises.

    Pool::with_transaction

    async fn[T] Pool::with_transaction(self : Pool, f : async (Transaction) -> T, options? : TransactionOptions) -> T

    Run a transaction on one automatically managed pooled session.

    PoolAsyncMessage

    pub struct PoolAsyncMessage {
    connection_id : Int
    message :
    AsyncMessage

    } derive(Eq,
    Debug
    )

    Asynchronous backend message tagged with its physical pool connection.

    PoolAsyncMessage::equal

    PoolAsyncMessage::not_equal

    fn PoolAsyncMessage::not_equal(x : PoolAsyncMessage, y : PoolAsyncMessage) -> Bool

    PoolConfig

    pub struct PoolConfig {
    max_size : Int
    timeouts : Timeouts
    queue_mode : QueueMode
    recycling_method : RecyclingMethod
    statement_cache_capacity : Int
    async_message_capacity : Int
    } derive(Eq,
    Debug
    )

    Capacity and checkout policy for one pool instance.

    PoolConfig::PoolConfig

    fn PoolConfig::PoolConfig(max_size : Int, timeouts? : Timeouts, queue_mode? : QueueMode, recycling_method? : RecyclingMethod, statement_cache_capacity? : Int, async_message_capacity? : Int) -> PoolConfig raise

    Construct and validate one pool configuration.

    max_size and async_message_capacity must be positive. Each configured timeout must be non-negative when present. On success this has no side effects.

    PoolExecutor

    type PoolExecutor

    Owns all physical connection executors and pool maintenance tasks.

    PoolExecutor::run

    async fn PoolExecutor::run(self : PoolExecutor) -> Unit

    Run pool maintenance and all physical client executors until close completes.

    PoolOptions

    pub struct PoolOptions {
    connector : Connector?
    post_create : async (Operation) -> Unit?
    pre_recycle : async (Operation) -> Unit?
    post_recycle : async (Operation) -> Unit?
    }

    Runtime extension points used when constructing a pool.

    PoolOptions::PoolOptions

    fn PoolOptions::PoolOptions(connector? : Connector, post_create? : async (Operation) -> Unit, pre_recycle? : async (Operation) -> Unit, post_recycle? : async (Operation) -> Unit) -> PoolOptions

    Build runtime options for pool construction.

    PreparedStatement

    type PreparedStatement

    Prepared statement handle scoped to the current pooled callback.

    The handle may wrap either a temporary statement or a lease on a cached statement entry. It becomes invalid once the owning callback ends.

    PreparedStatement::columns

    Return a read-only view of the prepared statement's result columns.

    PreparedStatement::execute

    Execute this scoped prepared statement and return the affected row count as UInt64.

    PreparedStatement::params

    Return a read-only view of the prepared statement's parameter types.

    PreparedStatement::query_all

    Execute this scoped prepared statement and collect all rows.

    Preconditions: the statement must still be active inside its callback scope.

    PreparedStatement::query_one

    Execute this scoped prepared statement and require exactly one row.

    Edge behavior: fully drains the stream and lets @client.ClientError::RowCount report an unexpected result size.

    PreparedStatement::query_opt

    Execute this scoped prepared statement and allow zero or one rows.

    Edge behavior: raises @client.ClientError::RowCount when more than one row is returned.

    PreparedStatement::with_stream

    Execute this scoped prepared statement as a callback-scoped row stream.

    QueueMode

    pub enum QueueMode {
    Fifo
    Lifo
    } derive(Eq,
    Debug
    )

    Strategy used when choosing which idle physical connection to reuse next.

    This setting affects only the order of the pool's idle list. It does not reorder waiting tasks, and it has no effect while the pool must open a new connection because no idle connection is available.

    QueueMode::fifo

    fn QueueMode::fifo() -> QueueMode

    Construct FIFO queue mode.

    The oldest idle connection is reused first.

    QueueMode::lifo

    fn QueueMode::lifo() -> QueueMode

    Construct LIFO queue mode.

    The most recently returned idle connection is reused first.

    RecyclingMethod

    pub enum RecyclingMethod {
    Fast
    Verified
    Clean
    Custom(String)
    } derive(Eq,
    Debug
    )

    Checkout-time cleanup policy for already-open physical connections.

    This policy runs only when the pool reuses an idle connection. New connections skip it and instead run the optional post_create hook.

    RecyclingMethod::clean

    Construct clean recycling mode.

    The pool runs the same cleanup SQL sequence used by deadpool-postgres-style "clean" recycling. In practice this closes open portals/cursors, resets session settings, clears LISTEN state, releases advisory locks, and discards temporary objects before reuse. Prepared statements and their cached plans are preserved so the connection-local statement cache remains effective across checkouts.

    RecyclingMethod::custom

    fn RecyclingMethod::custom(sql : String) -> RecyclingMethod

    Construct custom recycling mode.

    sql is executed with batch_execute during checkout of an idle connection. If it fails or times out, that physical connection is discarded.

    RecyclingMethod::fast

    Construct fast recycling mode.

    The pool trusts the idle connection without sending any SQL.

    RecyclingMethod::verified

    Construct verified recycling mode.

    The pool runs a lightweight connection check before handing the connection out again.

    Session

    type Session

    Callback-scoped pooled session.

    This handle temporarily owns one physical PostgreSQL session and expires when the Pool::with_session callback returns.

    Session::batch_execute

    async fn Session::batch_execute(self : Session, sql : String) -> Unit

    Execute one or more SQL commands without returning row data.

    Side effects follow PostgreSQL batch_execute: every command in sql runs on the current session in order.

    Session::check_connection

    async fn Session::check_connection(self : Session) -> Unit

    Perform a lightweight connection health check on this lease.

    Session::execute

    async fn Session::execute(self : Session, sql : String, params? : Array[&
    ToSql
    ]) -> UInt64

    Execute one command on this lease and return its affected row count as UInt64.

    Session::query_all

    Run one query on this lease and collect all rows before returning.

    Side effects: fully drains the query result, so no stream state escapes the call boundary.

    Session::query_one

    Run one query and require exactly one row.

    Row-count behavior follows the underlying @client.Client::query_one.

    Session::query_opt

    Run one query and allow zero or one rows.

    Row-count behavior follows the underlying @client.Client::query_opt.

    Session::query_typed_all

    Run one typed query and collect all rows before returning.

    Session::run_cancellable

    async fn[T] Session::run_cancellable(self : Session, f : async (Operation, OperationCancelToken) -> T) -> T

    Run one callback inside an exclusive cancellable request scope.

    The scope waits in FIFO order for earlier session work. During the callback, requests issued through Operation run one at a time so OperationCancelToken::cancel() targets the current request. When the callback finishes, the token becomes inert and late cancel work is drained.

    Session::with_copy_in

    async fn[T] Session::with_copy_in(self : Session, sql : String, f : async (
    CopyInSink
    ) -> T) -> T

    Run one callback with a COPY FROM STDIN sink on this session.

    Session::with_copy_out

    async fn[T] Session::with_copy_out(self : Session, sql : String, f : async (
    CopyOutStream
    ) -> T) -> T

    Run one callback with a COPY TO STDOUT stream on this session.

    Session::with_prepared

    async fn[T] Session::with_prepared(self : Session, sql : String, f : async (PreparedStatement) -> T) -> T

    Prepare or reuse one connection-local cached statement for this callback.

    A pool configured with statement_cache_capacity = 0 prepares a temporary statement instead. In either case the callback-scoped handle expires when this method returns.

    Session::with_prepared_typed

    async fn[T] Session::with_prepared_typed(self : Session, sql : String, param_types : Array[
    Type
    ], f : async (PreparedStatement) -> T) -> T

    Prepare or reuse one typed connection-local cached statement.

    Session::with_simple_query

    async fn[T] Session::with_simple_query(self : Session, sql : String, f : async (
    SimpleQueryStream
    ) -> T) -> T

    Run one callback with a simple-query protocol stream on this session.

    Session::with_stream

    async fn[T] Session::with_stream(self : Session, sql : String, params? : Array[&
    ToSql
    ], f : async (
    RowStream
    ) -> T) -> T

    Run one callback with an extended-query row stream on this session.

    Session::with_transaction

    async fn[T] Session::with_transaction(self : Session, f : async (Transaction) -> T, options? : TransactionOptions) -> T

    Run one callback inside a transaction and auto-complete it.

    On normal return, the transaction is committed if the callback did not already finish it explicitly. If the callback raises or is cancelled, the transaction is rolled back best-effort unless it was already finished.

    Session::with_typed_stream

    async fn[T] Session::with_typed_stream(self : Session, sql : String, param_types : Array[
    Type
    ], params? : Array[&
    ToSql
    ], f : async (
    RowStream
    ) -> T) -> T

    Run one callback with a typed extended-query row stream on this session.

    Status

    pub struct Status {
    size : Int
    available : Int
    waiting : Int
    max_size : Int
    closed : Bool
    } derive(Eq,
    Debug
    )

    Point-in-time snapshot of one pool's runtime state.

    TargetSessionAttrs

    pub enum TargetSessionAttrs {
    Any
    ReadWrite
    } derive(Eq,
    Debug
    )

    PostgreSQL target-session policy checked right after a new connection opens.

    Any accepts the first successfully opened target. ReadWrite immediately runs show transaction_read_only and rejects a target whose value is on, which is useful when the target list may contain replicas.

    TargetSessionAttrs::any

    Construct Any.

    TargetSessionAttrs::read_write

    Construct ReadWrite.

    TimeoutKind

    pub enum TimeoutKind {
    Wait
    Create
    Recycle
    } derive(Eq,
    Debug
    )

    Phase of checkout reported by PoolError::Timeout.

    Wait means the caller could not obtain pool capacity in time, Create means opening a new physical connection timed out, and Recycle means checkout-time validation or cleanup of an idle connection timed out.

    Timeouts

    pub struct Timeouts {
    wait_ms : Int?
    create_ms : Int?
    recycle_ms : Int?
    } derive(Eq,
    Debug
    )

    Optional checkout timeout overrides in milliseconds.

    These values control how long the pool waits for capacity, creates a new connection, or recycles an idle connection. None leaves the phase unbounded. Negative values are rejected by PoolConfig::PoolConfig or checkout.

    Timeouts::Timeouts

    fn Timeouts::Timeouts(wait_ms? : Int?, create_ms? : Int?, recycle_ms? : Int?) -> Timeouts

    Construct one timeout record.

    This constructor stores the values as-is and does not validate them yet. None disables the corresponding timeout.

    Transaction

    type Transaction

    Callback-scoped pooled transaction.

    This wraps a live PostgreSQL transaction or savepoint while its with_transaction / with_savepoint callback owns the pooled session. Completion expires the handle before it can be used by a later borrower.

    Transaction::batch_execute

    async fn Transaction::batch_execute(self : Transaction, sql : String) -> Unit

    Execute one or more SQL commands inside this transaction.

    Transaction::check_connection

    async fn Transaction::check_connection(self : Transaction) -> Unit

    Perform a lightweight health check while the transaction is open.

    Side effects: executes select 1::int4 as value inside the current transaction instead of using a transaction-independent probe.

    Transaction::commit

    async fn Transaction::commit(self : Transaction) -> Unit

    Commit this pooled transaction explicitly.

    Preconditions: the transaction must not already be finished, and no nested transaction/savepoint scope may still be active. The call waits for any in-flight non-exclusive operation to finish first.

    Transaction::execute

    async fn Transaction::execute(self : Transaction, sql : String, params? : Array[&
    ToSql
    ]) -> UInt64

    Execute one command inside this transaction and return its affected row count as UInt64.

    Transaction::query_all

    Run one query inside this transaction and collect all rows.

    Transaction::query_one

    Run one query inside this transaction and require exactly one row.

    Edge behavior: this helper materializes all rows first and raises @client.ClientError::RowCount when PostgreSQL returned anything other than exactly one row.

    Transaction::query_opt

    Run one query inside this transaction and allow zero or one rows.

    Edge behavior: raises @client.ClientError::RowCount when more than one row is returned.

    Transaction::query_typed_all

    Run one typed query inside the transaction and collect all rows.

    The connection-local statement cache is used unless caching is disabled.

    Transaction::rollback

    async fn Transaction::rollback(self : Transaction) -> Unit

    Roll back this pooled transaction explicitly.

    Preconditions and completion behavior match commit(), except the final SQL action is ROLLBACK.

    Transaction::with_prepared

    async fn[T] Transaction::with_prepared(self : Transaction, sql : String, f : async (PreparedStatement) -> T) -> T

    Prepare or reuse one connection-local cached statement in this transaction.

    Transaction::with_prepared_typed

    async fn[T] Transaction::with_prepared_typed(self : Transaction, sql : String, param_types : Array[
    Type
    ], f : async (PreparedStatement) -> T) -> T

    Prepare or reuse one typed connection-local cached statement in this transaction.

    Transaction::with_savepoint

    async fn[T] Transaction::with_savepoint(self : Transaction, name : String, f : async (Transaction) -> T) -> T

    Run one callback inside a named savepoint-backed nested transaction.

    On success the nested transaction is committed if still unfinished; on error or cancellation it is rolled back best-effort. The client quotes name as a case-sensitive identifier and rejects empty names or NUL characters.

    Transaction::with_stream

    async fn[T] Transaction::with_stream(self : Transaction, sql : String, params? : Array[&
    ToSql
    ], f : async (
    RowStream
    ) -> T) -> T

    Run one callback with an extended-query row stream in this transaction.

    Transaction::with_transaction

    async fn[T] Transaction::with_transaction(self : Transaction, f : async (Transaction) -> T) -> T

    Run one callback inside an unnamed savepoint-backed nested transaction.

    On success the nested transaction is committed if still unfinished; on error or cancellation it is rolled back best-effort.

    Transaction::with_typed_stream

    Run one typed row-stream callback in this transaction.

    TransactionOptions

    pub struct TransactionOptions {
    isolation_level :
    IsolationLevel
    ?
    read_only : Bool?
    deferrable : Bool?
    } derive(Eq,
    Debug
    )

    Options for the BEGIN command used when opening a pooled transaction.

    TransactionOptions::TransactionOptions

    fn TransactionOptions::TransactionOptions(isolation_level? :
    IsolationLevel
    , read_only? : Bool, deferrable? : Bool) -> TransactionOptions

    Build transaction options for a future BEGIN command.