mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 01:22:15 +03:00
Don't attempt to create a database if it already exists (#4498)
* don't attempt to create a database if already created * add tests --------- Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
This commit is contained in:
parent
d17ac82058
commit
c536af0df0
@ -141,10 +141,10 @@ defmodule Plausible.Release do
|
|||||||
IO.puts("Success!")
|
IO.puts("Success!")
|
||||||
end
|
end
|
||||||
|
|
||||||
def createdb do
|
def createdb(repos \\ repos()) do
|
||||||
prepare()
|
prepare()
|
||||||
|
|
||||||
for repo <- repos() do
|
for repo <- repos do
|
||||||
:ok = ensure_repo_created(repo)
|
:ok = ensure_repo_created(repo)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -225,12 +225,25 @@ defmodule Plausible.Release do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp ensure_repo_created(repo) do
|
defp ensure_repo_created(repo) do
|
||||||
IO.puts("create #{inspect(repo)} database if it doesn't exist")
|
config = repo.config()
|
||||||
|
adapter = repo.__adapter__()
|
||||||
|
|
||||||
case repo.__adapter__.storage_up(repo.config) do
|
case adapter.storage_status(config) do
|
||||||
:ok -> :ok
|
:up ->
|
||||||
{:error, :already_up} -> :ok
|
IO.puts("#{inspect(repo)} database already exists")
|
||||||
{:error, term} -> {:error, term}
|
:ok
|
||||||
|
|
||||||
|
:down ->
|
||||||
|
IO.puts("Creating #{inspect(repo)} database..")
|
||||||
|
|
||||||
|
case adapter.storage_up(config) do
|
||||||
|
:ok -> :ok
|
||||||
|
{:error, :already_up} -> :ok
|
||||||
|
{:error, _reason} = error -> error
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, _reason} = error ->
|
||||||
|
error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -46,38 +46,79 @@ defmodule Plausible.ReleaseTest do
|
|||||||
assert Application.get_env(:plausible, :ecto_repos) == [Plausible.Repo, Plausible.IngestRepo]
|
assert Application.get_env(:plausible, :ecto_repos) == [Plausible.Repo, Plausible.IngestRepo]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# this repo is used in place of Plausible.Repo
|
||||||
|
defmodule PostgreSQL do
|
||||||
|
use Ecto.Repo, otp_app: :plausible, adapter: Ecto.Adapters.Postgres
|
||||||
|
end
|
||||||
|
|
||||||
|
# this repo is used in place of Plausible.IngestRepo
|
||||||
|
defmodule ClickHouse do
|
||||||
|
use Ecto.Repo, otp_app: :plausible, adapter: Ecto.Adapters.ClickHouse
|
||||||
|
end
|
||||||
|
|
||||||
|
defp last_migration(repo) do
|
||||||
|
{:ok, {_status, version, name}, _started} =
|
||||||
|
Ecto.Migrator.with_repo(repo, fn repo ->
|
||||||
|
repo
|
||||||
|
|> Ecto.Migrator.migrations()
|
||||||
|
|> List.last()
|
||||||
|
end)
|
||||||
|
|
||||||
|
"#{version}_#{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp fake_migrate(repo, up_to_migration) do
|
||||||
|
{up_to_version, _name} = Integer.parse(up_to_migration)
|
||||||
|
|
||||||
|
insert_opts =
|
||||||
|
if repo == ClickHouse do
|
||||||
|
[types: [version: "Int64", inserted_at: "DateTime"]]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
Ecto.Migrator.with_repo(repo, fn repo ->
|
||||||
|
schema_versions =
|
||||||
|
Ecto.Migrator.migrations(repo)
|
||||||
|
|> Enum.filter(fn {status, version, _name} ->
|
||||||
|
status == :down and version <= up_to_version
|
||||||
|
end)
|
||||||
|
|> Enum.map(fn {_status, version, _name} ->
|
||||||
|
[version: version, inserted_at: NaiveDateTime.utc_now(:second)]
|
||||||
|
end)
|
||||||
|
|
||||||
|
repo.insert_all("schema_migrations", schema_versions, insert_opts)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp fake_repos(_context) do
|
||||||
|
pg_config =
|
||||||
|
Plausible.Repo.config()
|
||||||
|
|> Keyword.replace!(:database, "plausible_test_migrations")
|
||||||
|
# to see priv/repo/migrations from this fake pg repo
|
||||||
|
|> Keyword.put_new(:priv, "priv/repo")
|
||||||
|
|
||||||
|
ch_config =
|
||||||
|
Plausible.IngestRepo.config()
|
||||||
|
|> Keyword.replace!(:database, "plausible_test_migrations")
|
||||||
|
# to see priv/ingest_repo/migrations from this fake ch repo
|
||||||
|
|> Keyword.put_new(:priv, "priv/ingest_repo")
|
||||||
|
|
||||||
|
Application.put_env(:plausible, PostgreSQL, pg_config)
|
||||||
|
on_exit(fn -> Application.delete_env(:plausible, PostgreSQL) end)
|
||||||
|
|
||||||
|
Application.put_env(:plausible, ClickHouse, ch_config)
|
||||||
|
on_exit(fn -> Application.delete_env(:plausible, ClickHouse) end)
|
||||||
|
|
||||||
|
{:ok, repos: [PostgreSQL, ClickHouse]}
|
||||||
|
end
|
||||||
|
|
||||||
describe "pending_streaks/1" do
|
describe "pending_streaks/1" do
|
||||||
@describetag :migrations
|
@describetag :migrations
|
||||||
|
|
||||||
# this repo is used in place of Plausible.Repo
|
setup :fake_repos
|
||||||
defmodule PostgreSQL do
|
|
||||||
use Ecto.Repo, otp_app: :plausible, adapter: Ecto.Adapters.Postgres
|
|
||||||
end
|
|
||||||
|
|
||||||
# this repo is used in place of Plausible.IngestRepo
|
|
||||||
defmodule ClickHouse do
|
|
||||||
use Ecto.Repo, otp_app: :plausible, adapter: Ecto.Adapters.ClickHouse
|
|
||||||
end
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
pg_config =
|
|
||||||
Plausible.Repo.config()
|
|
||||||
|> Keyword.replace!(:database, "plausible_test_migrations")
|
|
||||||
# to see priv/repo/migrations from this fake pg repo
|
|
||||||
|> Keyword.put_new(:priv, "priv/repo")
|
|
||||||
|
|
||||||
ch_config =
|
|
||||||
Plausible.IngestRepo.config()
|
|
||||||
|> Keyword.replace!(:database, "plausible_test_migrations")
|
|
||||||
# to see priv/ingest_repo/migrations from this fake ch repo
|
|
||||||
|> Keyword.put_new(:priv, "priv/ingest_repo")
|
|
||||||
|
|
||||||
Application.put_env(:plausible, PostgreSQL, pg_config)
|
|
||||||
on_exit(fn -> Application.delete_env(:plausible, PostgreSQL) end)
|
|
||||||
|
|
||||||
Application.put_env(:plausible, ClickHouse, ch_config)
|
|
||||||
on_exit(fn -> Application.delete_env(:plausible, ClickHouse) end)
|
|
||||||
|
|
||||||
pg_config = PostgreSQL.config()
|
pg_config = PostgreSQL.config()
|
||||||
:ok = Ecto.Adapters.Postgres.storage_up(pg_config)
|
:ok = Ecto.Adapters.Postgres.storage_up(pg_config)
|
||||||
on_exit(fn -> :ok = Ecto.Adapters.Postgres.storage_down(pg_config) end)
|
on_exit(fn -> :ok = Ecto.Adapters.Postgres.storage_down(pg_config) end)
|
||||||
@ -89,41 +130,6 @@ defmodule Plausible.ReleaseTest do
|
|||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
defp last_migration(repo) do
|
|
||||||
{:ok, {_status, version, name}, _started} =
|
|
||||||
Ecto.Migrator.with_repo(repo, fn repo ->
|
|
||||||
repo
|
|
||||||
|> Ecto.Migrator.migrations()
|
|
||||||
|> List.last()
|
|
||||||
end)
|
|
||||||
|
|
||||||
"#{version}_#{name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
defp fake_migrate(repo, up_to_migration) do
|
|
||||||
{up_to_version, _name} = Integer.parse(up_to_migration)
|
|
||||||
|
|
||||||
insert_opts =
|
|
||||||
if repo == ClickHouse do
|
|
||||||
[types: [version: "Int64", inserted_at: "DateTime"]]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
|
|
||||||
Ecto.Migrator.with_repo(repo, fn repo ->
|
|
||||||
schema_versions =
|
|
||||||
Ecto.Migrator.migrations(repo)
|
|
||||||
|> Enum.filter(fn {status, version, _name} ->
|
|
||||||
status == :down and version <= up_to_version
|
|
||||||
end)
|
|
||||||
|> Enum.map(fn {_status, version, _name} ->
|
|
||||||
[version: version, inserted_at: NaiveDateTime.utc_now(:second)]
|
|
||||||
end)
|
|
||||||
|
|
||||||
repo.insert_all("schema_migrations", schema_versions, insert_opts)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "v2.0.0 -> master" do
|
test "v2.0.0 -> master" do
|
||||||
# pretend to migrate the repos up to v2.0.0
|
# pretend to migrate the repos up to v2.0.0
|
||||||
# https://github.com/plausible/analytics/tree/v2.0.0/priv/repo/migrations
|
# https://github.com/plausible/analytics/tree/v2.0.0/priv/repo/migrations
|
||||||
@ -246,4 +252,40 @@ defmodule Plausible.ReleaseTest do
|
|||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "createdb/1" do
|
||||||
|
@describetag :migrations
|
||||||
|
|
||||||
|
setup :fake_repos
|
||||||
|
|
||||||
|
setup %{repos: repos} do
|
||||||
|
on_exit(fn ->
|
||||||
|
Enum.each(repos, fn repo -> :ok = repo.__adapter__().storage_down(repo.config()) end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "does not create the database if it already exists", %{repos: repos} do
|
||||||
|
first_run = capture_io(fn -> Release.createdb(repos) end)
|
||||||
|
|
||||||
|
assert first_run == """
|
||||||
|
Loading plausible..
|
||||||
|
Starting dependencies..
|
||||||
|
Starting repos..
|
||||||
|
Creating Plausible.ReleaseTest.PostgreSQL database..
|
||||||
|
Creating Plausible.ReleaseTest.ClickHouse database..
|
||||||
|
Creation of Db successful!
|
||||||
|
"""
|
||||||
|
|
||||||
|
second_run = capture_io(fn -> Release.createdb(repos) end)
|
||||||
|
|
||||||
|
assert second_run == """
|
||||||
|
Loading plausible..
|
||||||
|
Starting dependencies..
|
||||||
|
Starting repos..
|
||||||
|
Plausible.ReleaseTest.PostgreSQL database already exists
|
||||||
|
Plausible.ReleaseTest.ClickHouse database already exists
|
||||||
|
Creation of Db successful!
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user