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::Query;
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 state::Streaming;
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 transaction::Transaction;
pub use tvp::Tvp;
pub use tvp::TvpColumn;
pub use tvp::TvpRow;
pub use tvp::TvpValue;
pub use encryption::EncryptionContext;
pub use encryption::EncryptionConfig;
pub use encryption::ParameterCryptoInfo;
pub use encryption::ParameterEncryptionInfo;
pub use encryption::ResultSetEncryptionInfo;
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.
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 builder and prepared statement support.
row
Row representation for query results.
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§

CertificateDer
A DER-encoded X.509 certificate; as specified in RFC 5280
Collation
SQL Server collation.
DecimalParamInfo
Explicit precision and scale for a decimal/numeric parameter (see numeric).
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.
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).
TdsVersion
TDS protocol version.
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.
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§

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.

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).