Skip to main content

Crate mssql_client

Crate mssql_client 

Source
Expand description

§mssql-client

High-level async SQL Server client with type-state connection management.

§Overview

This is the primary public API surface for the rust-mssql-driver project. It provides a type-safe, ergonomic interface for working with SQL Server databases using modern async Rust patterns.

§Features

  • Type-state pattern: Compile-time enforcement of connection states
  • Async/await: Built on Tokio for efficient async I/O
  • Parameterized queries: Server-side plan reuse via sp_executesql (a client-side statement cache is planned)
  • Transactions: Full transaction support with savepoints
  • Azure support: Automatic routing and failover handling
  • Lazy row decoding: Rows decode on demand from the buffered response (true streaming from the socket is planned)
  • Bulk insert: Bulk data loading via BCP
  • Table-valued parameters: Pass collections to stored procedures

§Type-State Connection Management

The client uses a compile-time type-state pattern that ensures invalid operations are caught at compile time:

Disconnected -> Ready (via connect())
Ready -> InTransaction (via begin_transaction())
InTransaction -> Ready (via commit() or rollback())

§Usage

use mssql_client::{Client, Config};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::from_connection_string(
        "Server=localhost;Database=test;User Id=sa;Password=Password123",
    )?;

    let mut client = Client::connect(config).await?;

    // Execute a query with parameters
    let rows = client
        .query("SELECT * FROM users WHERE id = @p1", &[&1i32])
        .await?;

    // QueryStream yields Result<Row, Error>
    for result in rows {
        let row = result?;
        let name: String = row.get(0)?;
        println!("User: {}", name);
    }

    Ok(())
}

§Transactions with Savepoints

use mssql_client::{Client, Config};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::from_connection_string(
        "Server=localhost;Database=test;User Id=sa;Password=Password123",
    )?;
    let client = Client::connect(config).await?;

    // begin_transaction() consumes the client and returns Client<InTransaction>
    let mut tx = client.begin_transaction().await?;
    tx.execute("INSERT INTO users (name) VALUES (@p1)", &[&"Alice"]).await?;

    // Create a savepoint for partial rollback
    let sp = tx.save_point("before_update").await?;
    tx.execute("UPDATE users SET active = 1", &[]).await?;

    // Rollback to savepoint if needed
    tx.rollback_to(&sp).await?;

    tx.commit().await?;
    Ok(())
}

§Large Result Sets

use mssql_client::{Client, Config};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::from_connection_string(
        "Server=localhost;Database=test;User Id=sa;Password=Password123",
    )?;
    let mut client = Client::connect(config).await?;

    // The response is buffered, but rows decode lazily as they are consumed —
    // only one decoded Row is alive at a time.
    let stream = client.query("SELECT * FROM large_table", &[]).await?;

    for result in stream {
        let row = result?;
        let _ = row; // Process each row as it decodes
    }
    Ok(())
}

§Bulk Insert

use mssql_client::{BulkColumn, BulkInsertBuilder, Client, Config, SqlValue};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::from_connection_string(
        "Server=localhost;Database=test;User Id=sa;Password=Password123",
    )?;
    let mut client = Client::connect(config).await?;

    let builder = BulkInsertBuilder::new("dbo.users").with_typed_columns(vec![
        BulkColumn::new("id", "INT", 0)?,
        BulkColumn::new("name", "NVARCHAR(100)", 1)?,
    ]);

    let mut writer = client.bulk_insert(&builder).await?;
    writer.send_row_values(&[SqlValue::Int(1), SqlValue::String("Alice".into())])?;
    writer.send_row_values(&[SqlValue::Int(2), SqlValue::String("Bob".into())])?;

    let result = writer.finish().await?;
    println!("Inserted {} rows", result.rows_affected);
    Ok(())
}

§Feature Flags

FlagDefaultDescription
chronoYesDate/time type support via chrono
uuidYesUUID type support
decimalYesDecimal type support via rust_decimal
encodingYesCollation-aware VARCHAR decoding
jsonNoJSON type support via serde_json
otelNoOpenTelemetry instrumentation
zeroizeNoSecure credential wiping
always-encryptedNoClient-side encryption with key providers

§Modules

ModuleDescription
clientMain Client type and connection management
configConnection configuration and parsing
queryQuery building and execution
rowRow and column access
streamResult streaming types
transactionTransaction and savepoint handling
bulkBulk insert operations
tvpTable-valued parameters
from_rowRow-to-struct mapping trait
to_paramsStruct-to-parameters trait
instrumentationOpenTelemetry integration

§Examples

See the examples/ directory for complete examples:

  • basic.rs - Simple queries and parameter binding
  • transactions.rs - Transaction handling with savepoints
  • bulk_insert.rs - Bulk loading
  • derive_macros.rs - Using #[derive(FromRow)] and #[derive(ToParams)]
  • streaming.rs - Iterating large result sets (lazy row decoding)

§Development

Built with heavy AI assistance, with a human maintainer reviewing and accountable for every change. The protocol layer has unit and property tests, and an integration suite runs against a real SQL Server in CI; known gaps are tracked in LIMITATIONS.md.

§License

MIT OR Apache-2.0

Re-exports§

pub use bulk::BulkColumn;
pub use bulk::BulkInsert;
pub use bulk::BulkInsertBuilder;
pub use bulk::BulkInsertResult;
pub use bulk::BulkOptions;
pub use bulk::BulkWriter;
pub use cancel::CancelHandle;
pub use client::Client;
pub use config::ApplicationIntent;
pub use config::Config;
pub use config::RedirectConfig;
pub use config::RetryPolicy;
pub use config::TimeoutConfig;
pub use error::Error;
pub use error::SharedIoError;
pub use from_row::FromRow;
pub use from_row::MapRows;
pub use from_row::RowIteratorExt;
pub use procedure::ProcedureBuilder;
pub use query::in_params;
pub use row::Column;
pub use row::Row;
pub use state::Connected;
pub use state::ConnectionState;
pub use state::Disconnected;
pub use state::InTransaction;
pub use state::ProtocolState;
pub use state::Ready;
pub use blob_stream::BlobStream;
pub use row_stream::RowStream;
pub use stream::ExecuteResult;
pub use stream::MultiResultStream;
pub use stream::OutputParam;
pub use stream::ProcedureResult;
pub use stream::QueryStream;
pub use stream::ResultSet;
pub use to_params::NamedParam;
pub use to_params::ParamList;
pub use to_params::ToParams;
pub use transaction::IsolationLevel;
pub use transaction::SavePoint;
pub use tvp::Tvp;
pub use tvp::TvpColumn;
pub use tvp::TvpRow;
pub use tvp::TvpValue;
pub use encryption::EncryptionConfig;
pub use instrumentation::DatabaseMetrics;
pub use instrumentation::OperationTimer;
pub use instrumentation::SanitizationConfig;
pub use instrumentation::attributes;
pub use instrumentation::metric_names;
pub use instrumentation::span_names;
pub use change_tracking::ChangeMetadata;
pub use change_tracking::ChangeOperation;
pub use change_tracking::ChangeTracking;
pub use change_tracking::ChangeTrackingQuery;
pub use change_tracking::SyncVersionStatus;

Modules§

blob
Streaming large object (LOB) reader for VARBINARY(MAX) and TEXT types.
blob_stream
Streaming a row’s trailing MAX column directly from the socket.
bulk
Bulk Copy Protocol (BCP) support.
cancel
Query cancellation support.
change_tracking
SQL Server Change Tracking support.
client
SQL Server client implementation.
config
Client configuration.
encryption
Always Encrypted client-side encryption and decryption.
error
Client error types.
from_row
FromRow trait for automatic row-to-struct mapping.
instrumentation
OpenTelemetry instrumentation for database operations.
procedure
Stored procedure builder for constructing and executing RPC calls.
query
Query helper utilities.
row
Row representation for query results.
row_stream
True incremental row streaming: rows pulled from the socket on demand.
state
Connection state types for type-state pattern.
stream
Query result sets with lazy per-row decoding.
to_params
ToParams trait for automatic struct-to-parameters mapping.
transaction
Transaction support.
tvp
Table-Valued Parameters (TVP) support.

Structs§

Binary
A fixed-length binary(length) parameter for an Always Encrypted column (see binary).
CertificateDer
A DER-encoded X.509 certificate; as specified in RFC 5280
Char
A fixed-length char(length) parameter for an Always Encrypted column (see char()).
Collation
SQL Server collation.
DateTime2
A datetime2(scale) parameter for an Always Encrypted column (see datetime2).
DateTimeLegacy
A legacy datetime parameter for an Always Encrypted column (see datetime).
DateTimeOffset
A datetimeoffset(scale) parameter for an Always Encrypted column (see datetimeoffset).
Money
Wrapper that sends its inner rust_decimal::Decimal as SQL Server MONEY (signed 64-bit fixed-point scaled by 10_000) instead of DECIMAL.
NChar
A fixed-length nchar(length) parameter for an Always Encrypted column (see nchar).
Numeric
A decimal/numeric parameter with explicit precision and scale.
SecretString
A secret string that is securely zeroed from memory when dropped.
SecureCredentials
Secure credentials with automatic zeroization on drop.
SmallDateTime
Wrapper that sends its inner chrono::NaiveDateTime as SQL Server SMALLDATETIME (4-byte days-since-1900 + minutes-since-midnight) instead of DATETIME2.
SmallMoney
Wrapper that sends its inner rust_decimal::Decimal as SQL Server SMALLMONEY (signed 32-bit fixed-point scaled by 10_000).
StatementCacheStats
A point-in-time snapshot of a connection’s prepared-statement cache.
TdsVersion
TDS protocol version.
Time
A time(scale) parameter for an Always Encrypted column (see time).
TlsConfig
TLS configuration for SQL Server connections.
TypedNull
A typed NULL parameter, created with null.

Enums§

AuthError
Errors that can occur during authentication.
CodecError
Errors that can occur during packet encoding/decoding.
Credentials
Credentials for SQL Server authentication.
EncryptedParamType
The explicit SQL type for an Always Encrypted parameter whose value cannot convey it (see numeric, time, datetime2, datetimeoffset, datetime). Carries the precision/scale/length the encrypted column requires the declared parameter type to match exactly.
ProtocolError
Errors that can occur during TDS protocol parsing or encoding.
SqlValue
A SQL value that can represent any SQL Server data type.
TlsError
Errors that can occur during TLS operations.
TypeError
Errors that can occur during type conversion.

Traits§

FromSql
Trait for types that can be converted from SQL values.
KeyStoreProvider
Trait for Column Master Key (CMK) providers.
SqlTyped
Associates a Rust type with its SQL type name so a typed NULL can be declared without a value (see null).
ToSql
Trait for types that can be converted to SQL values.

Functions§

binary
Create a binary(length) parameter for an Always Encrypted binary column.
char
Create a char(length) parameter for an Always Encrypted char column.
datetime
Create a legacy datetime parameter for an Always Encrypted datetime column. A plain NaiveDateTime defaults to datetime2, which an encrypted legacy datetime column rejects; this declares datetime explicitly.
datetime2
Create a datetime2(scale) parameter for an Always Encrypted datetime2 column. A plain NaiveDateTime defaults to datetime2(7), so an explicit scale is required to match a column with a different scale (and to encrypt at the right byte length). scale is the fractional-second digits (0–7).
datetimeoffset
Create a datetimeoffset(scale) parameter for an Always Encrypted datetimeoffset column. scale is the fractional-second digits (0–7).
nchar
Create an nchar(length) parameter for an Always Encrypted nchar column.
null
Create a typed NULL parameter for SQL type T, e.g. null::<i32>().
numeric
Create a decimal/numeric parameter with explicit precision and scale.
time
Create a time(scale) parameter for an Always Encrypted time column.

Derive Macros§

FromRow
Derive macro for implementing FromRow trait.
ToParams
Derive macro for implementing ToParams trait.
Tvp
Derive macro for implementing Tvp trait (Table-Valued Parameters).