Pipe-friendly builder for RSQL filter expressions, accepted by the filter
parameter of the catalog and scrobble-feed queries
(app.rocksky.song.getSongs, app.rocksky.artist.getArtists,
app.rocksky.album.getAlbums, app.rocksky.scrobble.getScrobbles).
alias Rocksky.Filter
Filter.eq(:artist, "Daft Punk")
|> Filter.and_(Filter.gt(:duration, 200_000))
|> Filter.or_(Filter.is_in(:genre, ["house", "electro"]))
|> Filter.build()
# => artist=="Daft Punk";duration=gt=200000,genre=in=(house,electro)Fields are atoms — :artist, or :"track.artist" for the dotted selectors of
the scrobble feed — though binaries are accepted too. String values are quoted
and escaped automatically when they contain characters RSQL reserves; *
wildcards pass through unquoted, so Filter.eq(:artist, "Daft*") performs a
case-insensitive match.
and, or and in are reserved in Elixir, hence and_/2, or_/2,
is_in/2 and is_out/2.
Summary
Types
A filterable field, as an atom (:artist, :"track.artist") or binary.
An RSQL filter node: a comparison, or an ;/, combination.
A comparable value: string, number or boolean.
Functions
Both sides must match (;). An or operand is parenthesized to keep RSQL
precedence. Pipe-first: a |> Filter.and_(b).
The RSQL expression string to send as the filter query param. Also accepts
a plain binary (identity), so query functions can take either.
field==value — equals; * in string values is a wildcard.
field=ge=value — greater than or equal.
field=gt=value — greater than.
field=in=(a,b) — matches any of the values. Raises ArgumentError on an
empty list.
field!=null — the field is not NULL.
field==null — the field is NULL.
field=out=(a,b) — matches none of the values. Raises ArgumentError on an
empty list.
field=le=value — less than or equal.
field=lt=value — less than.
field!=value — not equals.
Either side may match (,). Pipe-first: a |> Filter.or_(b).
Types
A filterable field, as an atom (:artist, :"track.artist") or binary.
@type t() :: %Rocksky.Filter{expr: String.t(), kind: :comparison | :and | :or}
An RSQL filter node: a comparison, or an ;/, combination.
A comparable value: string, number or boolean.
Functions
Both sides must match (;). An or operand is parenthesized to keep RSQL
precedence. Pipe-first: a |> Filter.and_(b).
iex> Rocksky.Filter.eq(:artist, "Radiohead")
...> |> Rocksky.Filter.and_(Rocksky.Filter.gt(:duration, 200_000))
...> |> Rocksky.Filter.build()
"artist==Radiohead;duration=gt=200000"
The RSQL expression string to send as the filter query param. Also accepts
a plain binary (identity), so query functions can take either.
iex> Rocksky.Filter.build("artist==Radiohead")
"artist==Radiohead"
field==value — equals; * in string values is a wildcard.
iex> Rocksky.Filter.eq(:artist, "Radiohead") |> Rocksky.Filter.build()
"artist==Radiohead"
iex> Rocksky.Filter.eq(:artist, "Daft Punk") |> Rocksky.Filter.build()
"artist==\"Daft Punk\""
field=ge=value — greater than or equal.
iex> Rocksky.Filter.ge(:year, 2000) |> Rocksky.Filter.build()
"year=ge=2000"
field=gt=value — greater than.
iex> Rocksky.Filter.gt(:duration, 200_000) |> Rocksky.Filter.build()
"duration=gt=200000"
field=in=(a,b) — matches any of the values. Raises ArgumentError on an
empty list.
iex> Rocksky.Filter.is_in(:genre, ["house", "electro"]) |> Rocksky.Filter.build()
"genre=in=(house,electro)"
field!=null — the field is not NULL.
iex> Rocksky.Filter.is_not_null(:uri) |> Rocksky.Filter.build()
"uri!=null"
field==null — the field is NULL.
iex> Rocksky.Filter.is_null(:uri) |> Rocksky.Filter.build()
"uri==null"
field=out=(a,b) — matches none of the values. Raises ArgumentError on an
empty list.
iex> Rocksky.Filter.is_out(:genre, ["rock"]) |> Rocksky.Filter.build()
"genre=out=(rock)"
field=le=value — less than or equal.
iex> Rocksky.Filter.le(:year, 1999) |> Rocksky.Filter.build()
"year=le=1999"
field=lt=value — less than.
iex> Rocksky.Filter.lt(:trackNumber, 5) |> Rocksky.Filter.build()
"trackNumber=lt=5"
field!=value — not equals.
iex> Rocksky.Filter.ne(:artist, "Eminem") |> Rocksky.Filter.build()
"artist!=Eminem"
Either side may match (,). Pipe-first: a |> Filter.or_(b).
iex> Rocksky.Filter.eq(:artist, "Radiohead")
...> |> Rocksky.Filter.or_(Rocksky.Filter.eq(:artist, "Muse"))
...> |> Rocksky.Filter.build()
"artist==Radiohead,artist==Muse"