package cli import ( "fmt" "os" "github.com/spf13/cobra" "sneak.berlin/go/vaultik/internal/config" "sneak.berlin/go/vaultik/internal/log" ) // NewDatabaseCommand creates the database command group func NewDatabaseCommand() *cobra.Command { cmd := &cobra.Command{ Use: "database", Short: "Manage the local state database", Long: `Commands for managing the local SQLite state database.`, } cmd.AddCommand( newDatabaseDeleteCommand(), ) return cmd } // newDatabaseDeleteCommand creates the database delete command. // (Renamed from "purge"; the operation removes the SQLite file // entirely, which is a delete, not a purge of content.) func newDatabaseDeleteCommand() *cobra.Command { var force bool cmd := &cobra.Command{ Use: "delete", Short: "Delete the local state database file", Long: `Completely removes the local SQLite state database. This will erase all local tracking of: - File metadata and change detection state - Chunk and blob mappings - Local snapshot records - The storage-binding record The remote storage is NOT affected. After deletion, the next backup will perform a full scan and re-deduplicate against existing remote blobs, and the local index will re-bind to the currently configured storage destination on that run. Use --force to skip the confirmation prompt.`, Args: cobra.NoArgs, RunE: func(_ *cobra.Command, _ []string) error { // Resolve config path configPath, err := ResolveConfigPath() if err != nil { return err } // Load config to get database path cfg, err := config.Load(configPath) if err != nil { return fmt.Errorf("failed to load config: %w", err) } dbPath := cfg.IndexPath // Check if database exists _, err = os.Stat(dbPath) if os.IsNotExist(err) { _, _ = fmt.Fprintf(os.Stdout, "Database does not exist: %s\n", dbPath) return nil } // Confirm unless --force if !force { _, _ = fmt.Fprintf(os.Stdout, "This will delete the local state database at:\n %s\n\n", dbPath) _, _ = fmt.Fprint(os.Stdout, "Are you sure? Type 'yes' to confirm: ") var confirm string _, err = fmt.Scanln(&confirm) if err != nil || confirm != "yes" { _, _ = fmt.Fprintln(os.Stdout, "Aborted.") //nolint:nilerr // a failed/aborted confirmation is a clean abort return nil } } // Delete the database file err = os.Remove(dbPath) if err != nil { return fmt.Errorf("failed to delete database: %w", err) } // Also delete WAL and SHM files if they exist walPath := dbPath + "-wal" shmPath := dbPath + "-shm" _ = os.Remove(walPath) // Ignore errors - files may not exist _ = os.Remove(shmPath) rootFlags := GetRootFlags() if !rootFlags.Quiet { _, _ = fmt.Fprintf(os.Stdout, "Database deleted: %s\n", dbPath) } log.Info("Local state database deleted", "path", dbPath) return nil }, } cmd.Flags().BoolVar(&force, "force", false, "Skip confirmation prompt") return cmd }