1 个不稳定版本

0.1.0 2021年4月3日

#1977数据库接口

MIT 许可证

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