3 个版本 (重大更新)
| 0.3.0 | 2024年7月21日 |
|---|---|
| 0.2.0 | 2024年2月17日 |
| 0.1.0 | 2023年11月12日 |
在 数据库接口 中排名 2147
每月下载量 322
在 rusqlite 中使用
6KB
95 行
Rusqlite
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.32.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 的每个连接限制。chrono实现了从FromSql和ToSql为chrono包 中的各种类型。serde_json实现了从FromSql和ToSql为serde_json包 中的Value类型。time实现了从FromSql和ToSql为time包 中的各种类型。url实现了从FromSql和ToSql为url包 中的Url类型。bundled使用了捆绑版本的 SQLite。这对于链接到 SQLite 复杂的情况(如 Windows)是一个好选择。sqlcipher会寻找 SQLCipher 库来链接,而不是 SQLite。这个特性会覆盖bundled。bundled-sqlcipher使用了捆绑版本的 SQLCipher。它搜索并链接到一个系统安装的加密库,以提供加密实现。bundled-sqlcipher-vendored-openssl允许使用捆绑的 SQLCipher 与 OpenSSL 的捆绑版本(通过openssl-sys包)作为加密提供者。- 如名称所示,这依赖于
bundled-sqlcipher特性,并自动开启它。 - 如果开启,这将使用
openssl-sys包,并启用vendored特性以构建和捆绑 OpenSSL 加密库。
- 如名称所示,这依赖于
hooks为 提交、回滚 和 数据变更 通知回调。preupdate_hook为 preupdate 通知回调。(隐含hooks。)unlock_notify为 解锁 通知。vtab为 虚拟表 支持(允许你在 Rust 中编写虚拟表实现)。目前,仅支持只读虚拟表。series公开了generate_series(...)表值函数。(隐含vtab。)csvtab,使用 Rust 编写的 CSV 虚拟表。(隐含vtab。)array,rarray()表值函数。(隐含vtab。)i128_blob允许在 SQLite 数据库中存储i128类型的值。内部,数据以 16 字节的大端 blob 存储的,最高有效位被翻转,这使得不同 blob 之间存储 i128 的排序和比较可以按预期工作。uuid允许使用 blob 从uuidcrate 存储和检索Uuid值。session,Session 模块扩展。需要buildtime_bindgen功能。(隐含hooks。)extra_check在执行只读查询或列数大于 0 时失败。column_decltype为 Statements 和 Rows 提供了columns()方法;如果链接到使用-DSQLITE_OMIT_DECLTYPE编译的 SQLite/SQLCipher 版本,则省略。collation暴露了sqlite3_create_collation_v2。serialize暴露了sqlite3_serialize(3.23.0)。
关于构建 rusqlite 和 libsqlite3-sys 的说明
libsqlite3-sys 是一个与 rusqlite 分离的 crate,它提供了 SQLite 的 Rust 声明。默认情况下,libsqlite3-sys 尝试使用 pkg-config 在您的系统上查找已存在的 SQLite 库,或者使用 Vcpkg 安装 MSVC ABI 构建。
您可以通过多种方式调整此行为
-
如果您使用
bundled、bundled-sqlcipher或bundled-sqlcipher-vendored-openssl功能,libsqlite3-sys将使用 cc crate 从源代码编译 SQLite 或 SQLCipher,并将其链接到该库。此源代码嵌入到libsqlite3-syscrate 中,目前为 SQLite 3.46.0(截至rusqlite0.32.0 /libsqlite3-sys0.30.0)。这可能是解决任何构建问题的最简单方法。您可以通过在Cargo.toml文件中添加以下内容来启用此功能[dependencies.rusqlite] version = "0.32.0" features = ["bundled"] -
使用任何
bundled功能时,构建脚本将尊重SQLITE_MAX_VARIABLE_NUMBER和SQLITE_MAX_EXPR_DEPTH变量。它还将尊重一个LIBSQLITE3_FLAGS变量,其格式如下"-USQLITE_ALPHA -DSQLITE_BETA SQLITE_GAMMA ..."。这将禁用SQLITE_ALPHA标志,并设置SQLITE_BETA和SQLITE_GAMMA标志。(最后的-D可以省略。) -
当使用
bundled-sqlcipher(且不使用bundled-sqlcipher-vendored-openssl)时,libsqlite3-sys需要链接到系统上的加密库。如果构建脚本可以找到 OpenSSL 或 LibreSSL 的libcrypto(它将咨询OPENSSL_LIB_DIR/OPENSSL_INCLUDE_DIR和OPENSSL_DIR环境变量),它将使用该库。如果在 Mac 上构建,并且没有设置这些变量,它将使用系统的 SecurityFramework。 -
当链接到系统上现有的 SQLite(或 SQLCipher)库(因此不使用任何
bundled功能)时,您可以设置SQLITE3_LIB_DIR(或SQLCIPHER_LIB_DIR)环境变量,使其指向包含库的目录。您还可以设置SQLITE3_INCLUDE_DIR(或SQLCIPHER_INCLUDE_DIR)变量,使其指向包含sqlite3.h的目录。 -
安装sqlite3开发包通常就足够了,但用于pkg-config和vcpkg的构建辅助程序有一些额外的配置选项。使用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和--features "bundled-full session buildtime_bindgen"运行测试/lint。
如果运行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)
社区
欢迎加入 [Rusqlite Discord 服务器](https://discord.gg/nFYfGPB8g4) 讨论或寻求关于 rusqlite 或 libsqlite3-sys 的帮助。
许可证
Rusqlite 和 libsqlite3-sys 在 MIT 许可证下可用。更多信息请参阅 LICENSE 文件。
捆绑软件的许可证
根据启用的 cargo features,rusqlite 和 libsqlite3-sys 还将捆绑其他库,这些库有自己的许可条款
-
如果启用了
--features=bundled-sqlcipher,则会编译并静态链接 SQLcipher 的供应商源代码。SQLcipher 在 BSD 样式许可证下分发,如[此处](https://github.com/rusqlite/rusqlite/blob/09bd40b3f126cdc333db537e3387e1a34dcc1a58/libsqlite3-sys/sqlcipher/LICENSE)所述。 -
如果启用了
--features=bundled,则会编译并链接 SQLite 的供应商源代码。SQLite 属于公有领域,如[此处](https://www.sqlite.org/copyright.html)所述。
这两者都相当宽松,不影响 rusqlite 或 libsqlite3-sys 本身的许可证,如果您不使用相关功能,可以完全忽略。
lib.rs:
rusqlite 的私有实现细节。
依赖项
~1.8–2.4MB
~47K SLoC