107 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Elixir
		
	
	
	
	
	
defmodule Mix.Tasks.Ecto.Drop do
 | 
						|
  use Mix.Task
 | 
						|
  import Mix.Ecto
 | 
						|
 | 
						|
  @shortdoc "Drops the repository storage"
 | 
						|
  @default_opts [force: false, force_drop: false]
 | 
						|
 | 
						|
  @aliases [
 | 
						|
    f: :force,
 | 
						|
    q: :quiet,
 | 
						|
    r: :repo
 | 
						|
  ]
 | 
						|
 | 
						|
  @switches [
 | 
						|
    force: :boolean,
 | 
						|
    force_drop: :boolean,
 | 
						|
    quiet: :boolean,
 | 
						|
    repo: [:keep, :string],
 | 
						|
    no_compile: :boolean,
 | 
						|
    no_deps_check: :boolean
 | 
						|
  ]
 | 
						|
 | 
						|
  @moduledoc """
 | 
						|
  Drop the storage for the given repository.
 | 
						|
 | 
						|
  The repositories to drop are the ones specified under the
 | 
						|
  `:ecto_repos` option in the current app configuration. However,
 | 
						|
  if the `-r` option is given, it replaces the `:ecto_repos` config.
 | 
						|
 | 
						|
  Since Ecto tasks can only be executed once, if you need to drop
 | 
						|
  multiple repositories, set `:ecto_repos` accordingly or pass the `-r`
 | 
						|
  flag multiple times.
 | 
						|
 | 
						|
  ## Examples
 | 
						|
 | 
						|
      $ mix ecto.drop
 | 
						|
      $ mix ecto.drop -r Custom.Repo
 | 
						|
 | 
						|
  ## Command line options
 | 
						|
 | 
						|
    * `-r`, `--repo` - the repo to drop
 | 
						|
    * `-q`, `--quiet` - run the command quietly
 | 
						|
    * `-f`, `--force` - do not ask for confirmation when dropping the database.
 | 
						|
      Configuration is asked only when `:start_permanent` is set to true
 | 
						|
      (typically in production)
 | 
						|
    * `--force-drop` - force the database to be dropped even
 | 
						|
      if it has connections to it (requires PostgreSQL 13+)
 | 
						|
    * `--no-compile` - do not compile before dropping
 | 
						|
    * `--no-deps-check` - do not compile before dropping
 | 
						|
 | 
						|
  """
 | 
						|
 | 
						|
  @impl true
 | 
						|
  def run(args) do
 | 
						|
    repos = parse_repo(args)
 | 
						|
    {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
 | 
						|
    opts = Keyword.merge(@default_opts, opts)
 | 
						|
 | 
						|
    Enum.each(repos, fn repo ->
 | 
						|
      ensure_repo(repo, args)
 | 
						|
 | 
						|
      ensure_implements(
 | 
						|
        repo.__adapter__(),
 | 
						|
        Ecto.Adapter.Storage,
 | 
						|
        "drop storage for #{inspect(repo)}"
 | 
						|
      )
 | 
						|
 | 
						|
      if skip_safety_warnings?() or
 | 
						|
           opts[:force] or
 | 
						|
           Mix.shell().yes?(
 | 
						|
             "Are you sure you want to drop the database for repo #{inspect(repo)}?"
 | 
						|
           ) do
 | 
						|
        drop_database(repo, opts)
 | 
						|
      end
 | 
						|
    end)
 | 
						|
  end
 | 
						|
 | 
						|
  defp skip_safety_warnings? do
 | 
						|
    Mix.Project.config()[:start_permanent] != true
 | 
						|
  end
 | 
						|
 | 
						|
  defp drop_database(repo, opts) do
 | 
						|
    config =
 | 
						|
      opts
 | 
						|
      |> Keyword.take([:force_drop])
 | 
						|
      |> Keyword.merge(repo.config())
 | 
						|
 | 
						|
    case repo.__adapter__().storage_down(config) do
 | 
						|
      :ok ->
 | 
						|
        unless opts[:quiet] do
 | 
						|
          Mix.shell().info("The database for #{inspect(repo)} has been dropped")
 | 
						|
        end
 | 
						|
 | 
						|
      {:error, :already_down} ->
 | 
						|
        unless opts[:quiet] do
 | 
						|
          Mix.shell().info("The database for #{inspect(repo)} has already been dropped")
 | 
						|
        end
 | 
						|
 | 
						|
      {:error, term} when is_binary(term) ->
 | 
						|
        Mix.raise("The database for #{inspect(repo)} couldn't be dropped: #{term}")
 | 
						|
 | 
						|
      {:error, term} ->
 | 
						|
        Mix.raise("The database for #{inspect(repo)} couldn't be dropped: #{inspect(term)}")
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |