db_migrate/commands/
reset.rs

1
2use crate::{migration::MigrationManager, CommandOutput};
3use anyhow::Result;
4use clap::Args;
5use colored::*;
6
7#[derive(Args)]
8pub struct ResetCommand {
9    /// Skip confirmation prompt
10    #[arg(long)]
11    yes: bool,
12}
13
14impl ResetCommand {
15    pub async fn execute(&self, manager: &mut MigrationManager) -> Result<CommandOutput> {
16        // Safety check - make sure destructive operations are allowed
17        if !manager.get_config().behavior.allow_destructive {
18            return Ok(CommandOutput::error(format!(
19                "{} Destructive operations are disabled in configuration. Set 'allow_destructive = true' in your config file to enable reset.",
20                "❌".red()
21            )));
22        }
23
24        // Get current state
25        let applied_migrations = manager.get_applied_migrations().await?;
26
27        if applied_migrations.is_empty() {
28            return Ok(CommandOutput::success(format!(
29                "{} No migrations to reset - migration table is already empty",
30                "✅".green()
31            )));
32        }
33
34        // Show what will be reset
35        let mut warning = vec![
36            format!("{} WARNING: This will permanently delete all migration records!", "⚠️ ".bright_red().bold()),
37            String::new(),
38            "The following migrations will be removed from the tracking table:".to_string(),
39        ];
40
41        for migration in &applied_migrations {
42            warning.push(format!(
43                "  • {} - {} (applied: {})",
44                migration.version.bright_cyan(),
45                migration.description,
46                crate::utils::format_timestamp(migration.applied_at).dimmed()
47            ));
48        }
49
50        warning.push(String::new());
51        warning.push(format!(
52            "{} This operation will NOT drop your actual database tables or data.",
53            "💡".bright_blue()
54        ));
55        warning.push("It only clears the migration tracking table.".dimmed().to_string());
56        warning.push(String::new());
57        warning.push(format!(
58            "Total migrations to reset: {}",
59            applied_migrations.len().to_string().bright_red().bold()
60        ));
61
62        if !self.yes {
63            warning.push(String::new());
64            warning.push(format!(
65                "{} Use --yes to confirm this destructive operation",
66                "🔒".yellow()
67            ));
68
69            return Ok(CommandOutput::success_with_data(
70                warning.join("\n"),
71                serde_json::json!({
72                    "action": "confirmation_required",
73                    "migrations_to_reset": applied_migrations.len(),
74                    "destructive": true,
75                    "confirmed": false
76                })
77            ));
78        }
79
80        // Perform the reset
81        match manager.reset_migrations().await {
82            Ok(_) => {
83                let success_message = vec![
84                    format!("{} Successfully reset all migrations!", "✅".green().bold()),
85                    String::new(),
86                    format!("• Removed {} migration record(s)", applied_migrations.len()),
87                    "• Migration tracking table has been recreated".to_string(),
88                    String::new(),
89                    format!(
90                        "{} You can now run 'db-migrate up' to reapply your migrations",
91                        "💡".bright_blue()
92                    ),
93                ];
94
95                Ok(CommandOutput::success_with_data(
96                    success_message.join("\n"),
97                    serde_json::json!({
98                        "action": "reset_completed",
99                        "migrations_reset": applied_migrations.len(),
100                        "destructive": true,
101                        "confirmed": true
102                    })
103                ))
104            }
105            Err(e) => {
106                Ok(CommandOutput::error(format!(
107                    "Failed to reset migrations: {}",
108                    e
109                )))
110            }
111        }
112    }
113}