Skip to content

Commit

Permalink
improvement: proper error on unsupported aggregates
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Sep 23, 2024
1 parent a4b2af4 commit 1982d66
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 7 deletions.
9 changes: 7 additions & 2 deletions lib/ash/actions/aggregate.ex
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ defmodule Ash.Actions.Aggregate do
query.resource,
name,
kind,
set_opts(query, [], opts)
Keyword.put(set_opts(query, [], opts), :agg_name, name)
) do
{:ok, aggregate} ->
{:cont, {:ok, [aggregate | aggregates]}}
Expand All @@ -157,7 +157,12 @@ defmodule Ash.Actions.Aggregate do
end

{name, kind, agg_opts}, {:ok, aggregates} ->
case Ash.Query.Aggregate.new(query.resource, name, kind, set_opts(query, agg_opts, opts)) do
case Ash.Query.Aggregate.new(
query.resource,
name,
kind,
Keyword.put(set_opts(query, agg_opts, opts), :agg_name, name)
) do
{:ok, aggregate} ->
{:cont, {:ok, [aggregate | aggregates]}}

Expand Down
2 changes: 2 additions & 0 deletions lib/ash/actions/read/read.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2871,6 +2871,7 @@ defmodule Ash.Actions.Read do
resource,
resource_aggregate.name,
resource_aggregate.kind,
agg_name: resource_aggregate.name,
path: resource_aggregate.relationship_path,
query: aggregate_query,
field: resource_aggregate.field,
Expand Down Expand Up @@ -3125,6 +3126,7 @@ defmodule Ash.Actions.Read do
related_resource,
resource_aggregate.name,
resource_aggregate.kind,
agg_name: resource_aggregate.name,
path: resource_aggregate.relationship_path,
query: aggregate_query,
field: resource_aggregate.field,
Expand Down
5 changes: 4 additions & 1 deletion lib/ash/filter/filter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2109,6 +2109,7 @@ defmodule Ash.Filter do
resource,
aggregate.name,
aggregate.kind,
agg_name: aggregate.name,
path: aggregate.relationship_path,
query: aggregate_query,
field: aggregate.field,
Expand Down Expand Up @@ -2808,6 +2809,7 @@ defmodule Ash.Filter do
context.resource,
aggregate.name,
aggregate.kind,
agg_name: aggregate.name,
path: aggregate.relationship_path,
query: aggregate_query,
field: aggregate.field,
Expand Down Expand Up @@ -3162,7 +3164,7 @@ defmodule Ash.Filter do
opts = Keyword.put(opts, :path, path)

with {:ok, agg} <-
Ash.Query.Aggregate.new(
Aggregate.new(
resource,
agg_name(kind, opts),
kind,
Expand Down Expand Up @@ -3535,6 +3537,7 @@ defmodule Ash.Filter do
related,
aggregate.name,
aggregate.kind,
agg_name: aggregate.name,
path: aggregate.relationship_path,
query: aggregate_query,
field: aggregate.field,
Expand Down
32 changes: 29 additions & 3 deletions lib/ash/query/aggregate.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Ash.Query.Aggregate do
@kinds [:count, :first, :sum, :list, :max, :min, :avg, :exists, :custom]
@type kind :: unquote(Enum.reduce(@kinds, &{:|, [], [&1, &2]}))

alias Ash.Error.Query.{NoReadAction, NoSuchRelationship}
alias Ash.Error.Query.{AggregatesNotSupported, NoReadAction, NoSuchRelationship}

require Ash.Query

Expand Down Expand Up @@ -60,6 +60,11 @@ defmodule Ash.Query.Aggregate do
"The relationship path to aggregate over. Only used when adding aggregates to a query.",
default: []
],
agg_name: [
type: :any,
hide: true,
doc: "A resource calculation this calculation maps to."
],
query: [
type: :any,
doc:
Expand Down Expand Up @@ -180,7 +185,9 @@ defmodule Ash.Query.Aggregate do
false
end)

with {:ok, %Opts{} = opts} <- Opts.validate(opts) do
with {:ok, %Opts{} = opts} <- Opts.validate(opts),
agg_name = agg_name(opts),
:ok <- validate_supported(resource, kind, agg_name) do
related = Ash.Resource.Info.related(resource, opts.path)

query =
Expand Down Expand Up @@ -334,7 +341,7 @@ defmodule Ash.Query.Aggregate do
{:ok,
%__MODULE__{
name: name,
agg_name: name,
agg_name: agg_name,
resource: resource,
constraints: constraints,
default_value: default || default_value(kind),
Expand Down Expand Up @@ -367,6 +374,25 @@ defmodule Ash.Query.Aggregate do
end
end

defp agg_name(opts) do
if :agg_name in opts.__set__ do
opts.agg_name
end
end

defp validate_supported(resource, kind, nil) do
if Ash.DataLayer.data_layer_can?(resource, {:aggregate, kind}) do
:ok
else
{:error, AggregatesNotSupported.exception(resource: resource, feature: "using")}
end
end

# resource aggregates can only exist if supported, so we don't need to check
defp validate_supported(_resource, _kind, _agg_name) do
:ok
end

defp parse_join_filter(resource, path, filter) do
[last_relationship | relationships] =
path_to_reversed_relationships(resource, path)
Expand Down
2 changes: 1 addition & 1 deletion lib/ash/query/calculation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ defmodule Ash.Query.Calculation do
calc_name: [
type: :any,
hide: true,
doc: "A resource calculation this calculation maps to. Defaults to `name`"
doc: "A resource calculation this calculation maps to."
],
source_context: [
type: :map,
Expand Down
1 change: 1 addition & 0 deletions lib/ash/query/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1628,6 +1628,7 @@ defmodule Ash.Query do
query.resource,
aggregate.name,
aggregate.kind,
agg_name: aggregate.name,
path: aggregate.relationship_path,
query: [filter: aggregate.filter, sort: aggregate.sort],
field: aggregate.field,
Expand Down

0 comments on commit 1982d66

Please sign in to comment.