Browse Source

First pass at Nostr filters

master
buttercat1791 3 months ago
parent
commit
c69f729843
  1. 56
      lib/gc_index_relay/nostr/filter.ex

56
lib/gc_index_relay/nostr/filter.ex

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
defmodule GcIndexRelay.Nostr.Filter do
alias GcIndexRelay.Repo
import Ecto.Query
@derive [Jason.Encoder]
defstruct [:ids, :authors, :kinds, :tags, :since, :until, :limit]
# TODO: Implement tag filtering
@doc """
Applies a filter to an Ecto query of Nostr events.
## Params
- `query` - An Ecto query. This MUST be a query over the `GcIndexRelay.Nostr.Event` schema.
- `filter` - A `GcIndexRelay.Nostr.Filter` struct.
## Returns
A filtered list of events in descending order of creation time.
"""
def apply(%Ecto.Query{} = query, %__MODULE__{} = filter) do
query
|> apply_ids(filter.ids)
|> apply_authors(filter.authors)
|> apply_kinds(filter.kinds)
|> apply_since(filter.since)
|> apply_until(filter.until)
|> preload(:tags)
# Always sort in descending order of creation time
|> order_by([e], desc: e.created_at)
|> apply_limit(filter.limit)
|> Repo.all()
end
defp apply_ids(query, nil), do: query
defp apply_ids(query, []), do: query
defp apply_ids(query, ids), do: where(query, [e], e.id in ^ids)
defp apply_authors(query, nil), do: query
defp apply_authors(query, []), do: query
defp apply_authors(query, authors), do: where(query, [e], e.author in ^authors)
defp apply_kinds(query, nil), do: query
defp apply_kinds(query, []), do: query
defp apply_kinds(query, kinds), do: where(query, [e], e.kind in ^kinds)
defp apply_since(query, nil), do: query
defp apply_since(query, since), do: where(query, [e], e.created_at >= ^since)
defp apply_until(query, nil), do: query
defp apply_until(query, until), do: where(query, [e], e.created_at <= ^until)
defp apply_limit(query, nil), do: query
defp apply_limit(query, limit), do: limit(query, ^limit)
end
Loading…
Cancel
Save