Can filter records by release year
This commit is contained in:
@@ -157,6 +157,10 @@ defmodule MusicLibrary.Records do
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
{:release_year, year}, search ->
|
||||||
|
search
|
||||||
|
|> where([r], fragment("substr(?, 1, 4) = ?", r.release_date, ^to_string(year)))
|
||||||
|
|
||||||
{:query, ""}, search ->
|
{:query, ""}, search ->
|
||||||
search
|
search
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
- `format:value` — filter by format (e.g. `cd`, `vinyl`)
|
- `format:value` — filter by format (e.g. `cd`, `vinyl`)
|
||||||
- `type:value` — filter by type (e.g. `album`, `single`)
|
- `type:value` — filter by type (e.g. `album`, `single`)
|
||||||
- `purchase_year:YYYY` — filter by purchase year
|
- `purchase_year:YYYY` — filter by purchase year
|
||||||
|
- `release_year:YYYY` — filter by release year
|
||||||
|
|
||||||
Multi-word values can be quoted: `artist:"the pineapple thief"`.
|
Multi-word values can be quoted: `artist:"the pineapple thief"`.
|
||||||
Unrecognized format/type values are silently ignored.
|
Unrecognized format/type values are silently ignored.
|
||||||
@@ -25,7 +26,8 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
optional(:genre) => String.t(),
|
optional(:genre) => String.t(),
|
||||||
optional(:format) => atom(),
|
optional(:format) => atom(),
|
||||||
optional(:type) => atom(),
|
optional(:type) => atom(),
|
||||||
optional(:purchase_year) => integer()
|
optional(:purchase_year) => integer(),
|
||||||
|
optional(:release_year) => integer()
|
||||||
}
|
}
|
||||||
|
|
||||||
import NimbleParsec
|
import NimbleParsec
|
||||||
@@ -54,6 +56,9 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
purchase_year_filter = ignore(string("purchase_year:"))
|
purchase_year_filter = ignore(string("purchase_year:"))
|
||||||
purchase_year = concat(purchase_year_filter, year) |> tag(:purchase_year)
|
purchase_year = concat(purchase_year_filter, year) |> tag(:purchase_year)
|
||||||
|
|
||||||
|
release_year_filter = ignore(string("release_year:"))
|
||||||
|
release_year = concat(release_year_filter, year) |> tag(:release_year)
|
||||||
|
|
||||||
genre_filter = ignore(string("genre:"))
|
genre_filter = ignore(string("genre:"))
|
||||||
genre = concat(genre_filter, query) |> tag(:genre)
|
genre = concat(genre_filter, query) |> tag(:genre)
|
||||||
|
|
||||||
@@ -86,7 +91,21 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
|> tag(:type)
|
|> tag(:type)
|
||||||
|
|
||||||
search =
|
search =
|
||||||
repeat(choice([artist, album, mbid, genre, space, comma, format, type, purchase_year, query]))
|
repeat(
|
||||||
|
choice([
|
||||||
|
artist,
|
||||||
|
album,
|
||||||
|
mbid,
|
||||||
|
genre,
|
||||||
|
space,
|
||||||
|
comma,
|
||||||
|
format,
|
||||||
|
type,
|
||||||
|
purchase_year,
|
||||||
|
release_year,
|
||||||
|
query
|
||||||
|
])
|
||||||
|
)
|
||||||
|
|
||||||
defparsecp(:search_parser, search)
|
defparsecp(:search_parser, search)
|
||||||
|
|
||||||
@@ -123,6 +142,8 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
{:ok, %{type: :album}}
|
{:ok, %{type: :album}}
|
||||||
iex> MusicLibrary.Records.SearchParser.parse("purchase_year:2024")
|
iex> MusicLibrary.Records.SearchParser.parse("purchase_year:2024")
|
||||||
{:ok, %{purchase_year: 2024}}
|
{:ok, %{purchase_year: 2024}}
|
||||||
|
iex> MusicLibrary.Records.SearchParser.parse("release_year:2024")
|
||||||
|
{:ok, %{release_year: 2024}}
|
||||||
"""
|
"""
|
||||||
@spec parse(String.t()) :: {:ok, search_result()}
|
@spec parse(String.t()) :: {:ok, search_result()}
|
||||||
def parse(""), do: {:ok, %{query: ""}}
|
def parse(""), do: {:ok, %{query: ""}}
|
||||||
@@ -168,6 +189,9 @@ defmodule MusicLibrary.Records.SearchParser do
|
|||||||
{:purchase_year, [{:year, [value]}]}, acc ->
|
{:purchase_year, [{:year, [value]}]}, acc ->
|
||||||
Map.put(acc, :purchase_year, value)
|
Map.put(acc, :purchase_year, value)
|
||||||
|
|
||||||
|
{:release_year, [{:year, [value]}]}, acc ->
|
||||||
|
Map.put(acc, :release_year, value)
|
||||||
|
|
||||||
{:query, [value]}, acc ->
|
{:query, [value]}, acc ->
|
||||||
Map.update(acc, :query, value, &(&1 <> " " <> value))
|
Map.update(acc, :query, value, &(&1 <> " " <> value))
|
||||||
|
|
||||||
|
|||||||
@@ -229,6 +229,26 @@ defmodule MusicLibrary.CollectionTest do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "search_records/2 with release_year" do
|
||||||
|
test "filters by release year" do
|
||||||
|
record_with_artist("Artist A", %{
|
||||||
|
title: "Album 1994",
|
||||||
|
release_date: "1994-09-13",
|
||||||
|
purchased_at: ~U[2024-12-27 16:50:57Z]
|
||||||
|
})
|
||||||
|
|
||||||
|
record_with_artist("Artist B", %{
|
||||||
|
title: "Album 2020",
|
||||||
|
release_date: "2020",
|
||||||
|
purchased_at: ~U[2024-12-28 16:50:57Z]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert [%{title: "Album 1994"}] = Collection.search_records("release_year:1994")
|
||||||
|
assert [%{title: "Album 2020"}] = Collection.search_records("release_year:2020")
|
||||||
|
assert [] = Collection.search_records("release_year:2000")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "collected_artist_ids/0" do
|
describe "collected_artist_ids/0" do
|
||||||
setup [:fill_collection]
|
setup [:fill_collection]
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,17 @@ defmodule MusicLibrary.WishlistTest do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "search_records/2 with release_year" do
|
||||||
|
test "filters by release year" do
|
||||||
|
record(%{purchased_at: nil, title: "Album 1994", release_date: "1994-09-13"})
|
||||||
|
record(%{purchased_at: nil, title: "Album 2020", release_date: "2020"})
|
||||||
|
|
||||||
|
assert [%{title: "Album 1994"}] = Wishlist.search_records("release_year:1994")
|
||||||
|
assert [%{title: "Album 2020"}] = Wishlist.search_records("release_year:2020")
|
||||||
|
assert [] = Wishlist.search_records("release_year:2000")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "count/0" do
|
describe "count/0" do
|
||||||
setup [:fill_wishlist]
|
setup [:fill_wishlist]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user