use std::{path::PathBuf, sync::Arc}; use async_trait::async_trait; use dagger_sdk::Container; use crate::dagger_middleware::DaggerMiddleware; use super::RustService; pub struct Sqlx { client: dagger_sdk::Query, migration_path: Option, } impl Sqlx { pub fn new(client: dagger_sdk::Query) -> Self { Self { client, migration_path: None, } } pub fn with_migration_path(mut self, migration_path: impl Into) -> Self { self.migration_path = Some(migration_path.into()); self } } #[async_trait] impl DaggerMiddleware for Sqlx { async fn handle(&self, container: Container) -> eyre::Result { let container = if std::path::PathBuf::from(".sqlx/").exists() { tracing::debug!("found .sqlx folder enabling offline mode"); let src = self.client.host().directory(".sqlx/"); container .with_directory(".sqlx", src) .with_env_variable("SQLX_OFFLINE", "true") } else { tracing::debug!("did not find a .sqlx folder, requires a running database"); container }; let container = if let Some(migration_path) = &self.migration_path { container .with_directory( "/mnt/sqlx/migrations", self.client .host() .directory(migration_path.display().to_string()), ) .with_env_variable("NEFARIOUS_DB_MIGRATION_PATH", "/mnt/sqlx/migrations") } else { container }; Ok(container) } } pub trait SqlxExt { fn with_sqlx(&mut self) -> &mut Self; fn with_sqlx_migrations(&mut self, path: impl Into) -> &mut Self; } impl SqlxExt for RustService { fn with_sqlx(&mut self) -> &mut Self { self.with_stage(super::RustServiceStage::BeforeBuild(Arc::new(Sqlx::new( self.client.clone(), )))) } fn with_sqlx_migrations(&mut self, path: impl Into) -> &mut Self { self.with_stage(super::RustServiceStage::BeforeBuild(Arc::new( Sqlx::new(self.client.clone()).with_migration_path(path), ))) } }