Skip to content

Commit 2cef7d0

Browse files
committed
improvement: add bulk_metadata ref to changesets
1 parent 277c055 commit 2cef7d0

File tree

2 files changed

+115
-4
lines changed

2 files changed

+115
-4
lines changed

lib/data_layer.ex

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,9 +1560,9 @@ defmodule AshPostgres.DataLayer do
15601560
:ok
15611561
end
15621562

1563-
{:ok, [changeset.data]}
1563+
{:ok, [add_bulk_metadata(changeset.data, changeset)]}
15641564
else
1565-
{:ok, repo.all(query, repo_opts)}
1565+
{:ok, Enum.map(repo.all(query, repo_opts), &add_bulk_metadata(&1, changeset))}
15661566
end
15671567
else
15681568
:ok
@@ -1612,9 +1612,10 @@ defmodule AshPostgres.DataLayer do
16121612
Map.merge(changeset.data, Map.take(result, modifying))
16131613
|> Map.update!(:aggregates, &Map.merge(&1, result.aggregates))
16141614
|> Map.update!(:calculations, &Map.merge(&1, result.calculations))
1615+
|> add_bulk_metadata(changeset)
16151616
|> then(&{:ok, [&1]})
16161617
else
1617-
{:ok, results}
1618+
{:ok, Enum.map(results, &add_bulk_metadata(&1, changeset))}
16181619
end
16191620
else
16201621
:ok
@@ -1887,7 +1888,8 @@ defmodule AshPostgres.DataLayer do
18871888
end)
18881889

18891890
if options[:return_records?] do
1890-
{:ok, AshSql.Query.remap_mapped_fields(results, query)}
1891+
results = AshSql.Query.remap_mapped_fields(results, query)
1892+
{:ok, Enum.map(results, &add_bulk_metadata(&1, changeset))}
18911893
else
18921894
:ok
18931895
end
@@ -3749,4 +3751,33 @@ defmodule AshPostgres.DataLayer do
37493751
resource
37503752
end
37513753
end
3754+
3755+
defp add_bulk_metadata(record, changeset) do
3756+
cond do
3757+
changeset.context[:bulk_update] ->
3758+
record
3759+
|> Ash.Resource.put_metadata(
3760+
:bulk_update_index,
3761+
changeset.context.bulk_update.index
3762+
)
3763+
|> Ash.Resource.put_metadata(
3764+
:bulk_action_ref,
3765+
changeset.context.bulk_update.ref
3766+
)
3767+
3768+
changeset.context[:bulk_destroy] ->
3769+
record
3770+
|> Ash.Resource.put_metadata(
3771+
:bulk_destroy_index,
3772+
changeset.context.bulk_destroy.index
3773+
)
3774+
|> Ash.Resource.put_metadata(
3775+
:bulk_action_ref,
3776+
changeset.context.bulk_destroy.ref
3777+
)
3778+
3779+
true ->
3780+
record
3781+
end
3782+
end
37523783
end

test/data_layer_metadata_test.exs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# SPDX-FileCopyrightText: 2019 ash_postgres contributors <https://github.com/ash-project/ash_postgres/graphs.contributors>
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
defmodule AshPostgres.DataLayerMetadataTest do
6+
use AshPostgres.RepoCase, async: false
7+
alias AshPostgres.Test.Post
8+
9+
require Ash.Query
10+
11+
test "update_query sets bulk metadata on returned records" do
12+
_post1 = Ash.create!(Post, %{title: "title1"})
13+
_post2 = Ash.create!(Post, %{title: "title2"})
14+
_post3 = Ash.create!(Post, %{title: "title3"})
15+
16+
ash_query = Ash.Query.new(Post)
17+
{:ok, query} = Ash.Query.data_layer_query(ash_query)
18+
19+
ref = make_ref()
20+
21+
changeset = %Ash.Changeset{
22+
resource: Post,
23+
action_type: :update,
24+
data: %Post{},
25+
attributes: %{title: "updated"},
26+
atomics: [],
27+
filter: nil,
28+
context: %{bulk_update: %{index: 0, ref: ref}},
29+
domain: AshPostgres.Test.Domain,
30+
tenant: nil,
31+
timeout: :infinity
32+
}
33+
34+
{:ok, results} =
35+
AshPostgres.DataLayer.update_query(query, changeset, Post, return_records?: true)
36+
37+
assert is_list(results)
38+
assert length(results) > 0
39+
40+
Enum.each(results, fn result ->
41+
assert is_integer(result.__metadata__.bulk_update_index)
42+
assert result.__metadata__.bulk_action_ref == ref
43+
end)
44+
end
45+
46+
test "destroy_query sets bulk metadata on returned records" do
47+
_post1 = Ash.create!(Post, %{title: "title1"})
48+
_post2 = Ash.create!(Post, %{title: "title2"})
49+
_post3 = Ash.create!(Post, %{title: "title3"})
50+
51+
ash_query = Ash.Query.new(Post)
52+
{:ok, query} = Ash.Query.data_layer_query(ash_query)
53+
54+
ref = make_ref()
55+
56+
changeset = %Ash.Changeset{
57+
resource: Post,
58+
action_type: :destroy,
59+
data: %Post{},
60+
attributes: %{},
61+
atomics: [],
62+
filter: nil,
63+
context: %{bulk_destroy: %{index: 0, ref: ref}},
64+
domain: AshPostgres.Test.Domain,
65+
tenant: nil,
66+
timeout: :infinity
67+
}
68+
69+
{:ok, results} =
70+
AshPostgres.DataLayer.destroy_query(query, changeset, Post, return_records?: true)
71+
72+
assert is_list(results)
73+
assert length(results) > 0
74+
75+
Enum.each(results, fn result ->
76+
assert is_integer(result.__metadata__.bulk_destroy_index)
77+
assert result.__metadata__.bulk_action_ref == ref
78+
end)
79+
end
80+
end

0 commit comments

Comments
 (0)