pub struct Client<S: ConnectionState> { /* private fields */ }Expand description
SQL Server client with type-state connection management.
The generic parameter S represents the current connection state,
ensuring at compile time that certain operations are only available
in appropriate states.
Implementations§
Source§impl Client<Disconnected>
impl Client<Disconnected>
Source§impl Client<Ready>
impl Client<Ready>
Sourcepub fn mark_needs_reset(&mut self)
pub fn mark_needs_reset(&mut self)
Mark this connection as needing a reset on next use.
Called by the connection pool when a connection is returned. The next SQL batch or RPC will include the RESETCONNECTION flag in the TDS packet header, causing SQL Server to reset connection state (temp tables, SET options, transaction isolation level, etc.) before executing the command.
This is more efficient than calling sp_reset_connection as a
separate command because it’s handled at the TDS protocol level.
Sourcepub fn needs_reset(&self) -> bool
pub fn needs_reset(&self) -> bool
Check if this connection needs a reset.
Returns true if mark_needs_reset() was called and the reset
hasn’t been performed yet.
Sourcepub async fn query<'a>(
&'a mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
) -> Result<QueryStream<'a>>
pub async fn query<'a>( &'a mut self, sql: &str, params: &[&(dyn ToSql + Sync)], ) -> Result<QueryStream<'a>>
Execute a query and return a streaming result set.
Per ADR-007, results are streamed by default for memory efficiency.
Use .collect_all() on the stream if you need all rows in memory.
§Example
use futures::StreamExt;
// Streaming (memory-efficient)
let mut stream = client.query("SELECT * FROM users WHERE id = @p1", &[&1]).await?;
while let Some(row) = stream.next().await {
let row = row?;
process(&row);
}
// Buffered (loads all into memory)
let rows: Vec<Row> = client
.query("SELECT * FROM small_table", &[])
.await?
.collect_all()
.await?;Sourcepub async fn query_with_timeout<'a>(
&'a mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
timeout_duration: Duration,
) -> Result<QueryStream<'a>>
pub async fn query_with_timeout<'a>( &'a mut self, sql: &str, params: &[&(dyn ToSql + Sync)], timeout_duration: Duration, ) -> Result<QueryStream<'a>>
Execute a query with a specific timeout.
This overrides the default command_timeout from the connection configuration
for this specific query. If the query does not complete within the specified
duration, an error is returned.
§Arguments
sql- The SQL query to executeparams- Query parameterstimeout_duration- Maximum time to wait for the query to complete
§Example
use std::time::Duration;
// Execute with a 5-second timeout
let rows = client
.query_with_timeout(
"SELECT * FROM large_table",
&[],
Duration::from_secs(5),
)
.await?;Sourcepub async fn query_multiple<'a>(
&'a mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
) -> Result<MultiResultStream<'a>>
pub async fn query_multiple<'a>( &'a mut self, sql: &str, params: &[&(dyn ToSql + Sync)], ) -> Result<MultiResultStream<'a>>
Execute a batch that may return multiple result sets.
This is useful for stored procedures or SQL batches that contain multiple SELECT statements.
§Example
// Execute a batch with multiple SELECTs
let mut results = client.query_multiple(
"SELECT 1 AS a; SELECT 2 AS b, 3 AS c;",
&[]
).await?;
// Process first result set
while let Some(row) = results.next_row().await? {
println!("Result 1: {:?}", row);
}
// Move to second result set
if results.next_result().await? {
while let Some(row) = results.next_row().await? {
println!("Result 2: {:?}", row);
}
}Sourcepub async fn execute(
&mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
) -> Result<u64>
pub async fn execute( &mut self, sql: &str, params: &[&(dyn ToSql + Sync)], ) -> Result<u64>
Execute a query that doesn’t return rows.
Returns the number of affected rows.
Sourcepub async fn execute_with_timeout(
&mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
timeout_duration: Duration,
) -> Result<u64>
pub async fn execute_with_timeout( &mut self, sql: &str, params: &[&(dyn ToSql + Sync)], timeout_duration: Duration, ) -> Result<u64>
Execute a statement with a specific timeout.
This overrides the default command_timeout from the connection configuration
for this specific statement. If the statement does not complete within the
specified duration, an error is returned.
§Arguments
sql- The SQL statement to executeparams- Statement parameterstimeout_duration- Maximum time to wait for the statement to complete
§Example
use std::time::Duration;
// Execute with a 10-second timeout
let rows_affected = client
.execute_with_timeout(
"UPDATE large_table SET status = @p1",
&[&"processed"],
Duration::from_secs(10),
)
.await?;Sourcepub async fn begin_transaction(self) -> Result<Client<InTransaction>>
pub async fn begin_transaction(self) -> Result<Client<InTransaction>>
Begin a transaction.
This transitions the client from Ready to InTransaction state.
Per MS-TDS spec, the server returns a transaction descriptor in the
BeginTransaction EnvChange token that must be included in subsequent
ALL_HEADERS sections.
Sourcepub async fn begin_transaction_with_isolation(
self,
isolation_level: IsolationLevel,
) -> Result<Client<InTransaction>>
pub async fn begin_transaction_with_isolation( self, isolation_level: IsolationLevel, ) -> Result<Client<InTransaction>>
Begin a transaction with a specific isolation level.
This transitions the client from Ready to InTransaction state
with the specified isolation level.
§Example
use mssql_client::IsolationLevel;
let tx = client.begin_transaction_with_isolation(IsolationLevel::Serializable).await?;
// All operations in this transaction use SERIALIZABLE isolation
tx.commit().await?;Sourcepub async fn simple_query(&mut self, sql: &str) -> Result<()>
pub async fn simple_query(&mut self, sql: &str) -> Result<()>
Execute a simple query without parameters.
This is useful for DDL statements and simple queries where you don’t need to retrieve the affected row count.
Sourcepub fn is_in_transaction(&self) -> bool
pub fn is_in_transaction(&self) -> bool
Check if the connection is currently in a transaction.
This returns true if a transaction was started via raw SQL
(BEGIN TRANSACTION) and has not yet been committed or rolled back.
Note: This only tracks transactions started via raw SQL. Transactions
started via the type-state API (begin_transaction()) result in a
Client<InTransaction> which is a different type.
§Example
client.execute("BEGIN TRANSACTION", &[]).await?;
assert!(client.is_in_transaction());
client.execute("COMMIT", &[]).await?;
assert!(!client.is_in_transaction());Sourcepub fn cancel_handle(&self) -> CancelHandle
pub fn cancel_handle(&self) -> CancelHandle
Get a handle for cancelling the current query.
The cancel handle can be cloned and sent to other tasks, enabling cancellation of long-running queries from a separate async context.
§Example
use std::time::Duration;
let cancel_handle = client.cancel_handle();
// Spawn a task to cancel after 10 seconds
let handle = tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(10)).await;
let _ = cancel_handle.cancel().await;
});
// This query will be cancelled if it runs longer than 10 seconds
let result = client.query("SELECT * FROM very_large_table", &[]).await;Source§impl Client<InTransaction>
impl Client<InTransaction>
Sourcepub async fn query<'a>(
&'a mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
) -> Result<QueryStream<'a>>
pub async fn query<'a>( &'a mut self, sql: &str, params: &[&(dyn ToSql + Sync)], ) -> Result<QueryStream<'a>>
Execute a query within the transaction and return a streaming result set.
See Client<Ready>::query for usage examples.
Sourcepub async fn execute(
&mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
) -> Result<u64>
pub async fn execute( &mut self, sql: &str, params: &[&(dyn ToSql + Sync)], ) -> Result<u64>
Execute a statement within the transaction.
Returns the number of affected rows.
Sourcepub async fn query_with_timeout<'a>(
&'a mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
timeout_duration: Duration,
) -> Result<QueryStream<'a>>
pub async fn query_with_timeout<'a>( &'a mut self, sql: &str, params: &[&(dyn ToSql + Sync)], timeout_duration: Duration, ) -> Result<QueryStream<'a>>
Execute a query within the transaction with a specific timeout.
See Client<Ready>::query_with_timeout for details.
Sourcepub async fn execute_with_timeout(
&mut self,
sql: &str,
params: &[&(dyn ToSql + Sync)],
timeout_duration: Duration,
) -> Result<u64>
pub async fn execute_with_timeout( &mut self, sql: &str, params: &[&(dyn ToSql + Sync)], timeout_duration: Duration, ) -> Result<u64>
Execute a statement within the transaction with a specific timeout.
See Client<Ready>::execute_with_timeout for details.
Sourcepub async fn commit(self) -> Result<Client<Ready>>
pub async fn commit(self) -> Result<Client<Ready>>
Commit the transaction.
This transitions the client back to Ready state.
Sourcepub async fn rollback(self) -> Result<Client<Ready>>
pub async fn rollback(self) -> Result<Client<Ready>>
Rollback the transaction.
This transitions the client back to Ready state.
Sourcepub async fn save_point(&mut self, name: &str) -> Result<SavePoint>
pub async fn save_point(&mut self, name: &str) -> Result<SavePoint>
Create a savepoint and return a handle for later rollback.
The returned SavePoint handle contains the validated savepoint name.
Use it with rollback_to() to partially undo transaction work.
§Example
let tx = client.begin_transaction().await?;
tx.execute("INSERT INTO orders ...").await?;
let sp = tx.save_point("before_items").await?;
tx.execute("INSERT INTO items ...").await?;
// Oops, rollback just the items
tx.rollback_to(&sp).await?;
tx.commit().await?;Sourcepub async fn rollback_to(&mut self, savepoint: &SavePoint) -> Result<()>
pub async fn rollback_to(&mut self, savepoint: &SavePoint) -> Result<()>
Rollback to a savepoint.
This rolls back all changes made after the savepoint was created, but keeps the transaction active. The savepoint remains valid and can be rolled back to again.
§Example
let sp = tx.save_point("checkpoint").await?;
// ... do some work ...
tx.rollback_to(&sp).await?; // Undo changes since checkpoint
// Transaction is still active, savepoint is still validSourcepub async fn release_savepoint(&mut self, savepoint: SavePoint) -> Result<()>
pub async fn release_savepoint(&mut self, savepoint: SavePoint) -> Result<()>
Release a savepoint (optional cleanup).
Note: SQL Server doesn’t have explicit savepoint release, but this method is provided for API completeness. The savepoint is automatically released when the transaction commits or rolls back.
Sourcepub fn cancel_handle(&self) -> CancelHandle
pub fn cancel_handle(&self) -> CancelHandle
Get a handle for cancelling the current query within the transaction.
See Client<Ready>::cancel_handle for usage examples.