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
|