Current section
Files
Jump to
Current section
Files
lib/migration/indexable.ex
defmodule Needle.Migration.Indexable do
@moduledoc "Helpers for creating indexes on pointer fields in migrations."
import Ecto.Migration
import Needle.Migration
defmacro __using__(_opts \\ []) do
quote do
import Ecto.Migration
import Needle.Migration
import Needle.Migration.Indexable
@disable_ddl_transaction true
end
end
@doc """
Adds a pointer field and an index for it. Note: this uses `alter table` and can't be run in the same migration as the `create table` call for the same table.
## Example
create_pointer_with_index(:my_table, :thread_id, :strong, Needle.Pointer, unique: false)
"""
def create_pointer_with_index(table_name, field, type, ref_table \\ Pointer, opts \\ []) do
alter table(table_name) do
add_pointer_if_not_exists(field, type, ref_table, opts)
end
create_index_for_pointer(table_name, field, opts)
end
@doc """
Creates index for a pointer field on a table.
"""
def create_index_for_pointer(table_name, fields, opts \\ []) do
create_if_not_exists(index(table_name, List.wrap(fields), Keyword.put_new(opts, :concurrently, System.get_env("DB_MIGRATE_INDEXES_CONCURRENTLY") != "false")))
end
@doc """
Bulk-creates indexes for pointer fields on a table.
## Examples
create_indexes_for_pointers(:my_table, [:user_id, :thread_id])
create_indexes_for_pointers(:my_table, [user_id: [unique: true], thread_id: [unique: false]], [where: "deleted_at IS NULL"])
"""
def create_indexes_for_pointers(table_name, fields, opts \\ []) do
Enum.each(fields, fn
{field, field_opts} when is_list(field_opts) ->
create_index_for_pointer(table_name, field, Keyword.merge(opts, field_opts))
field ->
create_index_for_pointer(table_name, field, opts)
end)
end
end