1use crate::config::DatabaseConfig;
2use crate::pool::DbPool;
3use sea_orm::{ConnectOptions, Database};
4use tracing::info;
5
6pub async fn connect(config: &DatabaseConfig) -> Result<DbPool, modo::Error> {
11 let mut opts = ConnectOptions::new(&config.url);
12 opts.max_connections(config.max_connections)
13 .min_connections(config.min_connections);
14
15 let conn = Database::connect(opts)
16 .await
17 .map_err(|e| modo::Error::internal(format!("Database connection failed: {e}")))?;
18
19 if conn.get_database_backend() == sea_orm::DatabaseBackend::Sqlite {
21 apply_sqlite_pragmas(&conn).await?;
22 }
23
24 info!(url = %redact_url(&config.url), "Database connected");
25 Ok(DbPool(conn))
26}
27
28#[cfg(feature = "sqlite")]
29async fn apply_sqlite_pragmas(conn: &sea_orm::DatabaseConnection) -> Result<(), modo::Error> {
30 use sea_orm::ConnectionTrait;
31
32 conn.execute_unprepared("PRAGMA journal_mode=WAL")
33 .await
34 .map_err(|e| modo::Error::internal(format!("Failed to set WAL mode: {e}")))?;
35 conn.execute_unprepared("PRAGMA busy_timeout=5000")
36 .await
37 .map_err(|e| modo::Error::internal(format!("Failed to set busy_timeout: {e}")))?;
38 conn.execute_unprepared("PRAGMA synchronous=NORMAL")
39 .await
40 .map_err(|e| modo::Error::internal(format!("Failed to set synchronous: {e}")))?;
41 conn.execute_unprepared("PRAGMA foreign_keys=ON")
42 .await
43 .map_err(|e| modo::Error::internal(format!("Failed to enable foreign_keys: {e}")))?;
44 Ok(())
45}
46
47#[cfg(not(feature = "sqlite"))]
48async fn apply_sqlite_pragmas(_conn: &sea_orm::DatabaseConnection) -> Result<(), modo::Error> {
49 Err(modo::Error::internal(
50 "SQLite URL provided but `sqlite` feature is not enabled",
51 ))
52}
53
54fn redact_url(url: &str) -> String {
56 if let Some(scheme_end) = url.find("://") {
57 let authority_start = scheme_end + 3;
58 if let Some(relative_at) = url[authority_start..].find('@') {
59 let prefix = &url[..authority_start];
60 let suffix = &url[authority_start + relative_at..];
61 return format!("{prefix}***{suffix}");
62 }
63 }
64 url.to_string()
65}