use crate::command_runner::CommandRunner; use crate::symbols::Symbol; use std::error::Error; use std::fmt; pub struct PostgreSQLDatabase<'a, N: AsRef, S: AsRef, C: CommandRunner> { name: N, seed_file: S, command_runner: &'a C, } impl<'a, N: AsRef, S: AsRef, C: CommandRunner> PostgreSQLDatabase<'a, N, S, C> { pub fn new(name: N, seed_file: S, command_runner: &'a C) -> Self { PostgreSQLDatabase { name, seed_file, command_runner, } } fn run_sql(&self, sql: &str) -> Result> { let b = self.command_runner.get_output( "su", args!["-", "postgres", "-c", format!("psql -t -c \"{}\"", sql)], )?; Ok(String::from_utf8(b)?) } } impl, S: AsRef, C: CommandRunner> fmt::Display for PostgreSQLDatabase<'_, N, S, C> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "PostgreSQL Database {}", self.name.as_ref()) } } impl, S: AsRef, C: CommandRunner> Symbol for PostgreSQLDatabase<'_, N, S, C> { fn target_reached(&self) -> Result> { Ok( self .run_sql(&format!( "SELECT datname FROM pg_database WHERE datname LIKE '{}'", self.name.as_ref() ))? .trim() == self.name.as_ref(), ) } fn execute(&self) -> Result<(), Box> { self.command_runner.run_successfully( "su", args![ "-", "postgres", "-c", format!("createuser {}", self.name.as_ref()) ], )?; self.command_runner.run_successfully( "su", args![ "-", "postgres", "-c", format!( "createdb -E UTF8 -T template0 -O {} {0}", self.name.as_ref() ), ], )?; self.command_runner.run_successfully( "su", args![ "-", "postgres", "-c", format!( "psql '{}' < {}", self.name.as_ref(), self.seed_file.as_ref() ), ], ) } } #[cfg(test)] mod test {}