Skip to main content

Client

Struct Client 

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

A connection to SQL Server.

Connect once and reuse it; every statement travels over the same connection.

use tdsql::{Client, Config};

let mut client = Client::connect(&Config::new()
    .host("localhost")
    .database("master")
    .auth("sa", "YourStrong!Passw0rd")
    .trust_cert()).await?;

let rows = client.query("SELECT id, name FROM users WHERE id > @P1", &[&10i32]).await?;
for row in &rows {
    let id: i32 = row.get("id");
    let name: String = row.get("name");
    println!("{id}: {name}");
}

§Cancelling

Stop waiting for a request – drop its future, let a timeout or select! give up on it, abort the task running it, drop a RowStream early – and it is cancelled on the server too, so it stops holding the connection, the server’s time and any locks it has taken. The connection stays usable. A request still queued behind another never runs; one already running is stopped where it is, even before it has sent anything back, and the statements after it in the same batch don’t run.

Transaction control – begin, commit, rollback, savepoints – always runs, whatever became of its future. And cancelling stops a statement, not the transaction around it: work finished before the cancel stays done, as it would if the statement had failed, so put statements that must stand or fall together in a Transaction.

Implementations§

Source§

impl Client

Source

pub async fn connect(config: &Config) -> Result<Self>

Connect using this configuration.

Gives up after the configuration’s connect timeout, 15 seconds unless set. A named instance given without a port (host\INSTANCE) is found through SQL Server Browser, and a redirect to another server, as Azure SQL’s gateway sends, is followed.

Source

pub async fn connect_str(connection_string: &str) -> Result<Self>

Connect using an ADO.NET-style connection string.

Source

pub async fn query( &mut self, sql: &str, params: &[&dyn ToSql], ) -> Result<Vec<Row>>

Run a query and collect every row of the first result set.

Parameters are positional: @P1 is params[0].

Source

pub async fn query_stream( &mut self, sql: &str, params: &[&dyn ToSql], ) -> Result<RowStream<'_>>

Run a query and receive the rows of its first result set as the server sends them, rather than all at once after the last one arrives.

Returns as soon as the server has described the columns, so a statement the server rejects fails here, just as it would from query. A failure partway through arrives as the stream’s last item instead, after the rows that came before it.

The stream borrows the client until it is dropped; see RowStream for what that holds up, and what happens if it is dropped early.

let mut rows = client
    .query_stream("SELECT id, name FROM users WHERE id > @P1", &[&10i32])
    .await?;

while let Some(row) = rows.try_next().await? {
    let name: String = row.get("name");
    println!("{name}");
}
Source

pub async fn query_one( &mut self, sql: &str, params: &[&dyn ToSql], ) -> Result<Row>

Run a query expecting exactly one row.

Fails with Error::UnexpectedRowCount for any other count.

Source

pub async fn query_opt( &mut self, sql: &str, params: &[&dyn ToSql], ) -> Result<Option<Row>>

Run a query expecting at most one row.

Fails with Error::UnexpectedRowCount if more than one comes back.

Source

pub async fn query_scalar<T: FromSql>( &mut self, sql: &str, params: &[&dyn ToSql], ) -> Result<T>

Run a query and read the first column of the first row.

Use Option<T> as T to accept a NULL. Fails with Error::UnexpectedRowCount if the query returns no rows.

Source

pub async fn execute(&mut self, sql: &str, params: &[&dyn ToSql]) -> Result<u64>

Run a statement that returns no rows, and report how many rows it affected.

If the batch holds several statements, the counts are summed.

Source

pub async fn batch(&mut self, sql: &str) -> Result<Vec<Row>>

Run a SQL batch verbatim, with no parameters, and collect its rows.

Parameterised statements are sent as an RPC, and some statements — CREATE PROCEDURE, CREATE VIEW, CREATE TRIGGER — must be the first statement of their own batch, so they cannot go that route. Use this for DDL, and execute or query for everything else.

Because the SQL is sent verbatim, never interpolate untrusted input into it; use parameters instead.

client
    .batch("CREATE PROCEDURE dbo.sp_demo AS BEGIN SELECT 1; END")
    .await?;
Source

pub async fn batch_dataset(&mut self, sql: &str) -> Result<DataSet>

Run a SQL batch verbatim and collect every result set it produces.

Source

pub async fn query_dataset(&mut self, command: &Command) -> Result<DataSet>

Run a Command and collect every result set it produces.

This is the path for stored procedures and for batches that return more than one result set.

Source

pub async fn execute_command(&mut self, command: &Command) -> Result<u64>

Run a Command for its row count rather than its rows.

Source

pub async fn transaction(&mut self) -> Result<Transaction<'_>>

Begin a transaction at READ COMMITTED, SQL Server’s default isolation level.

The returned Transaction borrows this client, so nothing else can use the connection until it is committed, rolled back, or dropped.

let mut tx = client.transaction().await?;
tx.execute("INSERT INTO orders (id) VALUES (@P1)", &[&1i32]).await?;
tx.commit().await?;
Source

pub async fn transaction_with_isolation( &mut self, level: IsolationLevel, ) -> Result<Transaction<'_>>

Begin a transaction at an explicit isolation level.

Once it ends, the connection goes back to READ COMMITTED.

Source

pub async fn close(self) -> Result<()>

Close the connection, sending a graceful logout.

Trait Implementations§

Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Executor for Client

Source§

fn transaction( &mut self, ) -> impl Future<Output = Result<Transaction<'_>>> + Send

Open a transaction scoped to this executor. Read more
Source§

fn query( &mut self, sql: &str, params: &[&dyn ToSql], ) -> impl Future<Output = Result<Vec<Row>>> + Send

Run a query and collect every row of the first result set.
Source§

fn query_stream( &mut self, sql: &str, params: &[&dyn ToSql], ) -> impl Future<Output = Result<RowStream<'_>>> + Send

Run a query and receive the rows of its first result set as they arrive.
Source§

fn query_one( &mut self, sql: &str, params: &[&dyn ToSql], ) -> impl Future<Output = Result<Row>> + Send

Run a query expecting exactly one row.
Source§

fn query_opt( &mut self, sql: &str, params: &[&dyn ToSql], ) -> impl Future<Output = Result<Option<Row>>> + Send

Run a query expecting at most one row.
Source§

fn query_scalar<T: FromSql + Send>( &mut self, sql: &str, params: &[&dyn ToSql], ) -> impl Future<Output = Result<T>> + Send

Run a query and read the first column of the first row.
Source§

fn execute( &mut self, sql: &str, params: &[&dyn ToSql], ) -> impl Future<Output = Result<u64>> + Send

Run a statement and report how many rows it affected.
Source§

fn batch(&mut self, sql: &str) -> impl Future<Output = Result<Vec<Row>>> + Send

Run a SQL batch verbatim and collect its rows.
Source§

fn batch_dataset( &mut self, sql: &str, ) -> impl Future<Output = Result<DataSet>> + Send

Run a SQL batch verbatim and collect every result set.
Source§

fn query_dataset( &mut self, command: &Command, ) -> impl Future<Output = Result<DataSet>> + Send

Run a Command and collect every result set it produces.
Source§

fn execute_command( &mut self, command: &Command, ) -> impl Future<Output = Result<u64>> + Send

Run a Command for its row count rather than its rows.

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more