Skip to content

Commit

Permalink
handle filter
Browse files Browse the repository at this point in the history
  • Loading branch information
barnabasJ committed Aug 15, 2024
1 parent 19b58cb commit 4b51589
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 25 deletions.
30 changes: 18 additions & 12 deletions lib/graphql/resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -507,15 +507,28 @@ defmodule AshGraphql.Graphql.Resolver do
end

def resolve(
%{arguments: _arguments, context: context, root_value: data} = resolution,
%{arguments: arguments, context: context, root_value: notification} = resolution,
{domain, resource, %AshGraphql.Resource.Subscription{read_action: read_action}, _input?}
) do
dbg(NOTIFICATION: notification)
data = notification.data

read_action =
read_action || Ash.Resource.Info.primary_action!(resource, :read).name

query =
Ash.Resource.Info.primary_key(resource)
|> Enum.reduce(resource, fn key, query ->
value = Map.get(data, key)
Ash.Query.filter(query, ^ref(key) == ^value)
end)

query =
Ash.Query.do_filter(query, massage_filter(query.resource, Map.get(arguments, :filter)))

query =
AshGraphql.Subscription.query_for_subscription(
resource
query
|> Ash.Query.for_read(read_action, %{},
actor: Map.get(context, :actor),
tenant: Map.get(context, :tenant)
Expand All @@ -524,13 +537,6 @@ defmodule AshGraphql.Graphql.Resolver do
resolution
)

query =
Ash.Resource.Info.primary_key(resource)
|> Enum.reduce(query, fn key, query ->
value = Map.get(data, key)
Ash.Query.filter(query, ^ref(key) == ^value)
end)

case query |> Ash.read_one() do
# should only happen if a resource is created/updated and the subscribed user is not allowed to see it
{:ok, nil} ->
Expand Down Expand Up @@ -1641,9 +1647,9 @@ defmodule AshGraphql.Graphql.Resolver do
end)}
end

defp massage_filter(_resource, nil), do: nil
def massage_filter(_resource, nil), do: nil

defp massage_filter(resource, filter) when is_map(filter) do
def massage_filter(resource, filter) when is_map(filter) do
Map.new(filter, fn {key, value} ->
cond do
rel = Ash.Resource.Info.relationship(resource, key) ->
Expand All @@ -1658,7 +1664,7 @@ defmodule AshGraphql.Graphql.Resolver do
end)
end

defp massage_filter(_resource, other), do: other
def massage_filter(_resource, other), do: other

defp calc_input(key, value) do
case Map.fetch(value, :input) do
Expand Down
4 changes: 1 addition & 3 deletions lib/resource/resource.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1153,9 +1153,7 @@ defmodule AshGraphql.Resource do
|> subscriptions()
|> Enum.map(fn %Subscription{name: name} = subscription ->
%Absinthe.Blueprint.Schema.FieldDefinition{
arguments:
args(:subscription, resource, nil, schema, nil)
|> IO.inspect(label: "args"),
arguments: args(:subscription, resource, nil, schema, nil),
identifier: name,
name: to_string(name),
config:
Expand Down
2 changes: 2 additions & 0 deletions lib/resource/subscription/actor.ex
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
defmodule AshGraphql.Resource.Subscription.Actor do
# I'd like to have the typespsay that actor can be anything
# but that the input and output must be the same
@callback author(actor :: any) :: actor :: any
end
6 changes: 6 additions & 0 deletions lib/subscription/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ defmodule AshGraphql.Subscription.Config do

actor =
if is_function(@subscription.actor) do
# might be nice to also pass in the subscription, that way you could potentially
# deduplicate on an action basis as well if you wanted to
@subscription.actor.(context[:actor])
else
context[:actor]
Expand All @@ -26,6 +28,10 @@ defmodule AshGraphql.Subscription.Config do
case Ash.can(
@resource
|> Ash.Query.new()
# not sure if we need this here
|> Ash.Query.do_filter(
AshGraphql.Graphql.Resolver.massage_filter(@resource, Map.get(args, :filter))
)
|> Ash.Query.set_tenant(context[:tenant])
|> Ash.Query.for_read(read_action),
actor,
Expand Down
14 changes: 6 additions & 8 deletions lib/subscription/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ defmodule AshGraphql.Subscription.Endpoint do

require Logger

def run_docset(pubsub, docs_and_topics, mutation_result) do
dbg(mutation_result, structs: false)

def run_docset(pubsub, docs_and_topics, notification) do
for {topic, key_strategy, doc} <- docs_and_topics do
try do
pipeline =
Absinthe.Subscription.Local.pipeline(doc, mutation_result.data)
Absinthe.Subscription.Local.pipeline(doc, notification)

{:ok, %{result: data}, _} = Absinthe.Pipeline.run(doc.source, pipeline)

Expand Down Expand Up @@ -43,12 +41,12 @@ defmodule AshGraphql.Subscription.Endpoint do
# return any data we do not send the error to the client
# because it would just expose unnecessary information
# and the user can not really do anything usefull with it
errors
|> List.wrap()
|> Enum.any?(fn error -> Map.get(error, :code) in ["forbidden", "not_found"] end)
not (errors
|> List.wrap()
|> Enum.any?(fn error -> Map.get(error, :code) in ["forbidden", "not_found"] end))
end

defp is_forbidden(_), do: false
defp should_send?(_), do: true

defp get_filter(topic) do
[_, rest] = String.split(topic, "__absinthe__:doc:")
Expand Down
2 changes: 0 additions & 2 deletions lib/subscription/notifier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ defmodule AshGraphql.Subscription.Notifier do
def notify(notification) do
pub_sub = Info.subscription_pubsub(notification.resource)

dbg(notification, structs: false)

for subscription <- AshGraphql.Resource.Info.subscriptions(notification.resource) do
if is_nil(subscription.actions) or
notification.action.name in List.wrap(subscription.actions) do
Expand Down

0 comments on commit 4b51589

Please sign in to comment.