use std::time::Duration;
use sqlx::{
migrate::{MigrateDatabase, Migrator},
sqlite::{SqliteConnectOptions, SqlitePoolOptions},
SqlitePool,
};
use sqlx::ConnectOptions;
use crate::config::Config;
use super::Result;
static MIGRATOR: Migrator = sqlx::migrate!();
#[derive(Debug)]
pub struct DatabaseHandler {
conn: SqlitePool,
}
impl DatabaseHandler {
pub async fn with_config(config: &Config) -> Result<Self> {
let url = format!(
"sqlite:///{}",
config.database_path.to_str().unwrap_or_default()
);
Self::new(&url).await
}
pub async fn new(url: &str) -> Result<Self> {
if !sqlx::Sqlite::database_exists(url).await? {
sqlx::Sqlite::create_database(url).await?;
}
let mut opts: SqliteConnectOptions = url.parse()?;
opts = opts.log_statements(log::LevelFilter::Trace);
let conn = SqlitePoolOptions::new()
.max_connections(12)
.acquire_timeout(Duration::from_secs(5))
.connect_with(opts)
.await?;
MIGRATOR.run(&conn).await?;
Ok(Self { conn })
}
#[must_use]
pub fn conn(&self) -> &SqlitePool {
&self.conn
}
#[doc(hidden)]
#[must_use]
pub fn with_conn(conn: SqlitePool) -> Self {
Self { conn }
}
#[doc(hidden)]
#[must_use]
pub async fn in_memory() -> Self {
Self::new("sqlite://")
.await
.expect("create in memory for test")
}
}
#[cfg(test)]
mod test {
use super::*;
#[tokio::test]
async fn create_mem_db() {
let _ = DatabaseHandler::new("sqlite://").await.unwrap();
}
}