PgDriver

Struct PgDriver 

Source
pub struct PgDriver { /* private fields */ }
Expand description

Combines the pure encoder (Layer 2) with async I/O (Layer 3).

Implementations§

Source§

impl PgDriver

Source

pub fn new(connection: PgConnection) -> Self

Create a new driver with an existing connection.

Source

pub fn builder() -> PgDriverBuilder

Builder pattern for ergonomic connection configuration.

§Example
let driver = PgDriver::builder()
    .host("localhost")
    .port(5432)
    .user("admin")
    .database("mydb")
    .password("secret")  // Optional
    .connect()
    .await?;
Source

pub async fn connect( host: &str, port: u16, user: &str, database: &str, ) -> PgResult<Self>

Connect to PostgreSQL and create a driver (trust mode, no password).

Source

pub async fn connect_with_password( host: &str, port: u16, user: &str, database: &str, password: &str, ) -> PgResult<Self>

Connect to PostgreSQL with password authentication (SCRAM-SHA-256).

Source

pub async fn connect_env() -> PgResult<Self>

Connect using DATABASE_URL environment variable.

Parses the URL format: postgresql://user:password@host:port/database or postgres://user:password@host:port/database

§Example
// Set DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
let driver = PgDriver::connect_env().await?;
Source

pub async fn connect_url(url: &str) -> PgResult<Self>

Connect using a PostgreSQL connection URL.

Parses the URL format: postgresql://user:password@host:port/database or postgres://user:password@host:port/database

§Example
let driver = PgDriver::connect_url("postgresql://user:pass@localhost:5432/mydb").await?;
Source

pub async fn connect_with_timeout( host: &str, port: u16, user: &str, database: &str, password: &str, timeout: Duration, ) -> PgResult<Self>

Connect to PostgreSQL with a connection timeout. If the connection cannot be established within the timeout, returns an error.

§Example
use std::time::Duration;
let driver = PgDriver::connect_with_timeout(
    "localhost", 5432, "user", "db", "password",
    Duration::from_secs(5)
).await?;
Source

pub fn clear_cache(&mut self)

Clear the prepared statement cache. Frees memory by removing all cached statements. Note: Statements remain on the PostgreSQL server until connection closes.

Source

pub fn cache_stats(&self) -> (usize, usize)

Get cache statistics. Returns (current_size, max_capacity).

Source

pub async fn fetch_all(&mut self, cmd: &Qail) -> PgResult<Vec<PgRow>>

Execute a QAIL command and fetch all rows (CACHED + ZERO-ALLOC). Default method - uses prepared statement caching for best performance. On first call: sends Parse + Bind + Execute + Sync On subsequent calls with same SQL: sends only Bind + Execute (SKIPS Parse!) Uses LRU cache with max 1000 statements (auto-evicts oldest).

Source

pub async fn fetch_typed<T: QailRow>(&mut self, cmd: &Qail) -> PgResult<Vec<T>>

Execute a QAIL command and fetch all rows as a typed struct. Requires the target type to implement QailRow trait.

§Example
let users: Vec<User> = driver.fetch_typed::<User>(&query).await?;
Source

pub async fn fetch_one_typed<T: QailRow>( &mut self, cmd: &Qail, ) -> PgResult<Option<T>>

Execute a QAIL command and fetch a single row as a typed struct. Returns None if no rows are returned.

Source

pub async fn fetch_all_uncached(&mut self, cmd: &Qail) -> PgResult<Vec<PgRow>>

Execute a QAIL command and fetch all rows (UNCACHED). Sends Parse + Bind + Execute on every call. Use for one-off queries or when caching is not desired.

Source

pub async fn fetch_all_fast(&mut self, cmd: &Qail) -> PgResult<Vec<PgRow>>

Execute a QAIL command and fetch all rows (FAST VERSION). Uses optimized recv_with_data_fast for faster response parsing. Skips column metadata collection for maximum speed.

Source

pub async fn fetch_one(&mut self, cmd: &Qail) -> PgResult<PgRow>

Execute a QAIL command and fetch one row.

Source

pub async fn fetch_all_cached(&mut self, cmd: &Qail) -> PgResult<Vec<PgRow>>

Execute a QAIL command with PREPARED STATEMENT CACHING (ZERO-ALLOC). Like fetch_all(), but caches the prepared statement on the server. On first call: sends Parse + Bind + Execute + Sync On subsequent calls: sends only Bind + Execute + Sync (SKIPS Parse!)

Source

pub async fn execute(&mut self, cmd: &Qail) -> PgResult<u64>

Execute a QAIL command (for mutations) - ZERO-ALLOC.

Source

pub async fn begin(&mut self) -> PgResult<()>

Begin a transaction (AST-native).

Source

pub async fn commit(&mut self) -> PgResult<()>

Commit the current transaction (AST-native).

Source

pub async fn rollback(&mut self) -> PgResult<()>

Rollback the current transaction (AST-native).

Source

pub async fn savepoint(&mut self, name: &str) -> PgResult<()>

Create a named savepoint within the current transaction. Savepoints allow partial rollback within a transaction. Use rollback_to() to return to this savepoint.

§Example
driver.begin().await?;
driver.execute(&insert1).await?;
driver.savepoint("sp1").await?;
driver.execute(&insert2).await?;
driver.rollback_to("sp1").await?; // Undo insert2, keep insert1
driver.commit().await?;
Source

pub async fn rollback_to(&mut self, name: &str) -> PgResult<()>

Rollback to a previously created savepoint. Discards all changes since the named savepoint was created, but keeps the transaction open.

Source

pub async fn release_savepoint(&mut self, name: &str) -> PgResult<()>

Release a savepoint (free resources, if no longer needed). After release, the savepoint cannot be rolled back to.

Source

pub async fn execute_batch(&mut self, cmds: &[Qail]) -> PgResult<Vec<u64>>

Execute multiple commands in a single atomic transaction. All commands succeed or all are rolled back.

§Example
let cmds = vec![
    Qail::add("users").columns(["name"]).values(["Alice"]),
    Qail::add("users").columns(["name"]).values(["Bob"]),
];
let results = driver.execute_batch(&cmds).await?;
// results = [1, 1] (rows affected)
Source

pub async fn set_statement_timeout(&mut self, ms: u32) -> PgResult<()>

Set statement timeout for this connection (in milliseconds).

§Example
driver.set_statement_timeout(30_000).await?; // 30 seconds
Source

pub async fn reset_statement_timeout(&mut self) -> PgResult<()>

Reset statement timeout to default (no limit).

Source

pub async fn pipeline_batch(&mut self, cmds: &[Qail]) -> PgResult<usize>

Execute multiple Qail ASTs in a single network round-trip (PIPELINING).

§Example
let cmds: Vec<Qail> = (1..=1000)
    .map(|i| Qail::get("harbors").columns(["id", "name"]).limit(i))
    .collect();
let count = driver.pipeline_batch(&cmds).await?;
assert_eq!(count, 1000);
Source

pub async fn pipeline_fetch( &mut self, cmds: &[Qail], ) -> PgResult<Vec<Vec<PgRow>>>

Execute multiple Qail ASTs and return full row data.

Source

pub async fn prepare(&mut self, sql: &str) -> PgResult<PreparedStatement>

Prepare a SQL statement for repeated execution.

Source

pub async fn pipeline_prepared_fast( &mut self, stmt: &PreparedStatement, params_batch: &[Vec<Option<Vec<u8>>>], ) -> PgResult<usize>

Execute a prepared statement pipeline in FAST mode (count only).

Source

pub async fn execute_raw(&mut self, sql: &str) -> PgResult<()>

Execute a raw SQL string. ⚠️ Discouraged: Violates AST-native philosophy. Use for bootstrap DDL only (e.g., migration table creation). For transactions, use begin(), commit(), rollback().

Source

pub async fn fetch_raw(&mut self, sql: &str) -> PgResult<Vec<PgRow>>

Execute a raw SQL query and return rows. ⚠️ Discouraged: Violates AST-native philosophy. Use for bootstrap/admin queries only.

Source

pub async fn copy_bulk( &mut self, cmd: &Qail, rows: &[Vec<Value>], ) -> PgResult<u64>

Bulk insert data using PostgreSQL COPY protocol (AST-native). Uses a Qail::Add to get validated table and column names from the AST, not user-provided strings. This is the sound, AST-native approach.

§Example
// Create a Qail::Add to define table and columns
let cmd = Qail::add("users")
    .columns(["id", "name", "email"]);
// Bulk insert rows
let rows: Vec<Vec<Value>> = vec![
    vec![Value::Int(1), Value::String("Alice"), Value::String("alice@ex.com")],
    vec![Value::Int(2), Value::String("Bob"), Value::String("bob@ex.com")],
];
driver.copy_bulk(&cmd, &rows).await?;
Source

pub async fn copy_bulk_bytes( &mut self, cmd: &Qail, data: &[u8], ) -> PgResult<u64>

Fastest bulk insert using pre-encoded COPY data. Accepts raw COPY text format bytes. Use when caller has already encoded rows to avoid any encoding overhead.

§Format

Data should be tab-separated rows with newlines (COPY text format): 1\thello\t3.14\n2\tworld\t2.71\n

§Example
let cmd = Qail::add("users").columns(["id", "name"]);
let data = b"1\tAlice\n2\tBob\n";
driver.copy_bulk_bytes(&cmd, data).await?;
Source

pub async fn copy_export_table( &mut self, table: &str, columns: &[String], ) -> PgResult<Vec<u8>>

Export table data using PostgreSQL COPY TO STDOUT (zero-copy streaming). Returns rows as tab-separated bytes for direct re-import via copy_bulk_bytes.

§Example
let data = driver.copy_export_table("users", &["id", "name"]).await?;
shadow_driver.copy_bulk_bytes(&cmd, &data).await?;
Source

pub async fn stream_cmd( &mut self, cmd: &Qail, batch_size: usize, ) -> PgResult<Vec<Vec<PgRow>>>

Stream large result sets using PostgreSQL cursors. This method uses DECLARE CURSOR internally to stream rows in batches, avoiding loading the entire result set into memory.

§Example
let cmd = Qail::get("large_table");
let batches = driver.stream_cmd(&cmd, 100).await?;
for batch in batches {
    for row in batch {
        // process row
    }
}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> ColumnValue<Value> for T