66 lines
1.8 KiB
Rust
66 lines
1.8 KiB
Rust
use crate::queries;
|
|
use sqlx::{AnyPool, any::AnyPoolOptions};
|
|
use tracing::{debug, info};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum DatabaseKind {
|
|
Sqlite,
|
|
Postgres,
|
|
MySql,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Database {
|
|
pool: AnyPool,
|
|
kind: DatabaseKind,
|
|
}
|
|
|
|
impl Database {
|
|
pub async fn connect(url: &str, max_connections: u32) -> Result<Self, sqlx::Error> {
|
|
sqlx::any::install_default_drivers();
|
|
let kind = DatabaseKind::from_url(url)?;
|
|
debug!(?kind, max_connections, "initializing database pool");
|
|
let pool = AnyPoolOptions::new()
|
|
.max_connections(max_connections)
|
|
.connect(url)
|
|
.await?;
|
|
if kind == DatabaseKind::Sqlite {
|
|
debug!("applying SQLite connection pragmas");
|
|
sqlx::query(queries::SQLITE_FOREIGN_KEYS_ON)
|
|
.execute(&pool)
|
|
.await?;
|
|
sqlx::query(queries::SQLITE_JOURNAL_WAL)
|
|
.execute(&pool)
|
|
.await?;
|
|
sqlx::query(queries::SQLITE_BUSY_TIMEOUT)
|
|
.execute(&pool)
|
|
.await?;
|
|
}
|
|
info!(?kind, max_connections, "database pool ready");
|
|
Ok(Self { pool, kind })
|
|
}
|
|
|
|
pub fn pool(&self) -> &AnyPool {
|
|
&self.pool
|
|
}
|
|
pub fn kind(&self) -> DatabaseKind {
|
|
self.kind
|
|
}
|
|
}
|
|
|
|
impl DatabaseKind {
|
|
fn from_url(url: &str) -> Result<Self, sqlx::Error> {
|
|
if url.starts_with("sqlite:") {
|
|
Ok(Self::Sqlite)
|
|
} else if url.starts_with("postgres:") || url.starts_with("postgresql:") {
|
|
Ok(Self::Postgres)
|
|
} else if url.starts_with("mysql:") {
|
|
Ok(Self::MySql)
|
|
} else {
|
|
Err(sqlx::Error::Configuration(
|
|
"DATABASE_URL must use sqlite://, postgres:// or mysql://".into(),
|
|
))
|
|
}
|
|
}
|
|
}
|