83 个版本

0.12.3 2024年7月19日
0.12.2 2023年4月18日
0.12.1 2023年2月10日
0.11.8 2024年7月19日
0.1.0 2016年5月6日

#17数据库接口

Download history 19330/week @ 2024-05-02 14315/week @ 2024-05-09 13016/week @ 2024-05-16 14519/week @ 2024-05-23 16853/week @ 2024-05-30 12557/week @ 2024-06-06 13949/week @ 2024-06-13 13565/week @ 2024-06-20 14400/week @ 2024-06-27 14976/week @ 2024-07-04 14489/week @ 2024-07-11 15081/week @ 2024-07-18 18078/week @ 2024-07-25 16195/week @ 2024-08-01 16341/week @ 2024-08-08 15158/week @ 2024-08-15

每月下载量68,854
用于 49 crate(直接使用 33 个)

MIT/Apache

455KB
10K SLoC

Tiberius

docs.rs Cargo tests Chat

Rust 的本地 Microsoft SQL Server (TDS) 客户端。

目标

  • 完美实现 TDS 协议。
  • 异步网络 IO。
  • 独立于网络协议。
  • 支持最新版本的 Linux、Windows 和 macOS。

非目标

  • 连接池(使用 bb8mobcdeadpool 或其他异步连接池)
  • 查询构建
  • 对象关系映射

支持的 SQL Server 版本

版本 支持级别 备注
2022 在 CI 上测试
2019 在 CI 上测试
2017 在 CI 上测试
2016 应该可以工作
2014 应该可以工作
2012 应该可以工作
2008 应该可以工作
2005 应该可以工作 禁用 tds73 功能标志。

功能标志

标志 描述 默认
tds73 支持 TDS 7.3 版本中的新日期和时间类型。如果使用 7.2 版本,则禁用。 启用
native-tls 使用操作系统的 TLS 库进行流量加密。 启用
rustls 使用 rustls 的内置 TLS 实现而不是链接到操作系统实现进行流量加密。 禁用
vendored-openssl 静态链接 OpenSSL 而不是动态链接到操作系统实现进行流量加密。 禁用
chrono 使用 chrono 的类型读取和写入日期和时间值。(对于新项目,建议使用 time 而不是 chrono) 禁用
time 使用 time crate 类型读取和写入日期和时间值。 禁用
rust_decimal 使用 rust_decimalDecimal 读取和写入 numeric/decimal 值。 禁用
bigdecimal 使用 bigdecimalBigDecimal 读取和写入 numeric/decimal 值。 禁用
sql-browser-async-std 为 async-std 的 TcpStream 实现的 SQL 浏览器。 禁用
sql-browser-tokio 为 Tokio 的 TcpStream 实现的 SQL 浏览器。 禁用
sql-browser-smol 为 smol 的 TcpStream 实现的 SQL 浏览器。 禁用
integrated-auth-gssapi 支持通过 GSSAPI 使用集成认证。 禁用

支持的协议

Tiberius 在连接到 SQL Server 实例时不依赖任何协议。相反,Clientfutures-rs 库中获取实现 AsyncReadAsyncWrite 特性的套接字。

目前,在 async-stdTokioSmol 项目中都有优秀的 TCP 异步实现。

为了能够在 Windows 平台上的 SQL Server 上与 Tiberius 一起使用,您应该确保已启用 TCP 协议,因为根据版本的不同,这可能是默认未启用的。标准版和企业版将默认启用设置,而开发者版、Express 版和 Windows Server OS 的 Windows 内部数据库功能则不会。要启用 TCP/IP 协议,您可能需要使用 服务器设置命令行。在官方 Docker 镜像 中,TCP 默认启用。

可以通过最新版本的 Tokio 中的 NamedPipeClient 使用命名管道。

共享内存协议未记录,并且似乎没有 Rust 库实现它。

加密(TLS/SSL)

Tiberius 可以设置为使用 TLS 连接加密的两种不同实现。默认情况下,它使用 native-tls,链接到操作系统提供的 TLS 库。这是一种良好的实践,在出现安全漏洞的情况下,升级系统库可以修复 Tiberius 中的漏洞而无需重新编译。在 Linux 上,我们链接到 OpenSSL,在 Windows 上链接到 schannel,在 macOS 上链接到 Security Framework。

或者,可以通过使用 rustls 功能标志来使用 Rust 本地 TLS 实现。这种方式没有对系统的动态依赖。在某些安装中可能很有用,但需要重新构建以更新到新的 TLS 版本。由于某些原因,macOS 上的 Security Framework 无法与 SQL Server TLS 设置一起使用,因此在 Apple 平台上如果需要 TLS,建议使用 rustls 而不是 native-tls。另一种选择是使用 vendored-openssl 功能标志,该标志静态链接到最新的 OpenSSL 实现。

还可以在没有 TLS 支持的情况下编译此库,但不能同时启用这两个功能。

Tiberius 有三个运行时加密设置

加密级别 描述
必需 所有流量都加密。 (默认值)
关闭 只有登录过程加密。
不支持 没有流量加密。

可以在连接到数据库时设置加密级别。

Unix-like 上的集成身份验证(TrustedConnection)

启用 integrated-auth-gssapi 功能后,该库需要安装 GSSAPI/Kerberos 库/头文件

  • CentOS
  • Arch
  • Debian(您需要 -dev 软件包来构建)
  • Ubuntu
  • NixOS:在存储库根目录上运行 nix-shell shell.nix
  • Mac: 从版本 0.4.2 开始,用于此功能的 libgssapi 包现在使用 Apple 的 GSS 框架,该框架随 MacOS 10.14 及更高版本一起提供。

此外,您的运行时系统需要被您 SQL Server 所在的 Active Directory 域信任,并已配置。特别是,您需要通过 kinit 或密钥表获取您身份的有效 TGT。此设置因环境和操作系统而异,但您的友好网络/系统管理员应该能够帮助您了解具体细节。

重定向

在某些 Azure 防火墙设置中,登录可能会返回 Error::Routing { host, port }。这意味着用户必须为给定地址创建一个新的 TcpStream,并重新连接。

简单连接过程如下

use tiberius::{Client, Config, AuthMethod, error::Error};
use tokio_util::compat::TokioAsyncWriteCompatExt;
use tokio::net::TcpStream;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut config = Config::new();

    config.host("0.0.0.0");
    config.port(1433);
    config.authentication(AuthMethod::sql_server("SA", "<Mys3cureP4ssW0rD>"));

    let tcp = TcpStream::connect(config.get_addr()).await?;
    tcp.set_nodelay(true)?;

    let client = match Client::connect(config, tcp.compat_write()).await {
        // Connection successful.
        Ok(client) => client,
        // The server wants us to redirect to a different address
        Err(Error::Routing { host, port }) => {
            let mut config = Config::new();

            config.host(&host);
            config.port(port);
            config.authentication(AuthMethod::sql_server("SA", "<Mys3cureP4ssW0rD>"));

            let tcp = TcpStream::connect(config.get_addr()).await?;
            tcp.set_nodelay(true)?;

            // we should not have more than one redirect, so we'll short-circuit here.
            Client::connect(config, tcp.compat_write()).await?
        }
        Err(e) => Err(e)?,
    };

    Ok(())
}

安全

如果您有安全问题要报告,请通过 [email protected] 联系我们

依赖关系

~5–20MB
~365K SLoC