feat: finish postgres cli

Implemented basic wanted functionality for postgres subcommands. We
currently assume that postgres is running in docker-compose project in a
service named "postgresdb". This could be looked at and changed at some
point in the future.
This commit is contained in:
Matej Janezic 2023-05-23 23:40:29 +02:00
parent 7b64d6192a
commit a625d5f43c
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
2 changed files with 76 additions and 9 deletions

View File

@ -7,7 +7,7 @@ use std::{
ffi::OsStr, ffi::OsStr,
fs::{File, OpenOptions}, fs::{File, OpenOptions},
path::PathBuf, path::PathBuf,
process::Command, process::{Command, Stdio},
}; };
use anyhow::{Context, Result}; use anyhow::{Context, Result};
@ -47,6 +47,12 @@ impl DockerCommand {
self.command.spawn()?.wait()?; self.command.spawn()?.wait()?;
Ok(()) Ok(())
} }
fn write_stdout(mut self, stdio: Stdio) -> Result<()> {
self.command.stdout(stdio);
self.spawn_wait()?;
Ok(())
}
} }
fn safe_create_file(path: PathBuf) -> Result<File, std::io::Error> { fn safe_create_file(path: PathBuf) -> Result<File, std::io::Error> {

View File

@ -1,12 +1,73 @@
use anyhow::Result; use super::{docker_compose, DockerCommand};
use std::path::PathBuf;
pub fn import(path: &PathBuf) -> Result<()> { use anyhow::{Context, Result};
println!("{path:?}"); use std::{
todo!() fs::File,
path::{Path, PathBuf},
process::Stdio,
};
fn get_containers() -> Result<[String; 2]> {
// get db container
// FIX: we assume we are running db in service named "postgresbd"
let db_container = DockerCommand::docker_compose()
.args("ps -q postgresdb")
.stdout()?
.trim()
.to_string();
// get all containers and filter out db container
let app_containers = DockerCommand::docker_compose()
.args("ps -q")
.stdout()?
.split_whitespace()
.filter(|x| x != &db_container)
.collect::<Vec<&str>>()
.join(" ");
Ok([db_container, app_containers])
} }
pub fn dump(path: &PathBuf) -> Result<()> { pub fn import(file: &Path) -> Result<()> {
println!("{path:?}"); let [db_container, app_containers] = get_containers()?;
todo!() let dump_file = file.to_string_lossy();
println!("stopping all containers");
docker_compose::stop()?;
println!("starting db container");
docker_compose::start(Some(&db_container))?;
println!("restoring database");
let commands = [
format!("cp {dump_file} {db_container}:/tmp/dbdump"),
format!("exec {db_container} dropdb -U db db"),
format!("exec {db_container} createdb -U db -E utf8 -T template0 db"),
format!("exec {db_container} pg_restore -U db --dbname=db /tmp/dbdump"),
];
for command in commands {
DockerCommand::docker().args(&command).spawn_wait()?;
}
println!("restarting containers");
docker_compose::stop()?;
docker_compose::up()?;
Ok(())
}
pub fn dump(file: &PathBuf) -> Result<()> {
let [db_container, _] = get_containers()?;
println!("dumping to local file {}", file.to_string_lossy());
let file = File::create(file)?;
let stdout = Stdio::from(file);
let command = format!("exec {db_container} pg_dump -U db --format=c db");
DockerCommand::docker()
.args(&command)
.write_stdout(stdout)?;
Ok(())
} }