mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: handle new type constraints properly
This commit is contained in:
parent
f892192969
commit
d9bacc1554
6 changed files with 21 additions and 57 deletions
|
@ -21,14 +21,6 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
raise ArgumentError, "Cannot specify `sorted?: true` and `return_stream?: true` together"
|
raise ArgumentError, "Cannot specify `sorted?: true` and `return_stream?: true` together"
|
||||||
end
|
end
|
||||||
|
|
||||||
opts =
|
|
||||||
if opts[:max_concurrency] && opts[:max_concurrency] > 0 &&
|
|
||||||
not Ash.DataLayer.can?(:async_engine, resource) do
|
|
||||||
Keyword.put(opts, :max_concurrency, 0)
|
|
||||||
else
|
|
||||||
opts
|
|
||||||
end
|
|
||||||
|
|
||||||
if opts[:transaction] == :all &&
|
if opts[:transaction] == :all &&
|
||||||
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
Ash.DataLayer.data_layer_can?(resource, :transact) do
|
||||||
notify? =
|
notify? =
|
||||||
|
@ -168,7 +160,7 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
end,
|
end,
|
||||||
fn _ -> :ok end
|
fn _ -> :ok end
|
||||||
)
|
)
|
||||||
|> map_batches(opts, fn
|
|> map_batches(resource, opts, fn
|
||||||
batch_config ->
|
batch_config ->
|
||||||
%{count: count, batch: batch, must_return_records?: must_return_records?} = batch_config
|
%{count: count, batch: batch, must_return_records?: must_return_records?} = batch_config
|
||||||
context = batch |> Enum.at(0) |> Kernel.||(%{}) |> Map.get(:context)
|
context = batch |> Enum.at(0) |> Kernel.||(%{}) |> Map.get(:context)
|
||||||
|
@ -497,9 +489,17 @@ defmodule Ash.Actions.Create.Bulk do
|
||||||
%{result | errors: errors, error_count: error_count}
|
%{result | errors: errors, error_count: error_count}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp map_batches(stream, opts, callback) do
|
defp map_batches(stream, resource, opts, callback) do
|
||||||
max_concurrency = opts[:max_concurrency]
|
max_concurrency = opts[:max_concurrency]
|
||||||
|
|
||||||
|
max_concurrency =
|
||||||
|
if max_concurrency && max_concurrency > 0 &&
|
||||||
|
not Ash.DataLayer.can?(:async_engine, resource) do
|
||||||
|
max_concurrency
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
|
||||||
if max_concurrency && max_concurrency > 1 do
|
if max_concurrency && max_concurrency > 1 do
|
||||||
Task.async_stream(
|
Task.async_stream(
|
||||||
stream,
|
stream,
|
||||||
|
|
|
@ -33,6 +33,7 @@ defmodule Ash.Type.DateTime do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@spec storage_type(nonempty_maybe_improper_list()) :: any()
|
||||||
def storage_type([{:storage_type, storage_type} | _]) do
|
def storage_type([{:storage_type, storage_type} | _]) do
|
||||||
storage_type
|
storage_type
|
||||||
end
|
end
|
||||||
|
|
|
@ -127,7 +127,7 @@ defmodule Ash.Type.NewType do
|
||||||
|
|
||||||
@impl Ash.Type
|
@impl Ash.Type
|
||||||
def init(constraints) do
|
def init(constraints) do
|
||||||
{:ok, type_constraints(constraints, unquote(subtype_constraints))}
|
unquote(subtype_of).init(type_constraints(constraints, unquote(subtype_constraints)))
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl Ash.Type
|
@impl Ash.Type
|
||||||
|
|
|
@ -373,7 +373,10 @@ defmodule Ash.Type do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def init(type, constraints), do: type.init(constraints)
|
def init(type, constraints) do
|
||||||
|
type = get_type(type)
|
||||||
|
type.init(constraints)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
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*)
|
||||||
|
@ -946,7 +949,9 @@ defmodule Ash.Type do
|
||||||
def init(opts) do
|
def init(opts) do
|
||||||
constraints = @parent.constraints()
|
constraints = @parent.constraints()
|
||||||
|
|
||||||
Keyword.take(opts, Keyword.keys(constraints))
|
opts
|
||||||
|
|> Keyword.take(Keyword.keys(constraints))
|
||||||
|
|> @parent.init()
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
|
@ -231,49 +231,6 @@ defmodule Ash.Test.Actions.BulkCreateTest do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can run batches concurrently" do
|
|
||||||
assert %Ash.BulkResult{
|
|
||||||
records: [
|
|
||||||
%{title: "title1", title2: "changes", title3: "wont"},
|
|
||||||
%{title: "title2", title2: "changes", title3: "wont"}
|
|
||||||
]
|
|
||||||
} =
|
|
||||||
Api.bulk_create!(
|
|
||||||
[
|
|
||||||
%{title: "title1", title2: "changes", title3: "wont"},
|
|
||||||
%{title: "title2", title2: "changes", title3: "wont"}
|
|
||||||
],
|
|
||||||
Post,
|
|
||||||
:create,
|
|
||||||
return_records?: true,
|
|
||||||
batch_size: 1,
|
|
||||||
max_concurrency: 2,
|
|
||||||
sorted?: true
|
|
||||||
)
|
|
||||||
|
|
||||||
assert %Ash.BulkResult{
|
|
||||||
records: [
|
|
||||||
%{title: "title1", title2: "did_change", title3: "wont"},
|
|
||||||
%{title: "title2", title2: "did_change", title3: "wont"}
|
|
||||||
]
|
|
||||||
} =
|
|
||||||
Api.bulk_create!(
|
|
||||||
[
|
|
||||||
%{title: "title1", title2: "did_change", title3: "oh no"},
|
|
||||||
%{title: "title2", title2: "did_change", title3: "what happened"}
|
|
||||||
],
|
|
||||||
Post,
|
|
||||||
:create,
|
|
||||||
return_records?: true,
|
|
||||||
batch_size: 1,
|
|
||||||
max_concurrency: 2,
|
|
||||||
upsert?: true,
|
|
||||||
upsert_identity: :unique_title,
|
|
||||||
upsert_fields: [:title2],
|
|
||||||
sorted?: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "runs after action hooks" do
|
test "runs after action hooks" do
|
||||||
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
assert %Ash.BulkResult{records: [%{title: "title1_stuff"}, %{title: "title2_stuff"}]} =
|
||||||
Api.bulk_create!(
|
Api.bulk_create!(
|
||||||
|
|
|
@ -807,7 +807,7 @@ defmodule Ash.Test.Actions.LoadTest do
|
||||||
|> new(%{name: "zerg"})
|
|> new(%{name: "zerg"})
|
||||||
|> Api.create!()
|
|> Api.create!()
|
||||||
|
|
||||||
_post1 =
|
post1 =
|
||||||
Post
|
Post
|
||||||
|> new(%{title: "post1"})
|
|> new(%{title: "post1"})
|
||||||
|> manage_relationship(:author, author, type: :append_and_remove)
|
|> manage_relationship(:author, author, type: :append_and_remove)
|
||||||
|
@ -824,6 +824,7 @@ defmodule Ash.Test.Actions.LoadTest do
|
||||||
|> Ash.Query.load(:latest_post)
|
|> Ash.Query.load(:latest_post)
|
||||||
|> Api.read!()
|
|> Api.read!()
|
||||||
|
|
||||||
|
refute author.latest_post.id == post1.id
|
||||||
assert author.latest_post.id == post2.id
|
assert author.latest_post.id == post2.id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue