use crate::command_runner::CommandRunner; use crate::storage::Storage; use crate::symbols::Symbol; use async_trait::async_trait; use std::error::Error; use std::str::FromStr; #[derive(Debug)] pub struct Dump<'a, N, C, S> { db_name: N, storage: S, command_runner: &'a C, } impl<'a, N, C: CommandRunner, S> Dump<'a, N, C, S> { pub fn new(db_name: N, storage: S, command_runner: &'a C) -> Self { Self { db_name, storage, 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, C: CommandRunner, S: Storage> Symbol for Dump<'_, N, C, S> { async fn target_reached(&self) -> Result> { let dump_date = self.storage.recent_date()?; let output = self.run_sql(&format!("select UNIX_TIMESTAMP(MAX(UPDATE_TIME)) from information_schema.tables WHERE table_schema = '{}'", self.db_name.as_ref())).await?; let modified_date = output.trim_end(); Ok(modified_date != "NULL" && u64::from_str(modified_date)? <= dump_date) } async fn execute(&self) -> Result<(), Box> { self .command_runner .run_successfully( "sh", args![ "-c", format!( "mysqldump '{}' > {}", self.db_name.as_ref(), self.storage.write_filename().to_str().unwrap() ), ], ) .await } } #[cfg(test)] mod test {}