use std::sync::Arc; use crate::{DatabaseConfig, db::DatabasePool}; #[cfg(feature = "sqlite")] use crate::{SqliteNoteRepository, SqliteTagRepository, SqliteUserRepository}; use notes_domain::{NoteRepository, TagRepository, UserRepository}; #[derive(Debug, thiserror::Error)] pub enum FactoryError { #[error("Database error: {0}")] Database(#[from] sqlx::Error), #[error("Not implemented: {0}")] NotImplemented(String), } pub type FactoryResult = Result; pub async fn build_database_pool(db_config: &DatabaseConfig) -> FactoryResult { if db_config.url.starts_with("sqlite:") { #[cfg(feature = "sqlite")] { let pool = sqlx::sqlite::SqlitePoolOptions::new() .max_connections(5) .connect(&db_config.url) .await?; Ok(DatabasePool::Sqlite(pool)) } #[cfg(not(feature = "sqlite"))] Err(FactoryError::NotImplemented( "SQLite feature not enabled".to_string(), )) } else if db_config.url.starts_with("postgres:") { #[cfg(feature = "postgres")] { let pool = sqlx::postgres::PgPoolOptions::new() .max_connections(5) .connect(&db_config.url) .await?; Ok(DatabasePool::Postgres(pool)) } #[cfg(not(feature = "postgres"))] Err(FactoryError::NotImplemented( "Postgres feature not enabled".to_string(), )) } else { Err(FactoryError::NotImplemented(format!( "Unsupported database URL scheme in: {}", db_config.url ))) } } pub async fn build_note_repository(pool: &DatabasePool) -> FactoryResult> { match pool { #[cfg(feature = "sqlite")] DatabasePool::Sqlite(pool) => Ok(Arc::new(SqliteNoteRepository::new(pool.clone()))), #[cfg(feature = "postgres")] DatabasePool::Postgres(_) => Err(FactoryError::NotImplemented( "Postgres NoteRepository".to_string(), )), #[allow(unreachable_patterns)] _ => Err(FactoryError::NotImplemented( "No database feature enabled".to_string(), )), } } pub async fn build_tag_repository(pool: &DatabasePool) -> FactoryResult> { match pool { #[cfg(feature = "sqlite")] DatabasePool::Sqlite(pool) => Ok(Arc::new(SqliteTagRepository::new(pool.clone()))), #[cfg(feature = "postgres")] DatabasePool::Postgres(_) => Err(FactoryError::NotImplemented( "Postgres TagRepository".to_string(), )), #[allow(unreachable_patterns)] _ => Err(FactoryError::NotImplemented( "No database feature enabled".to_string(), )), } } pub async fn build_user_repository(pool: &DatabasePool) -> FactoryResult> { match pool { #[cfg(feature = "sqlite")] DatabasePool::Sqlite(pool) => Ok(Arc::new(SqliteUserRepository::new(pool.clone()))), #[cfg(feature = "postgres")] DatabasePool::Postgres(_) => Err(FactoryError::NotImplemented( "Postgres UserRepository".to_string(), )), #[allow(unreachable_patterns)] _ => Err(FactoryError::NotImplemented( "No database feature enabled".to_string(), )), } } pub async fn build_session_store( pool: &DatabasePool, ) -> FactoryResult { match pool { #[cfg(feature = "sqlite")] DatabasePool::Sqlite(pool) => { let store = tower_sessions_sqlx_store::SqliteStore::new(pool.clone()); Ok(crate::session_store::InfraSessionStore::Sqlite(store)) } #[cfg(feature = "postgres")] DatabasePool::Postgres(pool) => { let store = tower_sessions_sqlx_store::PostgresStore::new(pool.clone()); Ok(crate::session_store::InfraSessionStore::Postgres(store)) } #[allow(unreachable_patterns)] _ => Err(FactoryError::NotImplemented( "No database feature enabled".to_string(), )), } }