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.

80 lines
2.1 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. use std::error::Error;
  2. use std::fmt;
  3. use std::str::FromStr;
  4. use command_runner::CommandRunner;
  5. use storage::Storage;
  6. use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
  7. pub struct DatabaseDump<'a, N, C, S>
  8. where
  9. N: 'a + AsRef<str>,
  10. C: 'a + CommandRunner,
  11. S: Storage,
  12. {
  13. db_name: N,
  14. storage: S,
  15. command_runner: &'a C,
  16. }
  17. impl<'a, N: AsRef<str>, C: CommandRunner, S: Storage> DatabaseDump<'a, N, C, S> {
  18. pub fn new(db_name: N, storage: S, command_runner: &'a C) -> Self {
  19. DatabaseDump {
  20. db_name,
  21. storage,
  22. command_runner,
  23. }
  24. }
  25. fn run_sql(&self, sql: &str) -> Result<String, Box<dyn Error>> {
  26. let b = self
  27. .command_runner
  28. .get_output("mariadb", &["--skip-column-names", "-B", "-e", sql])?;
  29. Ok(String::from_utf8(b)?)
  30. }
  31. }
  32. impl<'a, N: AsRef<str>, C: CommandRunner, S: Storage> fmt::Display for DatabaseDump<'a, N, C, S> {
  33. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  34. write!(f, "Dump MariaDB Database {}", self.db_name.as_ref())
  35. }
  36. }
  37. impl<'a, N: AsRef<str>, C: CommandRunner, S: Storage> Symbol for DatabaseDump<'a, N, C, S> {
  38. fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  39. let dump_date = self.storage.recent_date()?;
  40. let modified_date = try!(self.run_sql(&format!("select UNIX_TIMESTAMP(MAX(UPDATE_TIME)) from information_schema.tables WHERE table_schema = '{}'", self.db_name.as_ref())));
  41. if modified_date.trim_end() == "NULL" {
  42. return Ok(false);
  43. }
  44. Ok(u64::from_str(modified_date.trim_end())? <= dump_date)
  45. }
  46. fn execute(&self) -> Result<(), Box<dyn Error>> {
  47. self.command_runner.run_successfully(
  48. "sh",
  49. &[
  50. "-c",
  51. &format!(
  52. "mysqldump '{}' > {}",
  53. self.db_name.as_ref(),
  54. self.storage.write_filename()
  55. ),
  56. ],
  57. )
  58. }
  59. fn as_action<'b>(&'b self, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b> {
  60. Box::new(SymbolAction::new(runner, self))
  61. }
  62. fn into_action<'b>(self: Box<Self>, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b>
  63. where
  64. Self: 'b,
  65. {
  66. Box::new(OwnedSymbolAction::new(runner, *self))
  67. }
  68. }
  69. #[cfg(test)]
  70. mod test {}