mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
improvement: storage_type/0 -> storage_type/1
This commit is contained in:
parent
025f75a1aa
commit
b51dbe49c9
30 changed files with 58 additions and 41 deletions
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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 ->
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
[
|
[
|
||||||
|
|
Loading…
Reference in a new issue