improvement: storage_type/0 -> storage_type/1

This commit is contained in:
Zach Daniel 2023-08-17 17:51:44 -04:00
parent 025f75a1aa
commit b51dbe49c9
30 changed files with 58 additions and 41 deletions

View file

@ -119,7 +119,7 @@ defmodule Ash.Actions.Sort do
!Ash.DataLayer.data_layer_can?( !Ash.DataLayer.data_layer_can?(
resource, resource,
{:sort, Ash.Type.storage_type(attribute.type)} {:sort, Ash.Type.storage_type(attribute.type, attribute.constraints)}
) -> ) ->
{sorts, {sorts,
[ [
@ -191,7 +191,8 @@ defmodule Ash.Actions.Sort do
if Ash.DataLayer.data_layer_can?(resource, :aggregate_sort) && if Ash.DataLayer.data_layer_can?(resource, :aggregate_sort) &&
Ash.DataLayer.data_layer_can?( Ash.DataLayer.data_layer_can?(
resource, resource,
{:sort, Ash.Type.storage_type(type)} # do we need to get actual constraints for aggregates here?
{:sort, Ash.Type.storage_type(type, [])}
) do ) do
{sorts ++ [{field, order}], errors} {sorts ++ [{field, order}], errors}
else else

View file

@ -145,7 +145,7 @@ defmodule Ash.EmbeddableType do
quote location: :keep do quote location: :keep do
alias Ash.EmbeddableType.ShadowApi alias Ash.EmbeddableType.ShadowApi
def storage_type, do: :map def storage_type(_), do: :map
def cast_input(%{__struct__: __MODULE__} = input, _constraints), do: {:ok, input} def cast_input(%{__struct__: __MODULE__} = input, _constraints), do: {:ok, input}

View file

@ -88,7 +88,7 @@ defmodule Ash.Resource do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :map def storage_type(_), do: :map
@impl Ash.Type @impl Ash.Type
def cast_input(nil, _), do: {:ok, nil} def cast_input(nil, _), do: {:ok, nil}

View file

@ -58,7 +58,7 @@ defmodule Ash.Resource.Verifiers.ValidateRelationshipAttributesMatch do
Types are considered compatible if: Types are considered compatible if:
1. They are exactly the same 1. They are exactly the same
2. Their `storage_type/0` callback returns the same value 2. Their `storage_type/1` callback returns the same value
3. The storage types are `:text` and `:string` 3. The storage types are `:text` and `:string`
4. The relationship has `validate_destination_attribute?` set to `false`. 4. The relationship has `validate_destination_attribute?` set to `false`.
5. They are explicitly configured as compatible. To do so in this instance, add it to your config like so: 5. They are explicitly configured as compatible. To do so in this instance, add it to your config like so:
@ -71,9 +71,12 @@ defmodule Ash.Resource.Verifiers.ValidateRelationshipAttributesMatch do
""" """
end end
defp compatible_types?(%{type: source}, %{type: dest}) do defp compatible_types?(%{type: source, constraints: source_constraints}, %{
left_storage_type = Ash.Type.storage_type(source) type: dest,
right_storage_type = Ash.Type.storage_type(dest) constraints: dest_constraints
}) do
left_storage_type = Ash.Type.storage_type(source, source_constraints)
right_storage_type = Ash.Type.storage_type(dest, dest_constraints)
cond do cond do
source == dest -> source == dest ->

View file

@ -17,7 +17,7 @@ defmodule Ash.Type.Atom do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :string def storage_type(_), do: :string
@impl true @impl true
def constraints, do: @constraints def constraints, do: @constraints

View file

@ -8,7 +8,7 @@ defmodule Ash.Type.Binary do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :binary def storage_type(_), do: :binary
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -7,7 +7,7 @@ defmodule Ash.Type.Boolean do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :boolean def storage_type(_), do: :boolean
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -51,7 +51,7 @@ defmodule Ash.Type.CiString do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :string def storage_type(_), do: :string
@impl true @impl true
def constraints, do: @constraints def constraints, do: @constraints

View file

@ -7,7 +7,7 @@ defmodule Ash.Type.Date do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :date def storage_type(_), do: :date
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -58,7 +58,7 @@ defmodule Ash.Type.Decimal do
end end
@impl true @impl true
def storage_type, do: :decimal def storage_type(_), do: :decimal
@impl true @impl true
def constraints, do: @constraints def constraints, do: @constraints

View file

@ -46,7 +46,7 @@ defmodule Ash.Type.Enum do
def values, do: @values def values, do: @values
@impl Ash.Type @impl Ash.Type
def storage_type, do: :string def storage_type(_), do: :string
@impl Ash.Type @impl Ash.Type
def generator(_constraints) do def generator(_constraints) do
@ -120,7 +120,7 @@ defmodule Ash.Type.Enum do
:error :error
end end
defoverridable storage_type: 0 defoverridable storage_type: 1
end end
end end
end end

View file

@ -22,7 +22,7 @@ defmodule Ash.Type.Float do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :float def storage_type(_), do: :float
@impl true @impl true
def generator(constraints) do def generator(constraints) do

View file

@ -19,7 +19,7 @@ defmodule Ash.Type.Function do
] ]
@impl true @impl true
def storage_type, do: :binary def storage_type(_), do: :binary
@impl true @impl true
def constraints, do: @constraints def constraints, do: @constraints

View file

@ -21,7 +21,7 @@ defmodule Ash.Type.Integer do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :integer def storage_type(_), do: :integer
@impl true @impl true
def generator(constraints) do def generator(constraints) do

View file

@ -67,7 +67,7 @@ defmodule Ash.Type.Keyword do
def constraints, do: @constraints def constraints, do: @constraints
@impl true @impl true
def storage_type, do: :map def storage_type(_), do: :map
@impl true @impl true
def cast_input("", _), do: {:ok, nil} def cast_input("", _), do: {:ok, nil}

View file

@ -68,7 +68,7 @@ defmodule Ash.Type.Map do
def constraints, do: @constraints def constraints, do: @constraints
@impl true @impl true
def storage_type, do: :map def storage_type(_), do: :map
@impl true @impl true
def cast_input("", _), do: {:ok, nil} def cast_input("", _), do: {:ok, nil}

View file

@ -22,7 +22,7 @@ defmodule Ash.Type.Module do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :string def storage_type(_), do: :string
@impl true @impl true
def constraints, do: @constraints def constraints, do: @constraints

View file

@ -7,7 +7,7 @@ defmodule Ash.Type.NaiveDatetime do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :naive_datetime def storage_type(_), do: :naive_datetime
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -256,8 +256,8 @@ defmodule Ash.Type.NewType do
end end
@impl Ash.Type @impl Ash.Type
def storage_type do def storage_type(constraints) do
unquote(subtype_of).storage_type() unquote(subtype_of).storage_type(constraints)
end end
@impl Ash.Type @impl Ash.Type

View file

@ -39,7 +39,7 @@ defmodule Ash.Type.String do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :string def storage_type(_), do: :string
@impl true @impl true
def constraints, do: @constraints def constraints, do: @constraints

View file

@ -19,7 +19,7 @@ defmodule Ash.Type.Struct do
def constraints, do: @constraints def constraints, do: @constraints
@impl true @impl true
def storage_type, do: :map def storage_type(_), do: :map
@impl true @impl true
def cast_input(nil, _), do: {:ok, nil} def cast_input(nil, _), do: {:ok, nil}

View file

@ -7,7 +7,7 @@ defmodule Ash.Type.Term do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :binary def storage_type(_), do: :binary
@impl true @impl true
def cast_input(value, _), do: {:ok, value} def cast_input(value, _), do: {:ok, value}

View file

@ -7,7 +7,7 @@ defmodule Ash.Type.Time do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :time def storage_type(_), do: :time
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -97,7 +97,7 @@ defmodule Ash.Type do
use Ash.Type use Ash.Type
@impl Ash.Type @impl Ash.Type
def storage_type, do: :float def storage_type(_), do: :float
@impl Ash.Type @impl Ash.Type
def cast_input(value, _) do def cast_input(value, _) do
@ -147,7 +147,7 @@ defmodule Ash.Type do
authorize?: boolean | nil authorize?: boolean | nil
} }
@callback storage_type() :: Ecto.Type.t() @callback storage_type(constraints) :: Ecto.Type.t()
@doc """ @doc """
Useful for typed data layers (like ash_postgres) to instruct them not to attempt to cast input values. Useful for typed data layers (like ash_postgres) to instruct them not to attempt to cast input values.
@ -354,8 +354,9 @@ defmodule Ash.Type do
Returns the *underlying* storage type (the underlying type of the *ecto type* of the *ash type*) Returns the *underlying* storage type (the underlying type of the *ecto type* of the *ash type*)
""" """
@spec storage_type(t()) :: Ecto.Type.t() @spec storage_type(t()) :: Ecto.Type.t()
def storage_type({:array, type}), do: {:array, type.storage_type()} def storage_type(type, constraints \\ [])
def storage_type(type), do: type.storage_type() def storage_type({:array, type}, constraints), do: {:array, storage_type(type, constraints)}
def storage_type(type, constraints), do: type.storage_type(constraints)
@doc """ @doc """
Returns the ecto compatible type for an Ash.Type. Returns the ecto compatible type for an Ash.Type.
@ -919,8 +920,8 @@ defmodule Ash.Type do
end end
@impl true @impl true
def type(_) do def type(constraints) do
@parent.storage_type() @parent.storage_type(constraints)
end end
@impl true @impl true
@ -1104,6 +1105,18 @@ defmodule Ash.Type do
def equal?(left, right), do: left == right def equal?(left, right), do: left == right
end end
cond do
Module.defines?(__MODULE__, {:storage_type, 0}) &&
Module.defines?(__MODULE__, {:storage_type, 1}) ->
raise "Must only define storage_type/0 or storage_type/1 but not both"
Module.defines?(__MODULE__, {:storage_type, 0}) ->
def storage_type(_constraints), do: storage_type()
true ->
:ok
end
unless Module.defines?(__MODULE__, {:can_load?, 1}, :def) do unless Module.defines?(__MODULE__, {:can_load?, 1}, :def) do
@impl Ash.Type @impl Ash.Type
if Module.defines?(__MODULE__, {:load, 4}, :def) do if Module.defines?(__MODULE__, {:load, 4}, :def) do

View file

@ -109,7 +109,7 @@ defmodule Ash.Type.Union do
## Find the minimal supported type? ## Find the minimal supported type?
@impl true @impl true
def storage_type, do: :map def storage_type(_), do: :map
@impl true @impl true
def load(unions, load, constraints, context) do def load(unions, load, constraints, context) do

View file

@ -8,7 +8,7 @@ defmodule Ash.Type.UrlEncodedBinary do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :binary def storage_type(_), do: :binary
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -9,7 +9,7 @@ defmodule Ash.Type.UtcDatetime do
@beginning_of_day Time.new!(0, 0, 0) @beginning_of_day Time.new!(0, 0, 0)
@impl true @impl true
def storage_type, do: :utc_datetime def storage_type(_), do: :utc_datetime
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -9,7 +9,7 @@ defmodule Ash.Type.UtcDatetimeUsec do
@beginning_of_day Time.new!(0, 0, 0) @beginning_of_day Time.new!(0, 0, 0)
@impl true @impl true
def storage_type, do: :utc_datetime_usec def storage_type(_), do: :utc_datetime_usec
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -8,7 +8,7 @@ defmodule Ash.Type.UUID do
use Ash.Type use Ash.Type
@impl true @impl true
def storage_type, do: :uuid def storage_type(_), do: :uuid
@impl true @impl true
def generator(_constraints) do def generator(_constraints) do

View file

@ -7,7 +7,7 @@ defmodule Ash.Test.Type.TypeTest do
@moduledoc false @moduledoc false
use Ash.Type use Ash.Type
def storage_type, do: :string def storage_type(_), do: :string
def constraints do def constraints do
[ [