mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 21:13:10 +12:00
improvement: various performance improvements
This commit is contained in:
parent
52337b7bff
commit
7f7469eb9f
8 changed files with 115 additions and 52 deletions
|
@ -1314,6 +1314,8 @@ defmodule Ash.Resource.Dsl do
|
|||
]
|
||||
|
||||
@transformers [
|
||||
Ash.Resource.Transformers.AttributesByName,
|
||||
Ash.Resource.Transformers.ValidationsAndChangesForType,
|
||||
Ash.Resource.Transformers.RequireUniqueActionNames,
|
||||
Ash.Resource.Transformers.SetRelationshipSource,
|
||||
Ash.Resource.Transformers.BelongsToAttribute,
|
||||
|
|
|
@ -215,9 +215,15 @@ defmodule Ash.Resource.Info do
|
|||
Ash.Resource.Validation.t()
|
||||
]
|
||||
def validations(resource, type) do
|
||||
case Extension.get_persisted(resource, :validations_by_on) do
|
||||
nil ->
|
||||
resource
|
||||
|> validations()
|
||||
|> Enum.filter(&(type in &1.on))
|
||||
|
||||
persisted ->
|
||||
Map.get(persisted, type) || []
|
||||
end
|
||||
end
|
||||
|
||||
@doc "A list of all validations for the resource"
|
||||
|
@ -233,9 +239,15 @@ defmodule Ash.Resource.Info do
|
|||
| Ash.Resource.Change.t()
|
||||
)
|
||||
def changes(resource, type) do
|
||||
case Extension.get_persisted(resource, :changes_by_on) do
|
||||
nil ->
|
||||
resource
|
||||
|> changes()
|
||||
|> Enum.filter(&(type in &1.on))
|
||||
|
||||
persisted ->
|
||||
Map.get(persisted, type) || []
|
||||
end
|
||||
end
|
||||
|
||||
@doc "A list of all changes for the resource"
|
||||
|
@ -572,12 +584,14 @@ defmodule Ash.Resource.Info do
|
|||
@spec attribute(Spark.Dsl.t() | Ash.Resource.t(), String.t() | atom) ::
|
||||
Ash.Resource.Attribute.t() | nil
|
||||
def attribute(resource, name) when is_binary(name) do
|
||||
Extension.get_persisted(resource, :attributes_by_name)[name] ||
|
||||
resource
|
||||
|> attributes()
|
||||
|> Enum.find(&(to_string(&1.name) == name))
|
||||
end
|
||||
|
||||
def attribute(resource, name) do
|
||||
Extension.get_persisted(resource, :attributes_by_name)[name] ||
|
||||
resource
|
||||
|> attributes()
|
||||
|> Enum.find(&(&1.name == name))
|
||||
|
|
28
lib/ash/resource/transformers/attributes_by_name.ex
Normal file
28
lib/ash/resource/transformers/attributes_by_name.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
defmodule Ash.Resource.Transformers.AttributesByName do
|
||||
@moduledoc """
|
||||
Persists attribute_names and attributes_by_name.
|
||||
"""
|
||||
use Spark.Dsl.Transformer
|
||||
|
||||
alias Spark.Dsl.Transformer
|
||||
|
||||
def transform(dsl_state) do
|
||||
attributes =
|
||||
Ash.Resource.Info.attributes(dsl_state)
|
||||
|
||||
attributes_by_name =
|
||||
attributes
|
||||
|> Enum.reduce(%{}, fn %{name: name} = attr, acc ->
|
||||
acc
|
||||
|> Map.put(name, attr)
|
||||
|> Map.put(to_string(name), attr)
|
||||
end)
|
||||
|
||||
attribute_names = Enum.map(attributes, & &1.name)
|
||||
|
||||
{:ok,
|
||||
dsl_state
|
||||
|> Transformer.persist(:attributes_by_name, attributes_by_name)
|
||||
|> Transformer.persist(:attribute_names, attribute_names)}
|
||||
end
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
defmodule Ash.Resource.Transformers.ValidationsAndChangesForType do
|
||||
@moduledoc """
|
||||
Persists global changes/validations and what type they go on.
|
||||
"""
|
||||
use Spark.Dsl.Transformer
|
||||
|
||||
alias Spark.Dsl.Transformer
|
||||
|
||||
def transform(dsl_state) do
|
||||
validations_by_on =
|
||||
dsl_state
|
||||
|> Ash.Resource.Info.validations()
|
||||
|> Enum.reduce(%{}, fn validation, acc ->
|
||||
validation.on
|
||||
|> List.wrap()
|
||||
|> Enum.reduce(acc, fn on, acc ->
|
||||
Map.update(acc, on, [validation], &[validation | &1])
|
||||
end)
|
||||
end)
|
||||
|
||||
changes_by_on =
|
||||
dsl_state
|
||||
|> Ash.Resource.Info.changes()
|
||||
|> Enum.reduce(%{}, fn change, acc ->
|
||||
change.on
|
||||
|> List.wrap()
|
||||
|> Enum.reduce(acc, fn on, acc ->
|
||||
Map.update(acc, on, [change], &[change | &1])
|
||||
end)
|
||||
end)
|
||||
|
||||
{:ok,
|
||||
dsl_state
|
||||
|> Transformer.persist(:validations_by_on, validations_by_on)
|
||||
|> Transformer.persist(:changes_by_on, changes_by_on)}
|
||||
end
|
||||
end
|
|
@ -110,16 +110,10 @@ defmodule Ash.Type.NewType do
|
|||
|
||||
@impl Ash.Type
|
||||
def cast_input(value, constraints) do
|
||||
case unquote(subtype_of).cast_input(
|
||||
unquote(subtype_of).cast_input(
|
||||
value,
|
||||
constraints
|
||||
) do
|
||||
{:ok, value} ->
|
||||
apply_constraints(value, constraints)
|
||||
|
||||
other ->
|
||||
other
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
if function_exported?(subtype_of, :cast_input_array, 2) do
|
||||
|
|
|
@ -258,11 +258,7 @@ defmodule Ash.Type do
|
|||
end
|
||||
|
||||
def array_constraints(type) do
|
||||
if ash_type?(type) do
|
||||
type.array_constraints()
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_type(atom | module | {:array, atom | module}) ::
|
||||
|
@ -271,11 +267,12 @@ defmodule Ash.Type do
|
|||
{:array, get_type(value)}
|
||||
end
|
||||
|
||||
def get_type(value) when is_atom(value) do
|
||||
case Keyword.fetch(@short_names, value) do
|
||||
{:ok, mod} -> mod
|
||||
:error -> value
|
||||
for {short_name, value} <- @short_names do
|
||||
def get_type(unquote(short_name)), do: unquote(value)
|
||||
end
|
||||
|
||||
def get_type(value) when is_atom(value) do
|
||||
value
|
||||
end
|
||||
|
||||
def get_type(value) do
|
||||
|
@ -663,14 +660,10 @@ defmodule Ash.Type do
|
|||
def apply_constraints(type, term, constraints) do
|
||||
type = get_type(type)
|
||||
|
||||
if ash_type?(type) do
|
||||
case type.apply_constraints(term, constraints) do
|
||||
:ok -> {:ok, term}
|
||||
other -> other
|
||||
end
|
||||
else
|
||||
{:ok, term}
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
|
@ -720,11 +713,8 @@ defmodule Ash.Type do
|
|||
end
|
||||
|
||||
def constraints(type) do
|
||||
if ash_type?(type) do
|
||||
type = get_type(type)
|
||||
type.constraints()
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def cast_in_query?(type, constraints \\ [])
|
||||
|
@ -734,15 +724,13 @@ defmodule Ash.Type do
|
|||
end
|
||||
|
||||
def cast_in_query?(type, constraints) do
|
||||
if ash_type?(type) do
|
||||
type = get_type(type)
|
||||
|
||||
if function_exported?(type, :cast_in_query?, 0) do
|
||||
type.cast_in_query?()
|
||||
else
|
||||
type.cast_in_query?(constraints)
|
||||
end
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -302,7 +302,7 @@ defmodule Ash.MixProject do
|
|||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
{:spark, "~> 1.1 and >= 1.1.20"},
|
||||
{:spark, "~> 1.1 and >= 1.1.47"},
|
||||
{:ecto, "~> 3.7"},
|
||||
{:ets, "~> 0.8"},
|
||||
{:decimal, "~> 2.0"},
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -31,7 +31,7 @@
|
|||
"plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
|
||||
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
|
||||
"sourceror": {:hex, :sourceror, "0.14.0", "b6b8552d0240400d66b6f107c1bab7ac1726e998efc797f178b7b517e928e314", [:mix], [], "hexpm", "809c71270ad48092d40bbe251a133e49ae229433ce103f762a2373b7a10a8d8b"},
|
||||
"spark": {:hex, :spark, "1.1.44", "be9f2669b03ae43447bda77045598a4500988538a7d0ba576b8e306332822147", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "e49bf5ca770cb0bb9cac7ed8da5eb7871156b3236c8c535f3f4caa93377059a3"},
|
||||
"spark": {:hex, :spark, "1.1.47", "2bc334e542f519709e57853a425aa9304223c61e3ecf130b1cc014c6a4451f9a", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "c1ae778a3779b5d3e5b7c885cc9826577816dca10bbf4c21638198a1262f3df1"},
|
||||
"statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"},
|
||||
"stream_data": {:hex, :stream_data, "0.6.0", "e87a9a79d7ec23d10ff83eb025141ef4915eeb09d4491f79e52f2562b73e5f47", [:mix], [], "hexpm", "b92b5031b650ca480ced047578f1d57ea6dd563f5b57464ad274718c9c29501c"},
|
||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||
|
|
Loading…
Reference in a new issue