Skip to content

Commit d861ce0

Browse files
committed
improvement: support prefer_transaction?
1 parent 879c8f1 commit d861ce0

File tree

5 files changed

+28
-7
lines changed

5 files changed

+28
-7
lines changed

lib/data_layer.ex

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,11 @@ defmodule AshPostgres.DataLayer do
605605

606606
import Ecto.Query, only: [from: 2, subquery: 1]
607607

608+
@impl true
609+
def prefer_transaction?(resource) do
610+
AshPostgres.DataLayer.Info.repo(resource, :mutate).prefer_transaction?()
611+
end
612+
608613
@impl true
609614
def can?(_, :async_engine), do: true
610615
def can?(_, :bulk_create), do: true
@@ -1773,7 +1778,12 @@ defmodule AshPostgres.DataLayer do
17731778
|> AshSql.Bindings.default_bindings(resource, AshPostgres.SqlImplementation)
17741779

17751780
upsert_set =
1776-
upsert_set(resource, changesets, options)
1781+
upsert_set(
1782+
resource,
1783+
changesets,
1784+
options[:upsert_keys] || Ash.Resource.Info.primary_key(resource),
1785+
options
1786+
)
17771787

17781788
on_conflict =
17791789
case AshSql.Atomics.query_with_atomics(
@@ -1785,7 +1795,11 @@ defmodule AshPostgres.DataLayer do
17851795
upsert_set
17861796
) do
17871797
:empty ->
1788-
{:replace, options[:upsert_keys] || Ash.Resource.Info.primary_key(resource)}
1798+
if options[:return_records?] do
1799+
{:replace, options[:upsert_keys] || Ash.Resource.Info.primary_key(resource)}
1800+
else
1801+
:nothing
1802+
end
17891803

17901804
{:ok, query} ->
17911805
query
@@ -1913,7 +1927,7 @@ defmodule AshPostgres.DataLayer do
19131927
fun.()
19141928
end
19151929

1916-
defp upsert_set(resource, changesets, options) do
1930+
defp upsert_set(resource, changesets, keys, options) do
19171931
attributes_changing_anywhere =
19181932
changesets |> Enum.flat_map(&Map.keys(&1.attributes)) |> Enum.uniq()
19191933

@@ -1926,7 +1940,7 @@ defmodule AshPostgres.DataLayer do
19261940

19271941
fields_to_upsert =
19281942
upsert_fields --
1929-
Keyword.keys(Enum.at(changesets, 0).atomics)
1943+
Keyword.keys(Enum.at(changesets, 0).atomics) -- keys
19301944

19311945
fields_to_upsert
19321946
|> Enum.uniq()

lib/repo.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ defmodule AshPostgres.Repo do
6969
@doc "The default prefix(postgres schema) to use when building queries"
7070
@callback default_prefix() :: String.t()
7171

72+
@doc "Whether or not to explicitly start and close a transaction for each action, even if there are no transaction hooks"
73+
@callback prefer_transaction?() :: boolean
74+
7275
@doc "Allows overriding a given migration type for *all* fields, for example if you wanted to always use :timestamptz for :utc_datetime fields"
7376
@callback override_migration_type(atom) :: atom
7477
@doc "Should the repo should be created by `mix ash_postgres.create`?"
@@ -102,6 +105,9 @@ defmodule AshPostgres.Repo do
102105
def create?, do: true
103106
def drop?, do: true
104107

108+
# default to false in 4.0
109+
def prefer_transaction?, do: true
110+
105111
def transaction!(fun) do
106112
case fun.() do
107113
{:ok, value} -> value
@@ -242,6 +248,7 @@ defmodule AshPostgres.Repo do
242248
on_transaction_begin: 1,
243249
installed_extensions: 0,
244250
all_tenants: 0,
251+
prefer_transaction?: 0,
245252
tenant_migrations_path: 0,
246253
default_prefix: 0,
247254
override_migration_type: 1,

test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ defmodule AshPostgres.EmptyAtomicNonBulkActionsPolicyBypassTest do
1616
|> Ash.Changeset.for_create(:create, %{})
1717
|> Ash.create!()
1818

19-
Logger.configure(level: :debug)
20-
2119
assert_raise Ash.Error.Forbidden, fn ->
2220
post
2321
|> Ash.Changeset.for_update(:empty_update, %{}, authorize?: true)

test/support/test_repo.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ defmodule AshPostgres.TestRepo do
77
send(self(), data)
88
end
99

10+
def prefer_transaction?, do: false
11+
1012
def installed_extensions do
1113
["ash-functions", "uuid-ossp", "pg_trgm", "citext", AshPostgres.TestCustomExtension, "ltree"] --
1214
Application.get_env(:ash_postgres, :no_extensions, [])

test/test_helper.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ExUnit.start(capture_log: true)
1+
ExUnit.start(capture_log: false)
22

33
exclude_tags =
44
case System.get_env("PG_VERSION") do

0 commit comments

Comments
 (0)