1 changed files with 56 additions and 0 deletions
@ -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…
Reference in new issue