1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3#![deny(unsafe_code)]
4
5pub mod blob;
21pub mod blob_stream;
22pub(crate) mod browser;
23pub mod bulk;
24pub mod cancel;
25pub mod change_tracking;
26pub mod client;
27#[cfg(feature = "always-encrypted")]
28pub(crate) mod column_decryptor;
29pub(crate) mod column_parser;
30pub mod config;
31pub mod encryption;
32pub mod error;
33#[cfg(all(windows, feature = "filestream"))]
34#[allow(unsafe_code)] pub mod filestream;
36pub mod from_row;
37pub mod instrumentation;
38pub(crate) mod plp;
39pub mod procedure;
40pub mod query;
41pub mod row;
42pub(crate) mod row_source;
44pub mod row_stream;
45pub mod state;
46pub(crate) mod statement_cache;
50pub mod stream;
51pub mod to_params;
52pub mod transaction;
53pub mod tvp;
54pub(crate) mod validation;
55
56pub use bulk::{
58 BulkColumn, BulkInsert, BulkInsertBuilder, BulkInsertResult, BulkOptions, BulkWriter,
59};
60pub use cancel::CancelHandle;
61pub use client::Client;
62pub use config::{ApplicationIntent, Config, RedirectConfig, RetryPolicy, TimeoutConfig};
63pub use error::{Error, SharedIoError};
64pub use statement_cache::StatementCacheStats;
65pub use mssql_auth::AuthError;
72pub use mssql_codec::CodecError;
73#[cfg(feature = "tls")]
74pub use mssql_tls::TlsError;
75pub use mssql_types::TypeError;
76pub use tds_protocol::ProtocolError;
77
78#[cfg(feature = "tls")]
82pub use mssql_tls::{CertificateDer, TlsConfig};
83
84#[cfg(feature = "always-encrypted")]
88pub use mssql_auth::KeyStoreProvider;
89
90pub use tds_protocol::token::Collation;
94
95#[cfg(feature = "derive")]
102pub use mssql_derive::{FromRow, ToParams, Tvp};
103
104#[doc(hidden)]
108pub mod __private {
109 pub use mssql_types::{ToSql, TypeError};
110}
111
112pub use from_row::{FromRow, MapRows, RowIteratorExt};
114pub use mssql_auth::Credentials;
115pub use tds_protocol::version::TdsVersion;
116
117#[cfg(feature = "zeroize")]
119pub use mssql_auth::{SecretString, SecureCredentials};
120pub use mssql_types::{
121 Binary, Char, EncryptedParamType, FromSql, NChar, SqlTyped, SqlValue, ToSql, TypedNull, binary,
122 char, nchar, null,
123};
124#[cfg(feature = "chrono")]
125pub use mssql_types::{
126 DateTime2, DateTimeLegacy, DateTimeOffset, SmallDateTime, Time, datetime, datetime2,
127 datetimeoffset, time,
128};
129#[cfg(feature = "decimal")]
130pub use mssql_types::{Money, Numeric, SmallMoney, numeric};
131pub use procedure::ProcedureBuilder;
132pub use query::in_params;
133pub use row::{Column, Row};
134pub use state::{Connected, ConnectionState, Disconnected, InTransaction, ProtocolState, Ready};
135
136#[cfg(feature = "fuzzing")]
141#[doc(hidden)]
142pub mod __fuzzing {
143 pub use crate::column_parser::parse_column_value;
144}
145
146#[cfg(feature = "bench")]
151#[doc(hidden)]
152#[allow(clippy::expect_used)]
153pub mod __bench {
154 use bytes::Bytes;
155 use tds_protocol::token::{Token, TokenParser};
156
157 use crate::Ready;
158 use crate::client::Client;
159 use crate::row::Row;
160
161 #[must_use]
170 pub fn decode_buffered_response(bytes: Bytes) -> Vec<Row> {
171 let mut parser = TokenParser::new(bytes);
172 let mut row_meta = std::sync::Arc::new(crate::row::ColMetaData::new(Vec::new()));
173 let mut meta = None;
174 let mut rows = Vec::new();
175 while let Some(token) = parser
176 .next_token_with_metadata(meta.as_ref())
177 .expect("benchmark fixture must decode")
178 {
179 match token {
180 Token::ColMetaData(m) => {
181 row_meta = std::sync::Arc::new(crate::row::ColMetaData::new(
182 Client::<Ready>::build_columns(&m),
183 ));
184 meta = Some(m);
185 }
186 Token::Row(raw) => {
187 let m = meta.as_ref().expect("ColMetaData precedes ROW tokens");
188 rows.push(
189 crate::column_parser::convert_raw_row(&raw, m, &row_meta)
190 .expect("benchmark row must convert"),
191 );
192 }
193 _ => {}
194 }
195 }
196 rows
197 }
198}
199pub use blob_stream::BlobStream;
200pub use row_stream::RowStream;
201pub use stream::{
202 ExecuteResult, MultiResultStream, OutputParam, ProcedureResult, QueryStream, ResultSet,
203};
204pub use to_params::{NamedParam, ParamList, ToParams};
205pub use transaction::{IsolationLevel, SavePoint};
206pub use tvp::{Tvp, TvpColumn, TvpRow, TvpValue};
207
208#[cfg(all(windows, feature = "filestream"))]
210pub use filestream::{FileStream, FileStreamAccess, open_options as filestream_options};
211
212pub use encryption::EncryptionConfig;
214
215pub use instrumentation::{
217 DatabaseMetrics, OperationTimer, SanitizationConfig, attributes, metric_names, span_names,
218};
219
220pub use change_tracking::{
222 ChangeMetadata, ChangeOperation, ChangeTracking, ChangeTrackingQuery, SyncVersionStatus,
223};
224
225#[cfg(test)]
226mod auto_trait_tests {
227 use super::*;
234
235 fn assert_send<T: Send>() {}
236 fn assert_sync<T: Sync>() {}
237
238 #[test]
240 fn client_ready_is_send_sync() {
241 assert_send::<Client<Ready>>();
242 assert_sync::<Client<Ready>>();
243 }
244
245 #[test]
246 fn client_in_transaction_is_send_sync() {
247 assert_send::<Client<InTransaction>>();
248 assert_sync::<Client<InTransaction>>();
249 }
250
251 #[test]
252 fn client_disconnected_is_send_sync() {
253 assert_send::<Client<Disconnected>>();
254 assert_sync::<Client<Disconnected>>();
255 }
256
257 #[test]
258 fn client_connected_is_send_sync() {
259 assert_send::<Client<Connected>>();
260 assert_sync::<Client<Connected>>();
261 }
262
263 #[test]
265 fn config_is_send_sync() {
266 assert_send::<Config>();
267 assert_sync::<Config>();
268 }
269
270 #[test]
272 fn query_stream_is_send_sync() {
273 assert_send::<QueryStream<'_>>();
274 assert_sync::<QueryStream<'_>>();
275 }
276
277 #[test]
278 fn row_stream_is_send_sync() {
279 assert_send::<RowStream<'_>>();
280 assert_sync::<RowStream<'_>>();
281 }
282
283 #[test]
284 fn blob_stream_is_send_sync() {
285 assert_send::<BlobStream<'_>>();
286 assert_sync::<BlobStream<'_>>();
287 }
288
289 #[test]
290 fn multi_result_stream_is_send_sync() {
291 assert_send::<MultiResultStream<'_>>();
292 assert_sync::<MultiResultStream<'_>>();
293 }
294
295 #[test]
296 fn result_set_is_send_sync() {
297 assert_send::<ResultSet>();
298 assert_sync::<ResultSet>();
299 }
300
301 #[test]
302 fn execute_result_is_send_sync() {
303 assert_send::<ExecuteResult>();
304 assert_sync::<ExecuteResult>();
305 }
306
307 #[test]
308 fn procedure_result_is_send_sync() {
309 assert_send::<ProcedureResult>();
310 assert_sync::<ProcedureResult>();
311 }
312
313 #[test]
314 fn procedure_builder_is_send_sync() {
315 assert_send::<ProcedureBuilder<'_, Ready>>();
316 assert_sync::<ProcedureBuilder<'_, Ready>>();
317 }
318
319 #[test]
321 fn bulk_insert_is_send_sync() {
322 assert_send::<BulkInsert>();
323 assert_sync::<BulkInsert>();
324 }
325
326 #[test]
327 fn bulk_insert_builder_is_send_sync() {
328 assert_send::<BulkInsertBuilder>();
329 assert_sync::<BulkInsertBuilder>();
330 }
331
332 #[test]
333 fn bulk_options_is_send_sync() {
334 assert_send::<BulkOptions>();
335 assert_sync::<BulkOptions>();
336 }
337
338 #[test]
340 fn cancel_handle_is_send_sync() {
341 assert_send::<CancelHandle>();
342 assert_sync::<CancelHandle>();
343 }
344
345 #[test]
347 fn row_is_send_sync() {
348 assert_send::<Row>();
349 assert_sync::<Row>();
350 }
351
352 #[test]
353 fn column_is_send_sync() {
354 assert_send::<Column>();
355 assert_sync::<Column>();
356 }
357
358 #[test]
360 fn statement_cache_is_send_sync() {
361 use crate::statement_cache::StatementCache;
362 assert_send::<StatementCache>();
363 assert_sync::<StatementCache>();
364 }
365
366 #[test]
368 fn error_is_send_sync() {
369 assert_send::<Error>();
370 assert_sync::<Error>();
371 }
372}