Skip to main content

Connection

Trait Connection 

Source
pub trait Connection:
    Debug
    + Send
    + 'static {
    // Required methods
    fn exec<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        schema: &'life1 Arc<Schema>,
        plan: Operation,
    ) -> Pin<Box<dyn Future<Output = Result<ExecResponse>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn push_schema<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        _schema: &'life1 Schema,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn applied_migrations<'life0, 'async_trait>(
        &'life0 mut self,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<AppliedMigration>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn apply_migration<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 mut self,
        id: u64,
        name: &'life1 str,
        migration: &'life2 Migration,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;

    // Provided methods
    fn is_valid(&self) -> bool { ... }
    fn ping<'life0, 'async_trait>(
        &'life0 mut self,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
}
Expand description

A live database session that can execute Operations.

Connections are obtained from Driver::connect and are managed by the connection pool. All query execution flows through Connection::exec, which accepts an Operation and returns an ExecResponse.

§Examples

use toasty_core::driver::{Connection, Operation, ExecResponse};
use toasty_core::driver::operation::Transaction;

// Execute a transaction start operation on a connection:
let response = conn.exec(&schema, Transaction::start().into()).await?;

Required Methods§

Source

fn exec<'life0, 'life1, 'async_trait>( &'life0 mut self, schema: &'life1 Arc<Schema>, plan: Operation, ) -> Pin<Box<dyn Future<Output = Result<ExecResponse>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Executes a database operation and returns the result.

This is the single entry point for all database interactions. The query engine compiles user queries into Operation values and dispatches them here. The driver translates each operation into backend-specific calls and returns an ExecResponse.

Source

fn push_schema<'life0, 'life1, 'async_trait>( &'life0 mut self, _schema: &'life1 Schema, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Creates tables and indices defined in the schema on the database. TODO: This will probably use database introspection in the future.

Source

fn applied_migrations<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<Vec<AppliedMigration>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Returns a list of currently applied database migrations.

Source

fn apply_migration<'life0, 'life1, 'life2, 'async_trait>( &'life0 mut self, id: u64, name: &'life1 str, migration: &'life2 Migration, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Applies a single migration to the database and records it as applied.

Provided Methods§

Source

fn is_valid(&self) -> bool

Cheap, synchronous, local check that the driver’s client object still considers the connection open.

Examples: a flag the driver flips when its background reader reports a socket close (the MySQL driver does this), an is_closed() accessor on the underlying client. Implementations must not block and must not perform I/O — the check runs on the hot path of every recycle and must complete in nanoseconds. Drivers that cannot answer cheaply leave this at the default and rely on the pool’s ping sweep or the per-acquire pre-ping option to catch a dead connection.

The pool consults is_valid() whenever a connection is returned to the idle set. A false result causes the slot to be dropped before another caller can pick it up; the pool then returns another idle connection or opens a fresh one. A connection is also re-checked immediately after every Connection::exec; if the operation flipped the flag (e.g. the driver classified the error as connection-lost and updated its state), the worker task exits and the slot is evicted.

The default returns true. Drivers without a usable passive signal stay on this default and rely on the active path: an operation surfaces crate::Error::connection_lost, the pool drops the slot, and the background sweep eagerly pings the rest of the idle pool.

Source

fn ping<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Active liveness probe. The pool’s background health-check sweep calls this on the longest-idle connection on every tick, and on every other idle connection when an escalation is triggered. When pool_pre_ping is enabled, the pool also calls it on every acquire.

Drivers MUST classify a failure here as crate::Error::connection_lost rather than a generic operation error. The pool branches on that classification to drop the slot (vs. returning it to the idle set after a transient query error), and a user-observed connection_lost is what wakes the pool’s sweep to eagerly check the rest of the pool. Returning any other error variant from ping will leak a dead connection back into rotation.

Drivers SHOULD make this the cheapest round-trip the backend supports (SELECT 1, COM_PING, etc.). A ping that runs slower than the sweep’s per-call timeout (5 seconds, internal) is treated as failed.

The default returns Ok(()) without doing any I/O. That is the right answer for drivers whose connection layer cannot fail in isolation (the in-process SQLite driver) or whose backend manages its own pool beneath this surface (DynamoDB, where each exec is an HTTP call with its own retry policy).

Implementors§