Skip to content

Commit

Permalink
improvement: support a 2 argument function for the repo option
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Nov 14, 2023
1 parent cae89d8 commit db8255e
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 107 deletions.

Large diffs are not rendered by default.

46 changes: 29 additions & 17 deletions lib/data_layer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ defmodule AshPostgres.DataLayer do
],
schema: [
repo: [
type: :atom,
type: {:or, [{:behaviour, Ecto.Repo}, {:fun, 2}]},
required: true,
doc:
"The repo that will be used to fetch your data. See the `AshPostgres.Repo` documentation for more"
"The repo that will be used to fetch your data. See the `AshPostgres.Repo` documentation for more. Can also be a function that takes a resource and a type `:read | :mutate` and returns the repo"
],
migrate?: [
type: :boolean,
Expand Down Expand Up @@ -447,17 +447,18 @@ defmodule AshPostgres.DataLayer do
other_data_layer = Ash.DataLayer.data_layer(other_resource)

data_layer == other_data_layer and
AshPostgres.DataLayer.Info.repo(resource) == AshPostgres.DataLayer.Info.repo(other_resource)
AshPostgres.DataLayer.Info.repo(resource, :read) ==
AshPostgres.DataLayer.Info.repo(other_resource, :read)
end

def can?(resource, {:lateral_join, resources}) do
repo = AshPostgres.DataLayer.Info.repo(resource)
repo = AshPostgres.DataLayer.Info.repo(resource, :read)
data_layer = Ash.DataLayer.data_layer(resource)

data_layer == __MODULE__ &&
Enum.all?(resources, fn resource ->
Ash.DataLayer.data_layer(resource) == data_layer &&
AshPostgres.DataLayer.Info.repo(resource) == repo
AshPostgres.DataLayer.Info.repo(resource, :read) == repo
end)
end

Expand Down Expand Up @@ -510,7 +511,7 @@ defmodule AshPostgres.DataLayer do

@impl true
def in_transaction?(resource) do
AshPostgres.DataLayer.Info.repo(resource).in_transaction?()
AshPostgres.DataLayer.Info.repo(resource, :mutate).in_transaction?()
end

@impl true
Expand Down Expand Up @@ -683,7 +684,7 @@ defmodule AshPostgres.DataLayer do

@impl true
def functions(resource) do
config = AshPostgres.DataLayer.Info.repo(resource).config()
config = AshPostgres.DataLayer.Info.repo(resource, :mutate).config()

functions = [
AshPostgres.Functions.Fragment,
Expand Down Expand Up @@ -1131,7 +1132,7 @@ defmodule AshPostgres.DataLayer do

@doc false
def set_subquery_prefix(data_layer_query, source_query, resource) do
config = AshPostgres.DataLayer.Info.repo(resource).config()
config = AshPostgres.DataLayer.Info.repo(resource, :mutate).config()

if Ash.Resource.Info.multitenancy_strategy(resource) == :context do
%{
Expand Down Expand Up @@ -1357,7 +1358,7 @@ defmodule AshPostgres.DataLayer do

AshPostgres.MultiTenancy.create_tenant!(
tenant_name,
AshPostgres.DataLayer.Info.repo(resource)
AshPostgres.DataLayer.Info.repo(resource, :read)
)
else
:ok
Expand All @@ -1378,7 +1379,7 @@ defmodule AshPostgres.DataLayer do
new_tenant_name = tenant_name(resource, result)

AshPostgres.MultiTenancy.rename_tenant(
AshPostgres.DataLayer.Info.repo(resource),
AshPostgres.DataLayer.Info.repo(resource, :read),
old_tenant_name,
new_tenant_name
)
Expand Down Expand Up @@ -2621,7 +2622,7 @@ defmodule AshPostgres.DataLayer do
repo

_ ->
AshPostgres.DataLayer.Info.repo(resource)
AshPostgres.DataLayer.Info.repo(resource, :read)
end

func = fn ->
Expand All @@ -2638,7 +2639,7 @@ defmodule AshPostgres.DataLayer do

@impl true
def rollback(resource, term) do
AshPostgres.DataLayer.Info.repo(resource).rollback(term)
AshPostgres.DataLayer.Info.repo(resource, :mutate).rollback(term)
end

defp table(resource, changeset) do
Expand All @@ -2661,14 +2662,25 @@ defmodule AshPostgres.DataLayer do
end

defp dynamic_repo(resource, %{__ash_bindings__: %{context: %{data_layer: %{repo: repo}}}}) do
repo || AshPostgres.DataLayer.Info.repo(resource)
repo || AshPostgres.DataLayer.Info.repo(resource, :read)
end

defp dynamic_repo(resource, %{context: %{data_layer: %{repo: repo}}}) do
repo || AshPostgres.DataLayer.Info.repo(resource)
defp dynamic_repo(resource, %struct{context: %{data_layer: %{repo: repo}}}) do
type = struct_to_repo_type(struct)

repo || AshPostgres.DataLayer.Info.repo(resource, type)
end

defp dynamic_repo(resource, %struct{}) do
AshPostgres.DataLayer.Info.repo(resource, struct_to_repo_type(struct))
end

defp dynamic_repo(resource, _) do
AshPostgres.DataLayer.Info.repo(resource)
defp struct_to_repo_type(struct) do
case struct do
Ash.Changeset -> :mutate
Ash.Query -> :read
Ecto.Query -> :read
Ecto.Changeset -> :mutate
end
end
end
10 changes: 8 additions & 2 deletions lib/data_layer/info.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ defmodule AshPostgres.DataLayer.Info do
alias Spark.Dsl.Extension

@doc "The configured repo for a resource"
def repo(resource) do
Extension.get_opt(resource, [:postgres], :repo, nil, true)
def repo(resource, type \\ :mutate) do
case Extension.get_opt(resource, [:postgres], :repo, nil, true) do
fun when is_function(fun, 2) ->
fun.(resource, type)

repo ->
repo
end
end

@doc "The configured table for a resource"
Expand Down
6 changes: 3 additions & 3 deletions lib/expr.ex
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ defmodule AshPostgres.Expr do
embedded?,
type
) do
if "citext" in AshPostgres.DataLayer.Info.repo(query.__ash_bindings__.resource).installed_extensions() do
if "citext" in AshPostgres.DataLayer.Info.repo(query.__ash_bindings__.resource, :mutate).installed_extensions() do
do_dynamic_expr(
query,
%Fragment{
Expand Down Expand Up @@ -1528,7 +1528,7 @@ defmodule AshPostgres.Expr do

defp require_ash_functions!(query, operator) do
installed_extensions =
AshPostgres.DataLayer.Info.repo(query.__ash_bindings__.resource).installed_extensions()
AshPostgres.DataLayer.Info.repo(query.__ash_bindings__.resource, :mutate).installed_extensions()

unless "ash-functions" in installed_extensions do
raise """
Expand All @@ -1540,7 +1540,7 @@ defmodule AshPostgres.Expr do
end

defp require_extension!(query, extension, context) do
repo = AshPostgres.DataLayer.Info.repo(query.__ash_bindings__.resource)
repo = AshPostgres.DataLayer.Info.repo(query.__ash_bindings__.resource, :mutate)

unless extension in repo.installed_extensions() do
raise Ash.Error.Query.InvalidExpression,
Expand Down
2 changes: 1 addition & 1 deletion lib/join.ex
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ defmodule AshPostgres.Join do
join_query
| prefix:
AshPostgres.DataLayer.Info.schema(resource) ||
AshPostgres.DataLayer.Info.repo(resource).config()[:default_prefix] ||
AshPostgres.DataLayer.Info.repo(resource, :mutate).config()[:default_prefix] ||
"public"
}
end
Expand Down
20 changes: 11 additions & 9 deletions lib/migration_generator/migration_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ defmodule AshPostgres.MigrationGenerator do
all_resources
|> Enum.filter(fn resource ->
Ash.DataLayer.data_layer(resource) == AshPostgres.DataLayer &&
AshPostgres.DataLayer.Info.repo(resource) == repo &&
AshPostgres.DataLayer.Info.repo(resource, :mutate) == repo &&
(is_nil(only_resources) || resource in only_resources)
end)
|> Enum.flat_map(&get_snapshots(&1, all_resources))
Expand Down Expand Up @@ -2415,7 +2415,7 @@ defmodule AshPostgres.MigrationGenerator do
defp pad(i), do: to_string(i)

def get_snapshots(resource, all_resources) do
Code.ensure_compiled!(AshPostgres.DataLayer.Info.repo(resource))
Code.ensure_compiled!(AshPostgres.DataLayer.Info.repo(resource, :mutate))

if AshPostgres.DataLayer.Info.polymorphic?(resource) do
all_resources
Expand Down Expand Up @@ -2459,7 +2459,7 @@ defmodule AshPostgres.MigrationGenerator do
default(
source_attribute,
relationship.destination,
AshPostgres.DataLayer.Info.repo(relationship.destination)
AshPostgres.DataLayer.Info.repo(relationship.destination, :mutate)
),
deferrable: false,
destination_attribute_generated: source_attribute.generated?,
Expand Down Expand Up @@ -2493,7 +2493,7 @@ defmodule AshPostgres.MigrationGenerator do
check_constraints: check_constraints(resource),
custom_indexes: custom_indexes(resource),
custom_statements: custom_statements(resource),
repo: AshPostgres.DataLayer.Info.repo(resource),
repo: AshPostgres.DataLayer.Info.repo(resource, :mutate),
multitenancy: multitenancy(resource),
base_filter: AshPostgres.DataLayer.Info.base_filter_sql(resource),
has_create_action: has_create_action?(resource)
Expand Down Expand Up @@ -2584,7 +2584,7 @@ defmodule AshPostgres.MigrationGenerator do
end

defp attributes(resource, table) do
repo = AshPostgres.DataLayer.Info.repo(resource)
repo = AshPostgres.DataLayer.Info.repo(resource, :mutate)
ignored = AshPostgres.DataLayer.Info.migration_ignore_attributes(resource) || []

resource
Expand Down Expand Up @@ -2680,7 +2680,7 @@ defmodule AshPostgres.MigrationGenerator do
schema:
relationship.context[:data_layer][:schema] ||
AshPostgres.DataLayer.Info.schema(relationship.destination) ||
AshPostgres.DataLayer.Info.repo(relationship.destination).config()[
AshPostgres.DataLayer.Info.repo(relationship.destination, :mutate).config()[
:default_prefix
],
table:
Expand All @@ -2704,7 +2704,9 @@ defmodule AshPostgres.MigrationGenerator do
schema:
relationship.context[:data_layer][:schema] ||
AshPostgres.DataLayer.Info.schema(relationship.destination) ||
AshPostgres.DataLayer.Info.repo(relationship.destination).config()[:default_prefix],
AshPostgres.DataLayer.Info.repo(relationship.destination, :mutate).config()[
:default_prefix
],
name: nil,
ignore?: false
})
Expand Down Expand Up @@ -2741,8 +2743,8 @@ defmodule AshPostgres.MigrationGenerator do

defp foreign_key?(relationship) do
Ash.DataLayer.data_layer(relationship.source) == AshPostgres.DataLayer &&
AshPostgres.DataLayer.Info.repo(relationship.source) ==
AshPostgres.DataLayer.Info.repo(relationship.destination)
AshPostgres.DataLayer.Info.repo(relationship.source, :mutate) ==
AshPostgres.DataLayer.Info.repo(relationship.destination, :mutate)
end

defp identities(resource) do
Expand Down
4 changes: 3 additions & 1 deletion lib/mix/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ defmodule AshPostgres.MixHelpers do
end

resources
|> Enum.map(&AshPostgres.DataLayer.Info.repo(&1))
|> Enum.flat_map(
&[AshPostgres.DataLayer.Info.repo(&1, :read), AshPostgres.DataLayer.Info.repo(&1, :mutate)]
)
|> Enum.uniq()
|> case do
[] ->
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ defmodule AshPostgres.MixProject do
"sobelow --skip -i Config.Secrets --ignore-files lib/migration_generator/migration_generator.ex",
credo: "credo --strict",
docs: [
"spark.cheat_sheets",
# "spark.cheat_sheets",
"docs",
"spark.replace_doc_links",
"spark.cheat_sheets_in_search"
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%{
"ash": {:hex, :ash, "2.15.20", "0702181ca817ab1cad5e3ccb53851c56a9c8ec0a010780ad7eb881a997151e38", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 1.1.47 and < 2.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.6", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efa3afe081ed22f1c7d6dc45de13b8b80f8ab831ebaa255108aad11cacd23b13"},
"ash": {:hex, :ash, "2.17.1", "728a917baab9599b4bed4156009b3465fa5a24a9511dab212894b044d13d1a36", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 1.1.50 and < 2.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.6", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d45d8c6a9c99a0088ec5451692e46e03556d00575bfe00497a2e32f90163763f"},
"benchee": {:hex, :benchee, "1.1.0", "f3a43817209a92a1fade36ef36b86e1052627fd8934a8b937ac9ab3a76c43062", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}], "hexpm", "7da57d545003165a012b587077f6ba90b89210fd88074ce3c60ce239eb5e6d93"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
Expand Down Expand Up @@ -37,7 +37,7 @@
"postgrex": {:hex, :postgrex, "0.17.3", "c92cda8de2033a7585dae8c61b1d420a1a1322421df84da9a82a6764580c503d", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "946cf46935a4fdca7a81448be76ba3503cff082df42c6ec1ff16a4bdfbfb098d"},
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
"sourceror": {:hex, :sourceror, "0.14.1", "c6fb848d55bd34362880da671debc56e77fd722fa13b4dcbeac89a8998fc8b09", [:mix], [], "hexpm", "8b488a219e4c4d7d9ff29d16346fd4a5858085ccdd010e509101e226bbfd8efc"},
"spark": {:hex, :spark, "1.1.50", "809da1214151ad7c592389b3ea85eb4424f727b681b90439d8ffbe5305400ce9", [: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", "ed9b1b817b52c3aaeee283032640857ee9d8398b8c4e9e7d78d77929d387b9a1"},
"spark": {:hex, :spark, "1.1.51", "8458de5abbb89d18dd5c9235dd39e3757076eba84a5078d1cdc2c1e23c39aa95", [: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", "ed8410aa8db08867b8fff3d65e54deeb7f6f6cf2b8698fc405a386c1c7a9e4f0"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"},
"stream_data": {:hex, :stream_data, "0.6.0", "e87a9a79d7ec23d10ff83eb025141ef4915eeb09d4491f79e52f2562b73e5f47", [:mix], [], "hexpm", "b92b5031b650ca480ced047578f1d57ea6dd563f5b57464ad274718c9c29501c"},
Expand Down
1 change: 0 additions & 1 deletion test/sort_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ defmodule AshPostgres.SortTest do

require Ash.Query
require Ash.Sort
import Ash.Expr

test "multi-column sorts work" do
Post
Expand Down

0 comments on commit db8255e

Please sign in to comment.