Skip to content

Commit

Permalink
Add prefix option to check repo status plug (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevehodgkiss authored Oct 25, 2024
1 parent b44088a commit fe00d3d
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 17 deletions.
16 changes: 12 additions & 4 deletions lib/phoenix_ecto/check_repo_status.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ defmodule Phoenix.Ecto.CheckRepoStatus do
* `:otp_app` - name of the application which the repos are fetched from
* `:migration_paths` - a function that accepts a repo and returns a migration directory, or a list of migration directories, that is used to check for pending migrations
* `:migration_lock` - the locking strategy used by the Ecto Adapter when checking for pending migrations. Set to `false` to disable migration locks.
* `:prefix` - the prefix used to check for pending migrations.
"""

@behaviour Plug

alias Plug.Conn

@migration_opts [:migration_lock]
@migration_opts [:migration_lock, :prefix]
@compile {:no_warn_undefined, Ecto.Migrator}

def init(opts) do
Expand Down Expand Up @@ -60,16 +61,23 @@ defmodule Phoenix.Ecto.CheckRepoStatus do
end)

true = is_function(migrations_fun, 3)
migration_opts = Keyword.take(opts, @migration_opts)

try do
repo
|> migrations_fun.(dirs, Keyword.take(opts, @migration_opts))
|> migrations_fun.(dirs, migration_opts)
|> Enum.any?(fn {status, _version, _migration} -> status == :down end)
rescue
_ -> false
else
true -> raise Phoenix.Ecto.PendingMigrationError, repo: repo, directories: dirs
false -> true
true ->
raise Phoenix.Ecto.PendingMigrationError,
repo: repo,
directories: dirs,
migration_opts: migration_opts

false ->
true
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/phoenix_ecto/exceptions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ defmodule Phoenix.Ecto.StorageNotCreatedError do
end

defmodule Phoenix.Ecto.PendingMigrationError do
@enforce_keys [:repo, :directories]
defexception [:repo, :directories]
@enforce_keys [:repo, :directories, :migration_opts]
defexception [:repo, :directories, :migration_opts]

def message(%__MODULE__{repo: repo}) do
"there are pending migrations for repo: #{inspect(repo)}. " <>
Expand Down
8 changes: 5 additions & 3 deletions lib/phoenix_ecto/plug.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ unless Phoenix.Ecto.PendingMigrationError in excluded_exceptions do
defimpl Plug.Exception, for: Phoenix.Ecto.PendingMigrationError do
def status(_error), do: 503

def actions(%{repo: repo, directories: directories}),
def actions(%{repo: repo, directories: directories, migration_opts: migration_opts}),
do: [
%{
label: "Run migrations for repo",
handler: {__MODULE__, :migrate, [repo, directories]}
handler: {__MODULE__, :migrate, [repo, directories, migration_opts]}
}
]

def migrate(repo, directories), do: Ecto.Migrator.run(repo, directories, :up, all: true)
def migrate(repo, directories, migration_opts) do
Ecto.Migrator.run(repo, directories, :up, Keyword.merge(migration_opts || [], all: true))
end
end
end

Expand Down
49 changes: 41 additions & 8 deletions test/phoenix_ecto/check_repo_status_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,47 @@ defmodule Phoenix.Ecto.CheckRepoStatusTest do

conn = conn(:get, "/")

assert_raise(Phoenix.Ecto.PendingMigrationError, fn ->
CheckRepoStatus.call(
conn,
otp_app: :check_repo_ready,
mock_migrations_fn: mock_migrations_fn,
migration_lock: false
)
end)
exception =
assert_raise(Phoenix.Ecto.PendingMigrationError, fn ->
CheckRepoStatus.call(
conn,
otp_app: :check_repo_ready,
mock_migrations_fn: mock_migrations_fn,
migration_lock: false
)
end)

assert exception.migration_opts == [migration_lock: false]
after
Application.delete_env(:check_repo_ready, :ecto_repos)
Process.unregister(StorageUpRepo)
end

test "supports Ecto's prefix option" do
Process.register(self(), StorageUpRepo)
Application.put_env(:check_repo_ready, :ecto_repos, [StorageUpRepo])

mock_migrations_fn = fn _repo, _directories, opts ->
if opts[:prefix] == "tenant_1" do
[{:down, 1, "migration"}]
else
[]
end
end

conn = conn(:get, "/")

exception =
assert_raise(Phoenix.Ecto.PendingMigrationError, fn ->
CheckRepoStatus.call(
conn,
otp_app: :check_repo_ready,
mock_migrations_fn: mock_migrations_fn,
prefix: "tenant_1"
)
end)

assert exception.migration_opts == [prefix: "tenant_1"]
after
Application.delete_env(:check_repo_ready, :ecto_repos)
Process.unregister(StorageUpRepo)
Expand Down

0 comments on commit fe00d3d

Please sign in to comment.