use std::{convert::Infallible, path::PathBuf, time::Duration};
use deadpool::managed::{QueueMode, Timeouts};
use rusqlite::OpenFlags;
use super::{
CreatePoolError, Manager, Pool, PoolBuilder, PoolConfig, Runtime, RusqlitePool, SqliteConn,
noop_transform,
};
#[derive(Clone, Debug, Default)]
pub struct Config {
pub path: PathBuf,
pub open_flags: OpenFlags,
pub pool: PoolConfig,
}
impl Config {
#[must_use]
pub fn new(path: impl Into<PathBuf>) -> Self {
Self {
path: path.into(),
open_flags: OpenFlags::default(),
pool: PoolConfig {
max_size: 20,
timeouts: Timeouts {
wait: Some(Duration::from_secs(30)),
..Default::default()
},
queue_mode: QueueMode::default(),
},
}
}
pub fn read_only(mut self) -> Self {
self.open_flags =
OpenFlags::empty() | OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX;
self
}
pub fn max_size(mut self, value: usize) -> Self {
self.pool.max_size = value;
self
}
pub fn create_pool(&self) -> Result<RusqlitePool, CreatePoolError> {
self.builder(noop_transform)
.map_err(CreatePoolError::Config)?
.build()
.map_err(CreatePoolError::Build)
}
pub fn create_pool_transform<T: SqliteConn>(
&self,
f: impl Fn(rusqlite::Connection) -> Result<T, rusqlite::Error> + Send + Sync + 'static,
) -> Result<Pool<T>, CreatePoolError> {
self.builder(f)
.map_err(CreatePoolError::Config)?
.build()
.map_err(CreatePoolError::Build)
}
pub fn builder<T: SqliteConn>(
&self,
f: impl Fn(rusqlite::Connection) -> Result<T, rusqlite::Error> + Send + Sync + 'static,
) -> Result<PoolBuilder<T>, ConfigError> {
let manager = Manager::from_config(self, f);
Ok(Pool::builder(manager)
.config(self.get_pool_config())
.runtime(Runtime::Tokio1))
}
#[must_use]
pub fn get_pool_config(&self) -> PoolConfig {
self.pool
}
}
pub type ConfigError = Infallible;