use futures::future::join_all;
use tempfile::tempdir;
use super::*;
#[derive(Debug)]
struct TempDir {
dir: tempfile::TempDir,
}
impl TempDir {
fn new() -> anyhow::Result<Self> {
Ok(Self { dir: tempdir()? })
}
fn file(&self, name: &str) -> PathBuf {
self.dir.path().join(name)
}
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn connect_error() -> Result<(), anyhow::Error> {
let temp = TempDir::new()?;
let manager = RusqliteConnectionManager::new_with_flags(
temp.file("connect_error.db"),
OpenFlags::SQLITE_OPEN_READ_ONLY,
);
let pool = bb8::Pool::builder().build(manager).await?;
pool.dedicated_connection().await.expect_err("this connection must fail, since the database doesn't exist and the read only flag was provided");
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn flags() -> Result<(), anyhow::Error> {
let temp = TempDir::new()?;
let path = temp.file("flags.db");
let conn = Connection::open(&path)?;
conn.execute("CREATE TABLE t (a INTEGER)", [])?;
drop(conn);
let manager =
RusqliteConnectionManager::new_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_ONLY);
let pool = bb8::Pool::builder().build(manager).await?;
let conn = pool.get().await?;
conn.execute("INSERT INTO t (a) VALUES (?)", [42])
.expect_err("writing to a read-only database must fail");
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn plain() -> Result<(), anyhow::Error> {
let temp = TempDir::new()?;
let manager = RusqliteConnectionManager::new(temp.file("plain.db"));
let pool = bb8::Pool::builder().build(manager).await?;
let first = pool.get().await?;
first.execute("CREATE TABLE t (a INTEGER)", [])?;
let second = pool.get().await?;
second.execute("INSERT INTO t (a) VALUES (?)", [42])?;
join_all((0..8).map(|_| {
let local_pool = pool.clone();
tokio::spawn(async move {
let conn = local_pool.get().await.unwrap();
let v: i32 = conn
.query_row("SELECT a FROM t", [] , |row| row.get(0))
.unwrap();
assert_eq!(v, 42);
})
}))
.await;
Ok(())
}