#sqlite #ffi

rusqlite-le

SQLite的便捷封装

1个不稳定版本

0.24.2 2020年12月23日

#1531数据库接口

Download history 18/week @ 2024-03-11 22/week @ 2024-03-18 50/week @ 2024-03-25 64/week @ 2024-04-01 14/week @ 2024-04-08 26/week @ 2024-04-15 23/week @ 2024-04-22 7/week @ 2024-04-29 20/week @ 2024-05-06 27/week @ 2024-05-13 37/week @ 2024-05-20 12/week @ 2024-05-27 10/week @ 2024-06-03 7/week @ 2024-06-10 10/week @ 2024-06-17 43/week @ 2024-06-24

71 每月下载量
2 crate 中使用

MIT 许可证

10MB
211K SLoC

C 163K SLoC // 0.3% comments Rust 48K SLoC // 0.0% comments Shell 38 SLoC // 0.2% comments

Rusqlite

Travis Build Status AppVeyor Build Status Build Status dependency status Latest Version Gitter Docs codecov

Rusqlite 是从 Rust 使用 SQLite 的便捷封装。它试图提供一个与 rust-postgres 类似的接口。

use rusqlite::{params, Connection, Result};

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    data: Option<Vec<u8>>,
}

fn main() -> Result<()> {
    let conn = Connection::open_in_memory()?;

    conn.execute(
        "CREATE TABLE person (
                  id              INTEGER PRIMARY KEY,
                  name            TEXT NOT NULL,
                  data            BLOB
                  )",
        [],
    )?;
    let me = Person {
        id: 0,
        name: "Steven".to_string(),
        data: None,
    };
    conn.execute(
        "INSERT INTO person (name, data) VALUES (?1, ?2)",
        params![me.name, me.data],
    )?;

    let mut stmt = conn.prepare("SELECT id, name, data FROM person")?;
    let person_iter = stmt.query_map([], |row| {
        Ok(Person {
            id: row.get(0)?,
            name: row.get(1)?,
            data: row.get(2)?,
        })
    })?;

    for person in person_iter {
        println!("Found person {:?}", person.unwrap());
    }
    Ok(())
}

支持的SQLite版本

基本 rusqlite 包支持 SQLite 版本 3.6.8 或更高版本。如果您需要支持旧版本,请提交一个问题。一些 cargo 功能需要更高版本的 SQLite;请参见下面的详细信息。

可选功能

Rusqlite 提供了一些在 Cargo 功能 之后的特性。它们是

  • load_extension 允许加载基于动态库的 SQLite 扩展。
  • backup 允许使用 SQLite 的在线备份 API。注意:此功能需要 SQLite 3.6.11 或更高版本。
  • functions 允许您将 Rust 闭包加载到 SQLite 连接中以在查询中使用。注意:此功能需要 SQLite 3.7.3 或更高版本。
  • window 用于 窗口函数 支持 (fun(...) OVER ...)。 (隐含 functions)
  • trace 允许挂载到 SQLite 的跟踪和性能分析 API。注意:此功能需要 SQLite 3.6.23 或更高版本。
  • blob 提供对 SQL BLOB 的 std::io::{Read, Write, Seek} 访问。注意:此功能需要 SQLite 3.7.4 或更高版本。
  • limits 允许您设置和检索 SQLite 每个连接的限制。
  • chronochrono 中的各种类型实现了 FromSqlToSql
  • serde_json 实现了来自 FromSqlToSqlValue 类型,来自 serde_json
  • time 实现了来自 FromSqlToSqltime::OffsetDateTime 类型,来自 time
  • url 实现了来自 FromSqlToSqlUrl 类型,来自 url
  • bundled 使用了捆绑版本的 SQLite。这对于像 Windows 这样的链接到 SQLite 复杂的情况是一个好选择。
  • sqlcipher 查找 SQLCipher 库以链接,而不是 SQLite。此功能与 bundled 兼容性互斥。
  • hooks 用于 提交、回滚数据更改 通知回调。
  • unlock_notify 用于 解锁 通知。
  • vtab 用于 虚拟表 支持(允许你在 Rust 中编写虚拟表实现)。目前,仅支持只读虚拟表。
  • series 揭示了 generate_series(...) 表值函数。(隐含 vtab。)
  • csvtab,用 Rust 编写的 CSV 虚拟表。(隐含 vtab。)
  • arrayrarray() 表值函数。(隐含 vtab。)
  • i128_blob 允许在 SQLite 数据库中存储 i128 类型的值。内部,数据以 16 字节的大端 blob 存储,最高有效位翻转,这允许存储不同 blob 中的 i128 进行排序和比较,以符合预期。
  • uuid 允许使用 blob 存储和检索 uuid 包中的 Uuid 值。
  • session,会话模块扩展。需要 buildtime_bindgen 功能。(隐含 hooks。)
  • extra_check 当执行传递的查询为只读或列计数 > 0 时失败。
  • column_decltype 为语句和行提供了 columns() 方法;如果链接的是使用 -DSQLITE_OMIT_DECLTYPE 编译的 SQLite/SQLCipher 版本,则可以省略。
  • collation 提供了 sqlite3_create_collation_v2

关于构建 rusqlite 和 libsqlite3-sys 的说明

libsqlite3-sys 是一个独立的 crate,它提供了 SQLite C API 的 Rust 声明。默认情况下,libsqlite3-sys 会尝试使用 pkg-config 在您的系统上找到现有的 SQLite 库,或者使用 MSVC ABI 构建所需的 Vcpkg 安装。

您可以通过多种方式调整此行为

  • 如果您使用 bundled 功能,libsqlite3-sys 将使用 cc crate 从源代码编译 SQLite 并链接到它。此源代码嵌入在 libsqlite3-sys crate 中,目前是 SQLite 3.34.0(截至 rusqlite 0.24.1 / libsqlite3-sys 0.21.0)。这可能是最简单的解决方案。您可以通过在您的 Cargo.toml 文件中添加以下内容来启用此功能

    [dependencies.rusqlite]
    version = "0.24.2"
    features = ["bundled"]
    
  • 当使用 bundled 功能时,构建脚本将遵守 SQLITE_MAX_VARIABLE_NUMBERSQLITE_MAX_EXPR_DEPTH 变量。它还将遵守一个 LIBSQLITE3_FLAGS 变量,其格式可能如下所示:"-USQLITE_ALPHA -DSQLITE_BETA SQLITE_GAMMA ..."。这将禁用 SQLITE_ALPHA 标志,并设置 SQLITE_BETASQLITE_GAMMA 标志。(最后一个 -D 可以省略。)

  • 当链接到系统上已有的 SQLite 库时(即不使用 bundled 功能),您可以设置 SQLITE3_LIB_DIR 环境变量,使其指向包含库的目录。您还可以设置 SQLITE3_INCLUDE_DIR 变量,使其指向包含 sqlite3.h 的目录。

  • 安装 sqlite3 开发包通常就足够了,但 pkg-configvcpkg 的构建助手有一些额外的配置选项。使用 vcpkg 的默认设置是动态链接,必须在构建前设置 VCPKGRS_DYNAMIC=1 环境变量。运行 vcpkg install sqlite3:x64-windows 将安装所需的库。

  • 当链接到系统上已有的 SQLite 库时,您可以设置 SQLITE3_STATIC 环境变量为 1,以请求将库静态链接而不是动态链接。

绑定生成

我们使用 bindgen 从 SQLite 的 C 头文件生成 Rust 声明。bindgen 建议 将此作为使用此库的库的构建过程的一部分来运行。我们尝试过这样做(具体为 rusqlite 0.10.0),但有一些不便之处

  • libsqlite3-sys(以及因此 rusqlite)的构建时间显著增加。
  • 运行 bindgen 需要一个相对较新的 Clang 版本,许多系统默认并未安装。
  • 运行 bindgen 还需要存在 SQLite 的头文件。

截至 rusqlite 0.10.1,我们通过提供多个 SQLite 版本的预生成绑定来避免在构建时运行 bindgen。在编译 rusqlite 时,我们使用您选择的 Cargo 功能来选择支持您所选功能的最低 SQLite 版本的绑定。如果您直接使用 libsqlite3-sys,您可以使用相同的功能来选择使用的预生成绑定

  • min_sqlite_version_3_6_8 - SQLite 3.6.8 绑定(这是默认设置)
  • min_sqlite_version_3_7_16 - SQLite 3.7.16 绑定

如果您使用 bundled 功能,您将获得 SQLite捆绑版本的预生成绑定。如果您需要其他特定版本的预生成绑定,请提交问题。如果您想在构建时运行 bindgen 来生成自己的绑定,请使用 buildtime_bindgen Cargo 功能。

如果您启用 modern_sqlite 功能,我们将使用捆绑构建中包含的绑定。您通常应该启用 buildtime_bindgen,因为否则您需要将链接的 SQLite 版本与 rusqlite 捆绑的版本保持同步(通常是 SQLite 的最新版本)。如果未这样做,将导致运行时错误。

贡献

Rusqlite 有许多功能,其中许多功能以不兼容的方式影响构建配置。这是不幸的,使得测试更改变得困难。

为了帮助这里:您通常应该确保您为 --features bundled--features "bundled-full session buildtime_bindgen" 运行测试/lint。

如果您运行 bindgen 的问题,请使用 --features bundled-full 启用捆绑以及所有不需要绑定生成的功能,并将其用作替代品。

检查清单

  • 运行 cargo fmt 以确保您的 Rust 代码格式正确。
  • 确保 cargo clippy --all-targets --workspace --features bundled 无警告通过。
  • 确保 cargo clippy --all-targets --workspace --features "bundled-full session buildtime_bindgen" 无警告通过。
  • 确保 cargo test --all-targets --workspace --features bundled 报告没有失败。
  • 确保执行 cargo test --all-targets --workspace --features "bundled-full session buildtime_bindgen" 不报告任何失败。

作者

Rusqlite 是由多人共同努力的成果。名单可在此处找到:[https://github.com/rusqlite/rusqlite/graphs/contributors](https://github.com/rusqlite/rusqlite/graphs/contributors)

社区

目前为 rusqlite 建立了 Gitter 频道。[在此处](https://gitter.im/rusqlite/community)

许可证

Rusqlite 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。

依赖项