Current section

Files

Jump to
kanta lib kanta migrations sqlite3.ex
Raw

lib/kanta/migrations/sqlite3.ex

defmodule Kanta.Migrations.SQLite3 do
@moduledoc false
@behaviour Kanta.Migration
use Ecto.Migration
@initial_version 1
@current_version 2
@doc false
def initial_version, do: @initial_version
@doc false
def current_version, do: @current_version
@impl Kanta.Migration
def up(opts) do
opts = with_defaults(opts, @current_version)
initial = migrated_version(opts)
cond do
initial == 0 ->
change(@initial_version..opts.version, :up, opts)
initial < opts.version ->
change((initial + 1)..opts.version, :up, opts)
true ->
:ok
end
end
@impl Kanta.Migration
def down(opts) do
opts = with_defaults(opts, @initial_version)
initial = max(migrated_version(opts), @initial_version)
if initial >= opts.version do
change(initial..opts.version, :down, opts)
end
end
@impl Kanta.Migration
def migrated_version(opts) do
opts = with_defaults(opts, @initial_version)
repo = Map.get_lazy(opts, :repo, fn -> repo() end)
query = "PRAGMA user_version"
case repo.query(query, [], log: false) do
{:ok, %{rows: [[version]]}} when is_integer(version) -> version
_ -> 0
end
end
defp change(range, direction, opts) do
for index <- range do
pad_idx = String.pad_leading(to_string(index), 2, "0")
[__MODULE__, "V#{pad_idx}"]
|> Module.concat()
|> apply(direction, [opts])
end
case direction do
:up -> record_version(opts, Enum.max(range))
:down -> record_version(opts, Enum.min(range) - 1)
end
end
defp record_version(_opts, 0), do: :ok
defp record_version(_opts, version) do
execute "PRAGMA user_version = #{version}"
end
defp with_defaults(opts, version) do
Enum.into(opts, %{version: version})
end
end