1 个不稳定版本
0.28.1 | 2023 年 1 月 17 日 |
---|---|
0.28.0 |
|
#203 在 #sqlite
56 每月下载
在 ic-sqlite 中使用
625KB
13K SLoC
Rusqlite
Rusqlite 是从 Rust 使用 SQLite 的舒适包装。
历史上,API 是基于 rust-postgres
的。然而,这两个项目在很多方面都发生了分歧,并且不打算在它们之间提供兼容性。
用法
在您的 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.28.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.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 的每连接限制。chrono
实现了FromSql
和ToSql
接口,用于chrono
库 中的多种类型。serde_json
实现了FromSql
和ToSql
接口,用于serde_json
库 中的Value
类型。time
实现了FromSql
和ToSql
接口,用于time
库 中的time::OffsetDateTime
类型。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
用于 提交、回滚 和 数据更改 通知回调。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
值,该功能通过uuid
包实现。session
,Session 模块扩展。需要buildtime_bindgen
功能。(隐含hooks
。)extra_check
当执行查询时,如果查询是只读的或者列数大于 0,则会失败。column_decltype
为语句和行提供columns()
方法;如果链接到使用-DSQLITE_OMIT_DECLTYPE
编译的 SQLite/SQLCipher 版本,则省略。collation
提供了sqlite3_create_collation_v2
。winsqlite3
允许链接到 Windows 新版本中现有的 SQLite。
关于构建 rusqlite 和 libsqlite3-sys 的注意事项
libsqlite3-sys
是一个与 rusqlite
分离的 crate,它提供了 SQLite C API 的 Rust 声明。默认情况下,libsqlite3-sys
尝试使用 pkg-config 在您的系统上查找已存在的 SQLite 库,或者对于 MSVC ABI 构建使用 Vcpkg 安装。
您可以通过多种方式调整此行为
-
如果您使用
bundled
、bundled-sqlcipher
或bundled-sqlcipher-vendored-openssl
功能,libsqlite3-sys
将使用 cc crate 从源代码编译 SQLite 或 SQLCipher 并将其链接。此源代码嵌入在libsqlite3-sys
crate 中,目前是 SQLite 3.39.0(截至rusqlite
0.28.0 /libsqlite3-sys
0.25.0)。这可能是解决任何构建问题的最简单方法。您可以在Cargo.toml
文件中添加以下内容来启用此功能[dependencies.rusqlite] version = "0.28.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)库(因此不使用任何
捆绑
功能)时,您可以设置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_6_8
- SQLite 3.6.8绑定(这是默认值)min_sqlite_version_3_6_23
- SQLite 3.6.23绑定min_sqlite_version_3_7_7
- SQLite 3.7.7绑定
如果您使用任何捆绑
功能,您将获得捆绑版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/froghub-io/rusqlite/blob/8ee227ca4ac2ea9709d8c5a41f8aca216f15d84a/libsqlite3-sys/sqlcipher/LICENSE)所述。 -
如果启用了
--features=bundled
,将编译并链接SQLite的源代码。SQLite属于公共领域,如[此处](https://www.sqlite.org/copyright.html)所述。
这两个都是相当自由的,不影响rusqlite
或libsqlite3-sys
本身的许可证,如果您不使用相关功能,可以完全忽略。
依赖项
~24–35MB
~550K SLoC