use std::error::Error; use std::str::FromStr; use crate::command_runner::CommandRunner; use crate::storage::Storage; use crate::symbols::Symbol; #[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, } } fn run_sql(&self, sql: &str) -> Result> { let b = self .command_runner .get_output("mariadb", args!["--skip-column-names", "-B", "-e", sql])?; Ok(String::from_utf8(b)?) } } impl, C: CommandRunner, S: Storage> Symbol for Dump<'_, N, C, S> { fn target_reached(&self) -> Result> { let dump_date = self.storage.recent_date()?; let _modified_date = self.run_sql(&format!("select UNIX_TIMESTAMP(MAX(UPDATE_TIME)) from information_schema.tables WHERE table_schema = '{}'", self.db_name.as_ref()))?; let modified_date = _modified_date.trim_end(); Ok(modified_date != "NULL" && u64::from_str(modified_date)? <= dump_date) } 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() ), ], ) } } #[cfg(test)] mod test {}