mod builder;
mod compactor;
mod info;
use std::path::{Path, PathBuf};
use std::time::Duration;
pub use builder::{Journaling, SqliteBuilder};
use compactor::Compactor;
pub use info::{Info, VersionError};
use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
use thiserror::Error;
use crate::sync::EagerFutureCell;
#[derive(Debug, Clone)]
pub struct Sqlite {
pool: SqlitePool,
info: EagerFutureCell<Info>,
compactor: Compactor,
}
#[derive(Debug, Error)]
pub enum SqliteOpenOrCreateError {
#[error("the given path is a dangling symlink")]
BadSymlink(PathBuf),
#[error("failed to create directory for sqlite database: {0}")]
FailedToCreateDir(std::io::Error),
#[error("failed to parse connection options: {0}")]
ConenctOptionsParsing(sqlx::Error),
#[error("failed to create the sqlite pool")]
PoolCreateError(sqlx::Error),
#[error("failed to restrict permissions on the sqlite database: {0}")]
FailedToSetPermissions(std::io::Error),
}
impl Sqlite {
#[must_use]
pub fn builder<P: AsRef<Path>>(path: P) -> SqliteBuilder<P> {
SqliteBuilder::new(path)
}
async fn connect(
opts: SqliteConnectOptions,
timeout: Duration,
) -> Result<Self, SqliteOpenOrCreateError> {
let pool = SqlitePoolOptions::new()
.acquire_timeout(timeout)
.connect_with(opts)
.await
.map_err(SqliteOpenOrCreateError::PoolCreateError)?;
Ok(Self {
info: Info::new_eager_future(pool.clone()),
pool,
compactor: Compactor::inactive(),
})
}
pub fn pool(&self) -> &SqlitePool {
&self.pool
}
#[must_use]
pub async fn info(&self) -> Info {
self.info.get().await
}
#[cfg(feature = "test-utils")]
pub async fn close(&self) {
self.pool.close().await;
}
}