1 个不稳定版本
0.1.0 | 2021年4月3日 |
---|
#1977 在 数据库接口
12KB
159 行
bb8-rusqlite
此 crate 提供了一个连接管理器,您可以使用它与 bb8 一起提供 rusqlite 连接池。
示例
请参阅 examples/basic.rs
以查看一个自包含示例,但基本上,它看起来是这样的
let manager = RusqliteConnectionManager::new("my-database.db");
let pool = bb8::Pool::builder().build(manager).await?;
// ...
let conn = pool.get().await?;
// conn is a rusqlite::Connection, so do whatever you'd normally do with it!
注意事项
不支持内存数据库
rusqlite
允许使用 Connection::open_in_memory
系列方法创建内存数据库。内存 SQLite 数据库是每个连接的,这意味着拥有这些连接池会导致每个连接都有自己的、完全独立的数据库!
这可能会相当令人困惑,因此不提供这些方法的包装器。另外,除非您喜欢代码中非常奇怪的错误,否则请不要使用 rusqlite::OpenFlags::SQLITE_OPEN_MEMORY
。
rusqlite::Connection
仍然非常同步
bb8
在底层大量使用 tokio,而这个连接管理器也是如此。然而,您最终将处理 rusqlite::Connection
实例,而这些实例不提供任何异步 API。
如果您关心并发性,请确保通过标记使用 Connection
的任务为阻塞,避免长时间占用运行时。您可以通过将 Connection
移动到另一个阻塞任务或使用 tokio::task::block_in_place()
来完成此操作。实际上,在大多数情况下,您可能想要使用后者:将 Connection
实例移动到另一个任务中是危险的,因为它们没有实现 Sync
。
需要 tokio 的多线程运行时
由于上述 Connection
同步性,bb8-rusqlite
必须 与多线程执行器一起使用,以便可以使用 tokio::task::block_in_place()
。
未来可能性
bb8-diesel
采用了一种有趣的替代方法:通过使用 block_in_place()
对同步 Diesel API 进行包装,提供了一种更安全、仍然是同步的 API,从而降低了线程池饥饿的可能性。
这里的一个有趣的未来工作将是做同样的事情:使用 block_in_place()
将 rusqlite
类型包装在包装器中,然后实现一个返回这些包装器而不是原始 rusqlite::Connection
实例的连接管理器。这更难一些,因为 Connection
是一个具体类型,而不是 trait,但是通过大量的模板代码和一些 Deref
实现来作为后备,这应该是可能的。自私地说,我现在根本不需要它!
依赖项
~32MB
~505K SLoC