if Code.ensure_loaded?(Ecto.Migration) do
defmodule Needle.ULID.Migration do
import Ecto.Migration
# Based on answers to this SO thread, tweaked.
# https://stackoverflow.com/questions/49227572/function-minuuid-does-not-exist-in-postgresql
defp create_agg(op) do
"""
create or replace aggregate #{op}(uuid) (
sfunc = #{op}_uuid,
stype = uuid,
combinefunc = #{op}_uuid,
sortop = operator (<),
parallel = safe
)
"""
end
defp drop_agg(name), do: "drop aggregate if exists #{name}(uuid)"
@min_uuid """
create or replace function min_uuid(uuid, uuid)
returns uuid as $$
begin
if $1 is null then return $2; end if;
if $2 is null then return $1; end if;
if $2 > $1 then return $1; end if;
return $2;
end;
$$ LANGUAGE plpgsql
"""
@max_uuid """
create or replace function max_uuid(uuid, uuid)
returns uuid as $$
begin
if $1 is null then return $2; end if;
if $2 is null then return $1; end if;
if $1 > $2 then return $1; end if;
return $2;
end;
$$ LANGUAGE plpgsql
"""
defp drop_fun(name),
do: "drop function if exists #{name}(uuid, uuid) cascade"
defp min_uuid(), do: execute(@min_uuid, drop_fun("min_uuid"))
defp max_uuid(), do: execute(@max_uuid, drop_fun("max_uuid"))
defp min(), do: execute(create_agg("min"), drop_agg("min"))
defp max(), do: execute(create_agg("max"), drop_agg("max"))
defp functions() do
min_uuid()
max_uuid()
end
defp aggregates() do
min()
max()
end
def init_pointers_ulid_extra() do
init_pointers_ulid_extra(direction())
end
def init_pointers_ulid_extra(:up) do
functions()
aggregates()
end
def init_pointers_ulid_extra(:down) do
aggregates()
functions()
end
end
end