ecto.drop.ex (2871B)
1 defmodule Mix.Tasks.Ecto.Drop do 2 use Mix.Task 3 import Mix.Ecto 4 5 @shortdoc "Drops the repository storage" 6 @default_opts [force: false, force_drop: false] 7 8 @aliases [ 9 f: :force, 10 q: :quiet, 11 r: :repo 12 ] 13 14 @switches [ 15 force: :boolean, 16 force_drop: :boolean, 17 quiet: :boolean, 18 repo: [:keep, :string], 19 no_compile: :boolean, 20 no_deps_check: :boolean, 21 ] 22 23 @moduledoc """ 24 Drop the storage for the given repository. 25 26 The repositories to drop are the ones specified under the 27 `:ecto_repos` option in the current app configuration. However, 28 if the `-r` option is given, it replaces the `:ecto_repos` config. 29 30 Since Ecto tasks can only be executed once, if you need to drop 31 multiple repositories, set `:ecto_repos` accordingly or pass the `-r` 32 flag multiple times. 33 34 ## Examples 35 36 $ mix ecto.drop 37 $ mix ecto.drop -r Custom.Repo 38 39 ## Command line options 40 41 * `-r`, `--repo` - the repo to drop 42 * `-q`, `--quiet` - run the command quietly 43 * `-f`, `--force` - do not ask for confirmation when dropping the database. 44 Configuration is asked only when `:start_permanent` is set to true 45 (typically in production) 46 * `--force-drop` - force the database to be dropped even 47 if it has connections to it (requires PostgreSQL 13+) 48 * `--no-compile` - do not compile before dropping 49 * `--no-deps-check` - do not compile before dropping 50 51 """ 52 53 @impl true 54 def run(args) do 55 repos = parse_repo(args) 56 {opts, _} = OptionParser.parse! args, strict: @switches, aliases: @aliases 57 opts = Keyword.merge(@default_opts, opts) 58 59 Enum.each repos, fn repo -> 60 ensure_repo(repo, args) 61 ensure_implements(repo.__adapter__, Ecto.Adapter.Storage, 62 "drop storage for #{inspect repo}") 63 64 if skip_safety_warnings?() or 65 opts[:force] or 66 Mix.shell().yes?("Are you sure you want to drop the database for repo #{inspect repo}?") do 67 drop_database(repo, opts) 68 end 69 end 70 end 71 72 defp skip_safety_warnings? do 73 Mix.Project.config()[:start_permanent] != true 74 end 75 76 defp drop_database(repo, opts) do 77 config = 78 opts 79 |> Keyword.take([:force_drop]) 80 |> Keyword.merge(repo.config) 81 case repo.__adapter__.storage_down(config) do 82 :ok -> 83 unless opts[:quiet] do 84 Mix.shell().info "The database for #{inspect repo} has been dropped" 85 end 86 {:error, :already_down} -> 87 unless opts[:quiet] do 88 Mix.shell().info "The database for #{inspect repo} has already been dropped" 89 end 90 {:error, term} when is_binary(term) -> 91 Mix.raise "The database for #{inspect repo} couldn't be dropped: #{term}" 92 {:error, term} -> 93 Mix.raise "The database for #{inspect repo} couldn't be dropped: #{inspect term}" 94 end 95 end 96 end