Skip to main content

mssql_client/
lib.rs

1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3#![deny(unsafe_code)]
4
5// Module dependency graph (acyclic):
6//
7//   client ──→ config, state, error, stream, transaction, statement_cache
8//     ├── connect.rs ──→ config, state, instrumentation, mssql_tls, mssql_codec, tds_protocol
9//     ├── params.rs  ──→ mssql_types, tds_protocol
10//     └── response.rs ──→ error, mssql_codec, tds_protocol
11//   procedure ──→ client, error, state, stream, tds_protocol
12//   stream ──→ error, row
13//   row ──→ blob, error, mssql_types
14//   config ──→ mssql_auth, mssql_tls, tds_protocol
15//   bulk ──→ error, mssql_types, tds_protocol
16//   cancel ──→ error, mssql_codec, mssql_tls
17//   encryption ──→ mssql_auth, tds_protocol
18//   column_parser ──→ error, mssql_types, tds_protocol
19
20pub mod blob;
21pub(crate) mod browser;
22pub mod bulk;
23pub mod cancel;
24pub mod change_tracking;
25pub mod client;
26#[cfg(feature = "always-encrypted")]
27pub(crate) mod column_decryptor;
28pub(crate) mod column_parser;
29pub mod config;
30pub mod encryption;
31pub mod error;
32#[cfg(all(windows, feature = "filestream"))]
33#[allow(unsafe_code)] // Win32 FFI for OpenSqlFilestream; see SAFETY comments in each unsafe block
34pub mod filestream;
35pub mod from_row;
36pub mod instrumentation;
37pub mod procedure;
38pub mod query;
39pub mod row;
40pub mod state;
41pub mod statement_cache;
42pub mod stream;
43pub mod to_params;
44pub mod transaction;
45pub mod tvp;
46pub(crate) mod validation;
47
48// Re-export commonly used types
49pub use bulk::{
50    BulkColumn, BulkInsert, BulkInsertBuilder, BulkInsertResult, BulkOptions, BulkWriter,
51};
52pub use cancel::CancelHandle;
53pub use client::Client;
54pub use config::{ApplicationIntent, Config, RedirectConfig, RetryPolicy, TimeoutConfig};
55pub use error::{Error, SharedIoError};
56
57// Re-export TDS version for configuration
58pub use from_row::{FromRow, MapRows, RowIteratorExt};
59pub use mssql_auth::Credentials;
60pub use tds_protocol::version::TdsVersion;
61
62// Secure credential types (with zeroize feature)
63#[cfg(feature = "zeroize")]
64pub use mssql_auth::{SecretString, SecureCredentials};
65#[cfg(feature = "chrono")]
66pub use mssql_types::SmallDateTime;
67pub use mssql_types::{FromSql, SqlValue, ToSql};
68#[cfg(feature = "decimal")]
69pub use mssql_types::{Money, SmallMoney};
70pub use procedure::ProcedureBuilder;
71pub use query::{Query, in_params};
72pub use row::{Column, Row};
73pub use state::{
74    Connected, ConnectionState, Disconnected, InTransaction, ProtocolState, Ready, Streaming,
75};
76pub use statement_cache::{PreparedStatement, StatementCache, StatementCacheConfig};
77pub use stream::{
78    ExecuteResult, MultiResultStream, OutputParam, ProcedureResult, QueryStream, ResultSet,
79};
80pub use to_params::{NamedParam, ParamList, ToParams};
81pub use transaction::{IsolationLevel, SavePoint, Transaction};
82pub use tvp::{Tvp, TvpColumn, TvpRow, TvpValue};
83
84// FILESTREAM support (Windows only)
85#[cfg(all(windows, feature = "filestream"))]
86pub use filestream::{FileStream, FileStreamAccess, open_options as filestream_options};
87
88// Always Encrypted types
89#[cfg(feature = "always-encrypted")]
90pub use encryption::EncryptionContext;
91pub use encryption::{
92    EncryptionConfig, ParameterCryptoInfo, ParameterEncryptionInfo, ResultSetEncryptionInfo,
93};
94
95// OpenTelemetry instrumentation (available whether or not otel feature is enabled)
96pub use instrumentation::{
97    DatabaseMetrics, OperationTimer, SanitizationConfig, attributes, metric_names, span_names,
98};
99
100// Change Tracking support
101pub use change_tracking::{
102    ChangeMetadata, ChangeOperation, ChangeTracking, ChangeTrackingQuery, SyncVersionStatus,
103};
104
105#[cfg(test)]
106mod auto_trait_tests {
107    //! Compile-time assertions that key async types are Send + Sync.
108    //!
109    //! These tests catch regressions where a type accidentally becomes
110    //! !Send or !Sync due to interior changes (e.g., adding an Rc, Cell,
111    //! or non-Send future). They cost nothing at runtime.
112
113    use super::*;
114
115    fn assert_send<T: Send>() {}
116    fn assert_sync<T: Sync>() {}
117
118    // --- Type-state Client variants ---
119    #[test]
120    fn client_ready_is_send_sync() {
121        assert_send::<Client<Ready>>();
122        assert_sync::<Client<Ready>>();
123    }
124
125    #[test]
126    fn client_in_transaction_is_send_sync() {
127        assert_send::<Client<InTransaction>>();
128        assert_sync::<Client<InTransaction>>();
129    }
130
131    #[test]
132    fn client_disconnected_is_send_sync() {
133        assert_send::<Client<Disconnected>>();
134        assert_sync::<Client<Disconnected>>();
135    }
136
137    #[test]
138    fn client_connected_is_send_sync() {
139        assert_send::<Client<Connected>>();
140        assert_sync::<Client<Connected>>();
141    }
142
143    #[test]
144    fn client_streaming_is_send_sync() {
145        assert_send::<Client<Streaming>>();
146        assert_sync::<Client<Streaming>>();
147    }
148
149    // --- Configuration ---
150    #[test]
151    fn config_is_send_sync() {
152        assert_send::<Config>();
153        assert_sync::<Config>();
154    }
155
156    // --- Streaming types ---
157    #[test]
158    fn query_stream_is_send_sync() {
159        assert_send::<QueryStream<'_>>();
160        assert_sync::<QueryStream<'_>>();
161    }
162
163    #[test]
164    fn multi_result_stream_is_send_sync() {
165        assert_send::<MultiResultStream<'_>>();
166        assert_sync::<MultiResultStream<'_>>();
167    }
168
169    #[test]
170    fn result_set_is_send_sync() {
171        assert_send::<ResultSet>();
172        assert_sync::<ResultSet>();
173    }
174
175    #[test]
176    fn execute_result_is_send_sync() {
177        assert_send::<ExecuteResult>();
178        assert_sync::<ExecuteResult>();
179    }
180
181    #[test]
182    fn procedure_result_is_send_sync() {
183        assert_send::<ProcedureResult>();
184        assert_sync::<ProcedureResult>();
185    }
186
187    #[test]
188    fn procedure_builder_is_send_sync() {
189        assert_send::<ProcedureBuilder<'_, Ready>>();
190        assert_sync::<ProcedureBuilder<'_, Ready>>();
191    }
192
193    // --- Bulk insert types ---
194    #[test]
195    fn bulk_insert_is_send_sync() {
196        assert_send::<BulkInsert>();
197        assert_sync::<BulkInsert>();
198    }
199
200    #[test]
201    fn bulk_insert_builder_is_send_sync() {
202        assert_send::<BulkInsertBuilder>();
203        assert_sync::<BulkInsertBuilder>();
204    }
205
206    #[test]
207    fn bulk_options_is_send_sync() {
208        assert_send::<BulkOptions>();
209        assert_sync::<BulkOptions>();
210    }
211
212    // --- Cancel handle ---
213    #[test]
214    fn cancel_handle_is_send_sync() {
215        assert_send::<CancelHandle>();
216        assert_sync::<CancelHandle>();
217    }
218
219    // --- Row and column types ---
220    #[test]
221    fn row_is_send_sync() {
222        assert_send::<Row>();
223        assert_sync::<Row>();
224    }
225
226    #[test]
227    fn column_is_send_sync() {
228        assert_send::<Column>();
229        assert_sync::<Column>();
230    }
231
232    // --- Statement cache ---
233    #[test]
234    fn statement_cache_is_send_sync() {
235        assert_send::<StatementCache>();
236        assert_sync::<StatementCache>();
237    }
238
239    // --- Error type ---
240    #[test]
241    fn error_is_send_sync() {
242        assert_send::<Error>();
243        assert_sync::<Error>();
244    }
245}