pub struct Connection { /* private fields */ }Expand description
A PostgreSQL connection over TCP, TLS, or Unix domain socket.
All I/O is synchronous using sync_io::Stream which wraps TcpStream,
UnixStream, or rustls::StreamOwned. No async runtime is required.
§Thread safety
Connection is Send but not Sync — it must be used by one thread
at a time. This matches the PostgreSQL wire protocol which is inherently
sequential.
§Example
use bsql_driver_postgres::{Connection, Config};
let config = Config::from_url("postgres://user:pass@localhost/db")?;
let mut conn = Connection::connect(&config)?;
let hash = bsql_driver_postgres::hash_sql("SELECT 1 AS n");
let result = conn.query("SELECT 1 AS n", hash, &[])?;
assert_eq!(result.len(), 1);Implementations§
Source§impl Connection
impl Connection
Sourcepub fn connect(config: &Config) -> Result<Self, DriverError>
pub fn connect(config: &Config) -> Result<Self, DriverError>
Connect to PostgreSQL and complete the startup/auth handshake. Fully synchronous — no tokio runtime needed.
Transport is selected automatically based on config:
hoststarting with/-> Unix domain socket- Otherwise -> TCP (with optional TLS upgrade based on
sslmode)
§Errors
Returns an error if the connection fails, TLS upgrade fails (when required), or authentication fails.
Sourcepub fn connect_arc(config: Arc<Config>) -> Result<Self, DriverError>
pub fn connect_arc(config: Arc<Config>) -> Result<Self, DriverError>
Connect using a shared config. Avoids cloning the Config strings.
Preferred by the connection pool, which holds Arc<Config> and opens
new connections without 5 String clones per open.
Sourcepub fn prepare_only(
&mut self,
sql: &str,
sql_hash: u64,
) -> Result<(), DriverError>
pub fn prepare_only( &mut self, sql: &str, sql_hash: u64, ) -> Result<(), DriverError>
Prepare a statement without executing it (Parse+Describe+Sync only).
If the statement is already cached, this is a no-op.
Sourcepub fn query(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
) -> Result<QueryResult, DriverError>
pub fn query( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], ) -> Result<QueryResult, DriverError>
Execute a prepared query and return rows.
Optimized path: after send_pipeline flushes, we parse BindComplete +
DataRow* + CommandComplete + ReadyForQuery directly from stream_buf,
avoiding per-message read_message_buffered overhead. DataRow payloads
are parsed in-place from stream_buf into a response buffer.
Note: arena is not used — row data is stored in an inline resp_buf
owned by QueryResult. The parameter is kept for API compatibility
with the streaming path, but callers may pass any &mut Arena.
Sourcepub fn execute_monolithic(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
) -> Result<u64, DriverError>
pub fn execute_monolithic( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], ) -> Result<u64, DriverError>
Monolithic execute — everything in one function, no intermediate calls.
Inlines the entire send_pipeline + response parsing path for INSERT/UPDATE/DELETE. On cache hit: template copy + param patch + write_all + inline message parsing. No send_pipeline(), no flush_write(), no refill_stream_buf(). The compiler sees the entire path and can optimize globally.
On cache miss (first execution of a statement), falls through to the
cold execute_with_prepare path.
Sourcepub fn execute(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
) -> Result<u64, DriverError>
pub fn execute( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], ) -> Result<u64, DriverError>
Execute a query without result rows (INSERT/UPDATE/DELETE).
Delegates to execute_monolithic which inlines the entire send + receive
path. Kept for API compatibility.
Sourcepub fn execute_pipeline(
&mut self,
sql: &str,
sql_hash: u64,
param_sets: &[&[&(dyn Encode + Sync)]],
) -> Result<Vec<u64>, DriverError>
pub fn execute_pipeline( &mut self, sql: &str, sql_hash: u64, param_sets: &[&[&(dyn Encode + Sync)]], ) -> Result<Vec<u64>, DriverError>
Execute the same prepared statement N times with different parameters in a single pipeline round-trip.
Sends all N Bind+Execute messages followed by one Sync. PostgreSQL processes them in order and returns N BindComplete+CommandComplete responses followed by one ReadyForQuery.
This is a real optimization for bulk operations: N inserts in a transaction become 1 round-trip instead of N round-trips.
Returns the number of affected rows for each parameter set.
Sourcepub fn for_each<F>(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
f: F,
) -> Result<(), DriverError>
pub fn for_each<F>( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], f: F, ) -> Result<(), DriverError>
Process each row via a closure with zero-copy PgDataRow.
Sourcepub fn for_each_raw_monolithic<F>(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
f: F,
) -> Result<(), DriverError>
pub fn for_each_raw_monolithic<F>( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], f: F, ) -> Result<(), DriverError>
Monolithic for_each_raw — everything in one function, no intermediate calls.
Inlines the entire send_pipeline + response parsing path for SELECT queries processed via a raw byte closure. On cache hit: template copy + param patch + write_all + inline DataRow streaming + inline ReadyForQuery. No send_pipeline(), no flush_write(), no refill_stream_buf().
On cache miss (first execution of a statement), falls through to the
cold for_each_raw_with_prepare path.
Sourcepub fn for_each_raw<F>(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
f: F,
) -> Result<(), DriverError>
pub fn for_each_raw<F>( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], f: F, ) -> Result<(), DriverError>
Process each DataRow as raw bytes — fastest path.
Delegates to for_each_raw_monolithic which inlines the entire send +
receive path. Kept for API compatibility.
Sourcepub fn simple_query(&mut self, sql: &str) -> Result<(), DriverError>
pub fn simple_query(&mut self, sql: &str) -> Result<(), DriverError>
Simple query protocol — for non-prepared SQL (BEGIN, COMMIT, SET, etc.).
Sourcepub fn simple_query_rows(
&mut self,
sql: &str,
) -> Result<Vec<SimpleRow>, DriverError>
pub fn simple_query_rows( &mut self, sql: &str, ) -> Result<Vec<SimpleRow>, DriverError>
Execute a simple (text protocol) query and return all result rows.
Sourcepub fn prepare_describe(
&mut self,
sql: &str,
) -> Result<PrepareResult, DriverError>
pub fn prepare_describe( &mut self, sql: &str, ) -> Result<PrepareResult, DriverError>
Prepare a statement without executing it (Parse+Describe+Sync only).
Returns column and parameter metadata. Uses the unnamed statement ""
so there is no cache pollution.
Sourcepub fn wait_for_notification(&mut self) -> Result<(String, String), DriverError>
pub fn wait_for_notification(&mut self) -> Result<(String, String), DriverError>
Block until a NotificationResponse arrives on this connection.
Reads raw messages from the stream and skips everything except
NotificationResponse. Returns the (channel, payload) pair.
Used by the listener to receive LISTEN/NOTIFY events.
This method never returns Ok for non-notification messages – it loops
internally, discarding ParameterStatus, NoticeResponse, etc.
Sourcepub fn cancel(&self) -> Result<(), DriverError>
pub fn cancel(&self) -> Result<(), DriverError>
Cancel the currently running query on this connection.
Opens a NEW TCP connection to the same host:port and sends a CancelRequest message (16 bytes: length=16, code=80877102, pid, secret). The cancel connection is closed immediately after sending.
Sourcepub fn set_read_timeout(
&self,
timeout: Option<Duration>,
) -> Result<(), DriverError>
pub fn set_read_timeout( &self, timeout: Option<Duration>, ) -> Result<(), DriverError>
Set the read timeout on the underlying socket.
Used by listeners to poll for notifications with a timeout.
None means block indefinitely.
Sourcepub fn query_streaming_start(
&mut self,
sql: &str,
sql_hash: u64,
params: &[&(dyn Encode + Sync)],
chunk_size: i32,
) -> Result<(Arc<[ColumnDesc]>, bool), DriverError>
pub fn query_streaming_start( &mut self, sql: &str, sql_hash: u64, params: &[&(dyn Encode + Sync)], chunk_size: i32, ) -> Result<(Arc<[ColumnDesc]>, bool), DriverError>
Begin a streaming query using the PG extended query protocol with
Execute(max_rows=chunk_size).
Returns column metadata and puts the connection into streaming mode.
The caller must repeatedly call streaming_next_chunk() until it returns
Ok(false) (all rows consumed) before issuing any other query on this
connection.
Uses the unnamed portal "" which stays open between Execute calls
as long as Sync is NOT sent. We use Flush (not Sync) to force PG to
send buffered output without destroying the portal.
Sourcepub fn streaming_next_chunk(
&mut self,
arena: &mut Arena,
all_col_offsets: &mut Vec<(usize, i32)>,
) -> Result<bool, DriverError>
pub fn streaming_next_chunk( &mut self, arena: &mut Arena, all_col_offsets: &mut Vec<(usize, i32)>, ) -> Result<bool, DriverError>
Read the next chunk of rows from an in-progress streaming query.
Returns Ok(true) if more rows are available (PortalSuspended),
Ok(false) when all rows have been consumed (CommandComplete).
After CommandComplete, this method sends Sync and reads ReadyForQuery, returning the connection to a clean protocol state.
Sourcepub fn streaming_send_execute(
&mut self,
chunk_size: i32,
) -> Result<(), DriverError>
pub fn streaming_send_execute( &mut self, chunk_size: i32, ) -> Result<(), DriverError>
Send Execute+Flush for the next chunk of a streaming query.
Must be called before streaming_next_chunk() on the 2nd and
subsequent chunks (the first chunk’s Execute is sent by
query_streaming_start).
Uses Flush (not Sync) to keep the unnamed portal alive.
Sourcepub fn is_streaming(&self) -> bool
pub fn is_streaming(&self) -> bool
Whether a streaming query is in progress.
Sourcepub fn close(self) -> Result<(), DriverError>
pub fn close(self) -> Result<(), DriverError>
Send Terminate and close the connection.
Sourcepub fn is_in_transaction(&self) -> bool
pub fn is_in_transaction(&self) -> bool
Whether the connection is in a transaction.
Sourcepub fn is_in_failed_transaction(&self) -> bool
pub fn is_in_failed_transaction(&self) -> bool
Whether the connection is in a failed transaction.
Sourcepub fn idle_duration(&self) -> Duration
pub fn idle_duration(&self) -> Duration
How long since this connection last completed a query.
Sourcepub fn query_counter(&self) -> u64
pub fn query_counter(&self) -> u64
Monotonic query counter — incremented on every query/execute.
Sourcepub fn server_params(&self) -> &[(Box<str>, Box<str>)]
pub fn server_params(&self) -> &[(Box<str>, Box<str>)]
All server parameters received during startup.
Sourcepub fn secret_key(&self) -> i32
pub fn secret_key(&self) -> i32
Backend secret key.
Sourcepub fn drain_notifications(&mut self) -> Vec<Notification>
pub fn drain_notifications(&mut self) -> Vec<Notification>
Drain all buffered notifications.
Sourcepub fn pending_notification_count(&self) -> usize
pub fn pending_notification_count(&self) -> usize
Number of pending notifications.
Sourcepub fn set_max_stmt_cache_size(&mut self, size: usize)
pub fn set_max_stmt_cache_size(&mut self, size: usize)
Set the maximum number of cached prepared statements.
Sourcepub fn stmt_cache_len(&self) -> usize
pub fn stmt_cache_len(&self) -> usize
Number of currently cached prepared statements.
Sourcepub fn created_at(&self) -> Instant
pub fn created_at(&self) -> Instant
When this connection was created.