#sqlite #ffi #sql-cipher #native-bindings

sys libsqlite3-sys-le

libsqlite3 库的本地绑定

1 个不稳定版本

0.21.0 2020年12月23日

#2135数据库接口

Download history 82/week @ 2024-04-01 20/week @ 2024-04-08 30/week @ 2024-04-15 32/week @ 2024-04-22 10/week @ 2024-04-29 29/week @ 2024-05-06 27/week @ 2024-05-13 46/week @ 2024-05-20 12/week @ 2024-05-27 15/week @ 2024-06-03 10/week @ 2024-06-10 22/week @ 2024-06-17 40/week @ 2024-06-24 364/week @ 2024-07-01 24/week @ 2024-07-08 14/week @ 2024-07-15

444 每月下载量
3 个 Crates 中使用(通过 rusqlite-le

MIT 许可证

9.5MB
200K SLoC

C 163K SLoC // 0.3% comments Rust 36K SLoC // 0.0% comments Shell 28 SLoC // 0.2% comments

Rusqlite

Latest Version Documentation Build Status (GitHub) Build Status (AppVeyor) Code Coverage Dependency Status Discord Chat

Rusqlite 是 Rust 从 SQLite 使用的一个便捷包装器。

历史上,API 基于 rust-postgres 的 API。然而,这两个项目在许多方面都分道扬镳,两者之间没有兼容性。

用法

在您的 Cargo.toml 中

[dependencies]
# `bundled` causes us to automatically compile and link in an up to date
# version of SQLite for you. This avoids many common build issues, and
# avoids depending on the version of SQLite on the users system (or your
# system), which may be old or missing. It's the right choice for most
# programs that control their own SQLite databases.
#
# That said, it's not ideal for all scenarios and in particular, generic
# libraries built around `rusqlite` should probably not enable it, which
# is why it is not a default feature -- it could become hard to disable.
rusqlite = { version = "0.31.0", features = ["bundled"] }

简单示例用法

use rusqlite::{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
        )",
        (), // empty list of parameters.
    )?;
    let me = Person {
        id: 0,
        name: "Steven".to_string(),
        data: None,
    };
    conn.execute(
        "INSERT INTO person (name, data) VALUES (?1, ?2)",
        (&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.14.0 或更高版本。如果您需要支持旧版本,请提交一个问题。一些 cargo 功能需要更高版本的 SQLite;请参阅以下详细信息。

可选功能

Rusqlite 提供了一些功能,它们在 Cargo 功能 中。它们是

  • load_extension 允许加载基于动态库的 SQLite 扩展。
  • loadable_extension 用于在 Rust 中编程 可加载扩展
  • backup 允许使用 SQLite 的在线备份 API。
  • functions 允许您将 Rust 闭包加载到 SQLite 连接中以供查询使用。
  • window 支持 窗口函数fun(...) OVER ...)。(意味着 functions。)
  • trace 允许挂载到 SQLite 的跟踪和剖析 API。
  • blob 为 SQL BLOB 提供了 std::io::{Read, Write, Seek} 访问。
  • limits 允许您设置和检索 SQLite 的每个连接限制。
  • chronoFromSqlToSql 实现了来自 chrono 的多种类型的支持。
  • serde_jsonFromSqlToSql 实现了来自 serde_jsonValue 类型支持。
  • time 为来自 time 的多种类型实现了 FromSqlToSql
  • url 为来自 urlUrl 类型实现了 FromSqlToSql
  • bundled 使用了捆绑版本的 SQLite。这在需要复杂链接到 SQLite 的情况下是一个好选项,例如 Windows。
  • sqlcipher 寻找 SQLCipher 库来链接,而不是 SQLite。此功能覆盖了 bundled
  • bundled-sqlcipher 使用了 SQLCipher 的捆绑版本。它搜索并链接到系统安装的加密库,以提供加密实现。
  • bundled-sqlcipher-vendored-openssl 允许使用带有供应商版本的 OpenSSL(通过 openssl-sys 包)的捆绑-sqlcipher 作为加密提供者。
    • 如名称所示,这依赖于 bundled-sqlcipher 功能,并自动将其打开。
    • 如果开启,这将使用 openssl-sys 包,并启用 vendored 功能,以便构建和捆绑 OpenSSL 加密库。
  • hooks提交、回滚数据更改 通知回调。
  • preupdate_hookpreupdate 通知回调。(隐含 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,Session 模块扩展。需要 buildtime_bindgen 功能。(隐含 hooks。)
  • extra_check 在执行传递的查询为只读或列数 > 0 时失败。
  • column_decltype 为语句和行提供 columns() 方法;如果链接到使用 -DSQLITE_OMIT_DECLTYPE 编译的 SQLite/SQLCipher 版本,则省略。
  • collation 揭示 sqlite3_create_collation_v2
  • serialize 揭示 sqlite3_serialize(3.23.0)。

关于构建 rusqlite 和 libsqlite3-sys 的注意事项

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

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

  • 如果您使用 bundledbundled-sqlcipherbundled-sqlcipher-vendored-openssl 功能,则 libsqlite3-sys 将使用 cc crate 从源代码编译 SQLite 或 SQLCipher 并链接到它。此源代码嵌入在 libsqlite3-sys crate 中,目前是 SQLite 3.45.1(截至 rusqlite 0.31.0 / libsqlite3-sys 0.28.0)。这可能是解决任何构建问题的最简单方法。您可以通过在 Cargo.toml 文件中添加以下内容来启用此功能

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

  • 当使用 bundled-sqlcipher(并且不使用 bundled-sqlcipher-vendored-openssl)时,libsqlite3-sys 需要链接到系统上的加密库。如果构建脚本可以找到来自 OpenSSL 或 LibreSSL 的 libcrypto(它将咨询 OPENSSL_LIB_DIR/OPENSSL_INCLUDE_DIROPENSSL_DIR 环境变量),则使用该库。如果在 Mac 上构建并针对 Mac,并且没有设置这些变量,则将使用系统的 SecurityFramework。

  • 当链接到系统上已存在的SQLite(或SQLCipher)库(因此使用任何bundled功能)时,可以将环境变量SQLITE3_LIB_DIR(或SQLCIPHER_LIB_DIR)设置为一个包含库的目录。您还可以将环境变量SQLITE3_INCLUDE_DIR(或SQLCIPHER_INCLUDE_DIR)设置为一个包含sqlite3.h的目录。

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

  • 当链接到系统上已存在的SQLite(或SQLCipher)库时,可以将环境变量SQLITE3_STATIC(或SQLCIPHER_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_14_0 - SQLite 3.14.0绑定(这是默认值)

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

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

贡献

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

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

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

清单

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

作者

Rusqlite 是许多人辛勤工作的成果。名单在此:[https://github.com/rusqlite/rusqlite/graphs/contributors](https://github.com/rusqlite/rusqlite/graphs/contributors)

社区

欢迎加入 Rusqlite Discord 服务器 讨论或寻求关于 rusqlitelibsqlite3-sys 的帮助。

许可证

Rusqlite 和 libsqlite3-sys 在 MIT 许可证下可用。更多信息请参阅 LICENSE 文件。

捆绑软件的许可证

根据启用的 cargo features 集合,rusqlite 和 libsqlite3-sys 还将捆绑其他库,这些库有自己的许可证,如描述 此处

  • 如果启用 --features=bundled-sqlcipher,则将编译和静态链接 SQLcipher 的源代码。SQLcipher 在 BSD-style 许可证下分发,如此处所述。

  • 如果启用 --features=bundled,则将编译和链接 SQLite 的源代码。SQLite 处于公有领域,如此处所述。

这两者都很宽松,不会影响 rusqlitelibsqlite3-sys 本身的代码许可证,并且如果您不使用这些功能,可以完全忽略。

依赖项