pub struct Client<S: AsyncRead + AsyncWrite + Unpin + Send> { /* private fields */ }
Expand description
Client
is the main entry point to the SQL Server, providing query
execution capabilities.
A Client
is created using the Config
, defining the needed
connection options and capabilities.
§Example
use tokio_util::compat::TokioAsyncWriteCompatExt;
let mut config = Config::new();
config.host("0.0.0.0");
config.port(1433);
config.authentication(AuthMethod::sql_server("SA", "<Mys3cureP4ssW0rD>"));
let tcp = tokio::net::TcpStream::connect(config.get_addr()).await?;
tcp.set_nodelay(true)?;
// Client is ready to use.
let client = tiberius::Client::connect(config, tcp.compat_write()).await?;
Implementations§
Source§impl<S: AsyncRead + AsyncWrite + Unpin + Send> Client<S>
impl<S: AsyncRead + AsyncWrite + Unpin + Send> Client<S>
Sourcepub async fn connect(config: Config, tcp_stream: S) -> Result<Client<S>>
pub async fn connect(config: Config, tcp_stream: S) -> Result<Client<S>>
Uses an instance of Config
to specify the connection
options required to connect to the database using an established
tcp connection
Sourcepub async fn execute<'a>(
&mut self,
query: impl Into<Cow<'a, str>>,
params: &[&dyn ToSql],
) -> Result<ExecuteResult>
pub async fn execute<'a>( &mut self, query: impl Into<Cow<'a, str>>, params: &[&dyn ToSql], ) -> Result<ExecuteResult>
Executes SQL statements in the SQL Server, returning the number rows
affected. Useful for INSERT
, UPDATE
and DELETE
statements. The
query
can define the parameter placement by annotating them with
@PN
, where N is the index of the parameter, starting from 1
. If
executing multiple queries at a time, delimit them with ;
and refer to
ExecuteResult
how to get results for the separate queries.
For mapping of Rust types when writing, see the documentation for
ToSql
. For reading data from the database, see the documentation for
FromSql
.
This API is not quite suitable for dynamic query parameters. In these
cases using a Query
object might be easier.
§Example
let results = client
.execute(
"INSERT INTO ##Test (id) VALUES (@P1), (@P2), (@P3)",
&[&1i32, &2i32, &3i32],
)
.await?;
Sourcepub async fn query<'a, 'b>(
&'a mut self,
query: impl Into<Cow<'b, str>>,
params: &'b [&'b dyn ToSql],
) -> Result<QueryStream<'a>>where
'a: 'b,
pub async fn query<'a, 'b>(
&'a mut self,
query: impl Into<Cow<'b, str>>,
params: &'b [&'b dyn ToSql],
) -> Result<QueryStream<'a>>where
'a: 'b,
Executes SQL statements in the SQL Server, returning resulting rows.
Useful for SELECT
statements. The query
can define the parameter
placement by annotating them with @PN
, where N is the index of the
parameter, starting from 1
. If executing multiple queries at a time,
delimit them with ;
and refer to QueryStream
on proper stream
handling.
For mapping of Rust types when writing, see the documentation for
ToSql
. For reading data from the database, see the documentation for
FromSql
.
This API can be cumbersome for dynamic query parameters. In these cases,
if fighting too much with the compiler, using a Query
object might be
easier.
§Example
let stream = client
.query(
"SELECT @P1, @P2, @P3",
&[&1i32, &2i32, &3i32],
)
.await?;
Sourcepub async fn simple_query<'a, 'b>(
&'a mut self,
query: impl Into<Cow<'b, str>>,
) -> Result<QueryStream<'a>>where
'a: 'b,
pub async fn simple_query<'a, 'b>(
&'a mut self,
query: impl Into<Cow<'b, str>>,
) -> Result<QueryStream<'a>>where
'a: 'b,
Execute multiple queries, delimited with ;
and return multiple result
sets; one for each query.
§Example
let row = client.simple_query("SELECT 1 AS col").await?.into_row().await?.unwrap();
assert_eq!(Some(1i32), row.get("col"));
§Warning
Do not use this with any user specified input. Please resort to prepared
statements using the query
method.
Sourcepub async fn bulk_insert<'a>(
&'a mut self,
table: &'a str,
) -> Result<BulkLoadRequest<'a, S>>
pub async fn bulk_insert<'a>( &'a mut self, table: &'a str, ) -> Result<BulkLoadRequest<'a, S>>
Execute a BULK INSERT
statement, efficiantly storing a large number of
rows to a specified table. Note: make sure the input row follows the same
schema as the table, otherwise calling send()
will return an error.
§Example
let create_table = r#"
CREATE TABLE ##bulk_test (
id INT IDENTITY PRIMARY KEY,
val INT NOT NULL
)
"#;
client.simple_query(create_table).await?;
// Start the bulk insert with the client.
let mut req = client.bulk_insert("##bulk_test").await?;
for i in [0i32, 1i32, 2i32] {
let row = (i).into_row();
// The request will handle flushing to the wire in an optimal way,
// balancing between memory usage and IO performance.
req.send(row).await?;
}
// The request must be finalized.
let res = req.finalize().await?;
assert_eq!(3, res.total());