A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.6 KiB

4 years ago
  1. use crate::command_runner::CommandRunner;
  2. use crate::storage::Storage;
  3. use crate::symbols::Symbol;
  4. use async_trait::async_trait;
  5. use std::error::Error;
  6. use std::str::FromStr;
  7. #[derive(Debug)]
  8. pub struct Dump<'a, N, C, S> {
  9. db_name: N,
  10. storage: S,
  11. command_runner: &'a C,
  12. }
  13. impl<'a, N, C: CommandRunner, S> Dump<'a, N, C, S> {
  14. pub fn new(db_name: N, storage: S, command_runner: &'a C) -> Self {
  15. Self {
  16. db_name,
  17. storage,
  18. command_runner,
  19. }
  20. }
  21. async fn run_sql(&self, sql: &str) -> Result<String, Box<dyn Error>> {
  22. let b = self
  23. .command_runner
  24. .get_output("mariadb", args!["--skip-column-names", "-B", "-e", sql])
  25. .await?;
  26. Ok(String::from_utf8(b)?)
  27. }
  28. }
  29. #[async_trait(?Send)]
  30. impl<N: AsRef<str>, C: CommandRunner, S: Storage> Symbol for Dump<'_, N, C, S> {
  31. async fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  32. let dump_date = self.storage.recent_date()?;
  33. 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?;
  34. let modified_date = output.trim_end();
  35. Ok(modified_date != "NULL" && u64::from_str(modified_date)? <= dump_date)
  36. }
  37. async fn execute(&self) -> Result<(), Box<dyn Error>> {
  38. self
  39. .command_runner
  40. .run_successfully(
  41. "sh",
  42. args![
  43. "-c",
  44. format!(
  45. "mysqldump '{}' > {}",
  46. self.db_name.as_ref(),
  47. self.storage.write_filename().to_str().unwrap()
  48. ),
  49. ],
  50. )
  51. .await
  52. }
  53. }
  54. #[cfg(test)]
  55. mod test {}