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 从uuid
crate 存储和检索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-sys
crate 中,目前为 SQLite 3.46.0(截至rusqlite
0.32.0 /libsqlite3-sys
0.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