improvement: better imported index names

improvement: add `--extend` option, forwarded to generated resource
This commit is contained in:
Zach Daniel 2024-09-05 12:54:13 -04:00
parent 5395aba898
commit a9913a6999
3 changed files with 57 additions and 35 deletions

View file

@ -23,6 +23,7 @@ defmodule Mix.Tasks.AshPostgres.Gen.Resources do
- `tables`, `t` - Defaults to `public.*`. The tables to generate resources for, comma separated. Can be specified multiple times. See the section on tables for more.
- `skip-tables`, `s` - The tables to skip generating resources for, comma separated. Can be specified multiple times. See the section on tables for more.
- `snapshots-only` - Only generate snapshots for the generated resources, and not migraitons.
- `extend`, `e` - Extension or extensions to apply to the generated resources. See `mix ash.patch.extend` for more.
- `yes`, `y` - Answer yes (or skip) to all questions.
## Tables
@ -45,6 +46,7 @@ defmodule Mix.Tasks.AshPostgres.Gen.Resources do
yes: :boolean,
tables: :keep,
skip_tables: :keep,
extend: :keep,
snapshots_only: :boolean,
domain: :keep
],
@ -52,6 +54,7 @@ defmodule Mix.Tasks.AshPostgres.Gen.Resources do
t: :tables,
y: :boolean,
r: :repo,
e: :extend,
d: :domain,
s: :skip_tables
]

View file

@ -13,33 +13,7 @@ defmodule AshPostgres.ResourceGenerator do
igniter = Igniter.include_all_elixir_files(igniter)
opts =
if opts[:tables] do
Keyword.put(
opts,
:tables,
opts[:tables]
|> List.wrap()
|> Enum.join(",")
|> String.split(",")
)
else
opts
end
opts =
if opts[:skip_tables] do
Keyword.put(
opts,
:skip_tables,
opts[:skip_tables]
|> List.wrap()
|> Enum.join(",")
|> String.split(",")
)
else
opts
end
opts = handle_csv_opts(opts, [:tables, :skip_tables, :extend])
specs =
repos
@ -75,6 +49,23 @@ defmodule AshPostgres.ResourceGenerator do
end)
end
defp handle_csv_opts(opts, keys) do
Enum.reduce(keys, opts, fn key, opts ->
opts
|> Keyword.get_values(key)
|> case do
[] ->
opts
values ->
values
|> Enum.join(",")
|> String.split(",", trim: true)
|> then(&Keyword.put(opts, key, &1))
end
end)
end
defp table_to_resource(
igniter,
%AshPostgres.ResourceGenerator.Spec{} = table_spec,
@ -113,6 +104,15 @@ defmodule AshPostgres.ResourceGenerator do
igniter
|> Ash.Domain.Igniter.add_resource_reference(domain, table_spec.resource)
|> Igniter.Code.Module.create_module(table_spec.resource, resource)
|> then(fn igniter ->
if opts[:extend] do
Igniter.compose_task(igniter, "ash.patch.extend", [
table_spec.resource | opts[:extend] || []
])
else
igniter
end
end)
end
defp check_constraints(%{check_constraints: _check_constraints}, true) do
@ -138,7 +138,7 @@ defmodule AshPostgres.ResourceGenerator do
"""
end
defp skip_unique_indexes(%{indexes: indexes}) do
defp skip_unique_indexes(%{table_name: table_name, indexes: indexes}) do
indexes
|> Enum.filter(fn %{unique?: unique?, columns: columns} ->
unique? && Enum.all?(columns, &Regex.match?(~r/^[0-9a-zA-Z_]+$/, &1))
@ -150,12 +150,12 @@ defmodule AshPostgres.ResourceGenerator do
indexes ->
"""
skip_unique_indexes [#{Enum.map_join(indexes, ",", &":#{&1.name}")}]
skip_unique_indexes [#{Enum.map_join(indexes, ",", &":#{&1.identity_name}")}]
"""
end
end
defp identity_index_names(%{indexes: indexes}) do
defp identity_index_names(%{table_name: table_name, indexes: indexes}) do
indexes
|> Enum.filter(fn %{unique?: unique?, columns: columns} ->
unique? && Enum.all?(columns, &Regex.match?(~r/^[0-9a-zA-Z_]+$/, &1))
@ -167,19 +167,19 @@ defmodule AshPostgres.ResourceGenerator do
indexes ->
indexes
|> Enum.map_join(", ", fn index ->
"#{index.name}: \"#{index.name}\""
"#{index.identity_name}: \"#{index.name}\""
end)
|> then(&"identity_index_names [#{&1}]")
end
end
defp add_identities(str, %{indexes: indexes}) do
defp add_identities(str, %{table_name: table_name, indexes: indexes}) do
indexes
|> Enum.filter(fn %{unique?: unique?, columns: columns} ->
unique? && Enum.all?(columns, &Regex.match?(~r/^[0-9a-zA-Z_]+$/, &1))
end)
|> Enum.map(fn index ->
name = index.name
name = index.identity_name
fields = "[" <> Enum.map_join(index.columns, ", ", &":#{&1}") <> "]"

View file

@ -48,7 +48,16 @@ defmodule AshPostgres.ResourceGenerator.Spec do
defmodule Index do
@moduledoc false
defstruct [:name, :columns, :unique?, :nulls_distinct, :where_clause, :using, :include]
defstruct [
:name,
:columns,
:unique?,
:nulls_distinct,
:where_clause,
:using,
:include,
:identity_name
]
end
defmodule CheckConstraint do
@ -196,7 +205,8 @@ defmodule AshPostgres.ResourceGenerator.Spec do
contype = 'c'
AND conrelid::regclass::text = $1
""",
[spec.table_name]
[spec.table_name],
log: false
)
attribute = Enum.find(spec.attributes, & &1.primary_key?) || Enum.at(spec.attributes, 0)
@ -290,9 +300,18 @@ defmodule AshPostgres.ResourceGenerator.Spec do
nil
end
identity_name =
index_name
|> String.trim_leading(spec.table_name <> "_")
|> String.trim_leading("unique_")
|> String.replace("_unique_", "_")
|> String.trim_trailing("_index")
|> String.replace("_index_", "_")
[
%Index{
name: index_name,
identity_name: identity_name,
columns: Enum.uniq(columns),
unique?: is_unique,
include: include,