defmodule Aprsme.Repo.Migrations.RestorePacketGeometryIndex do
  use Ecto.Migration

  @disable_ddl_transaction true
  @disable_migration_lock true

  @parent_index "idx_packets_location"

  def up do
    if Aprsme.Repo.config()[:pool] == Ecto.Adapters.SQL.Sandbox do
      execute("""
      CREATE INDEX IF NOT EXISTS #{@parent_index}
      ON packets USING gist (location)
      WHERE has_position = true
      """)
    else
      execute("""
      CREATE INDEX IF NOT EXISTS #{@parent_index}
      ON ONLY packets USING gist (location)
      WHERE has_position = true
      """)

      Aprsme.Repo.query!("""
      SELECT inhrelid::regclass::text
      FROM pg_inherits
      WHERE inhparent = 'packets'::regclass
      """).rows
      |> List.flatten()
      |> Enum.each(&build_and_attach/1)
    end
  end

  def down do
    execute("DROP INDEX IF EXISTS #{@parent_index}")
  end

  defp build_and_attach(partition) do
    index_name =
      partition
      |> String.replace(~r/[^a-zA-Z0-9_]/, "_")
      |> Kernel.<>("_location_gist_idx")

    execute("""
    CREATE INDEX CONCURRENTLY IF NOT EXISTS #{index_name}
    ON #{partition} USING gist (location)
    WHERE has_position = true
    """)

    execute("ALTER INDEX #{@parent_index} ATTACH PARTITION #{index_name}")
  end
end
