defmodule Ash.Resource.Transformers.CachePrimaryKey do
@moduledoc "Validates and caches the primary key of a resource"
use Spark.Dsl.Transformer
alias Spark.Dsl.Transformer
alias Spark.Error.DslError
def transform(dsl_state) do
primary_key_attribute =
dsl_state
|> Transformer.get_entities([:attributes])
|> Enum.filter(& &1.primary_key?)
pk_allows_nil? = Enum.any?(primary_key_attribute, & &1.allow_nil?)
simple_equality? = Enum.all?(primary_key_attribute, &Ash.Type.simple_equality?(&1.type))
primary_key =
if pk_allows_nil? == false do
Enum.map(primary_key_attribute, & &1.name)
else
:error_pk_allows_nil
end
case primary_key do
:error_pk_allows_nil ->
{:error, DslError.exception(message: "Primary keys must not be allowed to be nil")}
[] ->
{:error,
DslError.exception(message: "Resources without a primary key are not yet supported")}
[field] ->
dsl_state =
dsl_state
|> Transformer.persist(:primary_key, [field])
|> Transformer.persist(:primary_key_simple_equality?, simple_equality?)
{:ok, dsl_state}
fields ->
dsl_state =
dsl_state
|> Transformer.persist(:primary_key, fields)
|> Transformer.persist(:primary_key_simple_equality?, simple_equality?)
{:ok, dsl_state}
end
end
def after?(Ash.Resource.Transformers.BelongsToAttribute), do: true
def after?(Ash.Resource.Transformers.DefaultPrimaryKey), do: true
def after?(_), do: false
end