Packages

Build multitenant applications on top of Ecto.

Current section

Files

Jump to
tenant lib mix tasks tenant.migrations.ex
Raw

lib/mix/tasks/tenant.migrations.ex

defmodule Mix.Tasks.Tenant.Migrations do
use Mix.Task
alias Ecto.Migrator
alias Mix.Ecto
alias Mix.Tenant, as: MTenant
alias Tenant
@shortdoc "Displays the repository migration status"
@recursive true
@moduledoc """
Displays the up / down migration status for the given repository.
The repository must be set under `:ecto_repos` in the
current app configuration or given via the `-r` option.
By default, migrations are expected at "priv/YOUR_REPO/migrations"
directory of the current application but it can be configured
by specifying the `:priv` key under the repository configuration.
If the repository has not been started yet, one will be
started outside our application supervision tree and shutdown
afterwards.
## Examples
mix tenant.migrations
mix tenant.migrations -r Custom.Repo
## Command line options
* `-r`, `--repo` - the repo to obtain the status for
"""
@doc false
def run(args, migrations \\ &Migrator.migrations/2, puts \\ &IO.puts/1) do
repos = Ecto.parse_repo(args)
result =
Enum.map(repos, fn repo ->
Ecto.ensure_repo(repo, args)
MTenant.ensure_tenant_migrations_path(repo)
{:ok, _pid, _} = MTenant.ensure_started(repo, all: true)
migration_lists = migrations.(repo, Tenant.migrations_path(repo))
tenants_state = tenants_state(repo, migration_lists)
repo.stop()
tenants_state
end)
puts.(Enum.join(result, "\n"))
end
defp tenants_state(repo, migration_lists) do
Enum.map_join(Tenant.all(repo), fn tenant ->
tenant_versions = Migrator.migrated_versions(repo, prefix: Tenant.to_prefix(tenant))
repo_status = repo_status(migration_lists, tenant_versions)
"""
Repo: #{inspect(repo)}
Tenant: #{tenant}
Status Migration ID Migration Name
--------------------------------------------------
#{migrations_table(repo_status)}
"""
end)
end
defp repo_status(migration_lists, tenant_versions) do
Enum.map(migration_lists, fn
{_, ts, desc} ->
if Enum.member?(tenant_versions, ts) do
{:up, ts, desc}
else
{:down, ts, desc}
end
end)
end
defp migrations_table(repo_status) do
Enum.map_join(repo_status, "\n", fn {status, number, description} ->
status =
case status do
:up -> "up "
:down -> "down"
end
" #{status} #{number} #{description}"
end)
end
end