use std::backtrace::Backtrace;
use async_once_cell::OnceCell;
use snafu::ResultExt as _;
use snafu::Snafu;
use sqlx::SqliteConnection;
use sqlx::migrate::MigrateError;
use crate::databases::sqlite::database::SqliteDatabase;
use crate::databases::sqlite::pool::SqlitePool;
use crate::databases::sqlite::pool::SqlitePoolError;
use crate::databases::sqlite::pool::SqlitePoolManager;
impl SqliteDatabase {
pub async fn init_pool<F>(&self, pool: F) -> Result<SqlitePool, PoolInitError>
where
F: FnOnce() -> SqlitePool,
SqliteConnection:,
{
let pool = pool();
if let Some(migrator) = self.migrations.as_ref() {
let conn = &mut *pool.get().await.context(ConnectionSnafu)?;
futures::executor::block_on(async { migrator.run(conn).await })
.context(MigrationSnafu)?
}
Ok(pool)
}
pub async fn get_pool_or_init_with<F>(&self, pool: F) -> Result<&SqlitePool, PoolInitError>
where
F: FnOnce() -> SqlitePool,
{
self.pool.get_or_try_init(self.init_pool(pool)).await
}
pub async fn get_pool_or_init(&self) -> Result<&SqlitePool, PoolInitError> {
self.get_pool_or_init_with(move || {
SqlitePool::builder(SqlitePoolManager::new(self.connection_config.to_owned()))
.config(self.pool_config.to_owned().unwrap_or_default())
.build()
.expect("Couldn't build the sqlite pool")
})
.await
}
pub fn close_pool(&mut self) {
self.pool = OnceCell::new()
}
}
#[derive(Debug, Snafu)]
pub enum PoolInitError {
#[snafu(display("Could not get a connection from the database"))]
ConnectionError {
backtrace: Backtrace,
source: SqlitePoolError,
},
#[snafu(display("Could not apply the migrations"))]
MigrationError {
backtrace: Backtrace,
source: MigrateError,
},
}