use crate::cli::DbCommand;
use crate::error::{CommandError, DbCommandError};
pub(crate) fn execute(command: DbCommand) -> Result<(), CommandError> {
match command {
DbCommand::Migrate => super::migrate::run_migrate(),
DbCommand::Rollback { steps } => super::migrate::run_rollback(steps),
DbCommand::Status => super::status::run_status(),
DbCommand::Fresh { force } => {
if !force {
return Err(CommandError::Db(DbCommandError::DestructiveRequiresForce(
"fresh",
)));
}
super::migrate::run_fresh()
}
DbCommand::Reset { force } => {
if !force {
return Err(CommandError::Db(DbCommandError::DestructiveRequiresForce(
"reset",
)));
}
super::migrate::run_reset()
}
DbCommand::Refresh { force } => {
if !force {
return Err(CommandError::Db(DbCommandError::DestructiveRequiresForce(
"refresh",
)));
}
super::migrate::run_refresh()
}
DbCommand::Prepare => super::prepare::run_prepare(),
DbCommand::PrepareCheck => super::prepare::run_prepare_check(),
DbCommand::Lint { format } => super::lint::run_lint(format),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fresh_without_force_is_rejected() {
let result = execute(DbCommand::Fresh { force: false });
assert!(
matches!(
result,
Err(CommandError::Db(DbCommandError::DestructiveRequiresForce(
"fresh"
)))
),
"fresh without --force must be rejected"
);
}
#[test]
fn reset_without_force_is_rejected() {
let result = execute(DbCommand::Reset { force: false });
assert!(
matches!(
result,
Err(CommandError::Db(DbCommandError::DestructiveRequiresForce(
"reset"
)))
),
"reset without --force must be rejected"
);
}
#[test]
fn refresh_without_force_is_rejected() {
let result = execute(DbCommand::Refresh { force: false });
assert!(
matches!(
result,
Err(CommandError::Db(DbCommandError::DestructiveRequiresForce(
"refresh"
)))
),
"refresh without --force must be rejected"
);
}
#[test]
fn destructive_error_message_does_not_leak_credentials() {
let result = execute(DbCommand::Fresh { force: false });
let error = result.expect_err("should error");
let message = format!("{error}");
assert!(!message.contains("DATABASE_URL"));
assert!(!message.contains("password"));
assert!(!message.contains("postgres://"));
}
}