use crate::command_runner::CommandRunner; use crate::storage::Storage; use crate::symbols::Symbol; use async_trait::async_trait; use std::error::Error; #[derive(Debug)] pub struct Database<'a, D, S, C> { db_name: D, seed_file: S, command_runner: &'a C, } impl<'a, D, S, C: CommandRunner> Database<'a, D, S, C> { pub fn new(db_name: D, seed_file: S, command_runner: &'a C) -> Self { Self { db_name, seed_file, command_runner, } } async fn run_sql(&self, sql: &str) -> Result> { let b = self .command_runner .get_output("mariadb", args!["--skip-column-names", "-B", "-e", sql]) .await?; Ok(String::from_utf8(b)?) } } #[async_trait(?Send)] impl, S: Storage, C: CommandRunner> Symbol for Database<'_, D, S, C> { async fn target_reached(&self) -> Result> { Ok( self .run_sql(&format!("SHOW DATABASES LIKE '{}'", self.db_name.as_ref())) .await? .trim_end() == self.db_name.as_ref(), ) } async fn execute(&self) -> Result<(), Box> { self .run_sql(&format!("CREATE DATABASE {}", self.db_name.as_ref())) .await?; self .command_runner .run_successfully( "sh", args![ "-c", format!( "mariadb '{}' < {}", self.db_name.as_ref(), self.seed_file.read_filename()?.to_str().unwrap() ), ], ) .await } } #[cfg(test)] mod test {}