@@ -75,6 +75,47 @@ defmodule MusicLibrary.Artists do
|
|||||||
|> Enum.into(%{})
|
|> Enum.into(%{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec search_by_name(String.t(), non_neg_integer()) :: [map()]
|
||||||
|
def search_by_name(query, limit) do
|
||||||
|
case String.trim(query) do
|
||||||
|
"" ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
trimmed_query ->
|
||||||
|
normalized_query = String.downcase(trimmed_query)
|
||||||
|
|
||||||
|
from(ar in ArtistRecord,
|
||||||
|
join: ai in ArtistInfo,
|
||||||
|
on: ar.musicbrainz_id == ai.id,
|
||||||
|
where:
|
||||||
|
fragment("lower(unaccent(artist ->> '$.name')) LIKE ?", ^"%#{normalized_query}%"),
|
||||||
|
group_by: ar.musicbrainz_id,
|
||||||
|
select: %{artist: ar.artist, image_data_hash: ai.image_data_hash},
|
||||||
|
limit: ^limit,
|
||||||
|
order_by: fragment("artist ->> '$.name'")
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec search_by_name_count(String.t()) :: non_neg_integer()
|
||||||
|
def search_by_name_count(query) do
|
||||||
|
case String.trim(query) do
|
||||||
|
"" ->
|
||||||
|
0
|
||||||
|
|
||||||
|
trimmed_query ->
|
||||||
|
normalized_query = String.downcase(trimmed_query)
|
||||||
|
|
||||||
|
from(ar in ArtistRecord,
|
||||||
|
where: fragment("lower(artist ->> '$.name') LIKE ?", ^"%#{normalized_query}%"),
|
||||||
|
select: ar.musicbrainz_id,
|
||||||
|
distinct: true
|
||||||
|
)
|
||||||
|
|> Repo.aggregate(:count, :musicbrainz_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@spec exists?(String.t()) :: boolean()
|
@spec exists?(String.t()) :: boolean()
|
||||||
def exists?(artist_id) do
|
def exists?(artist_id) do
|
||||||
q =
|
q =
|
||||||
|
|||||||
@@ -8,11 +8,7 @@ defmodule MusicLibrary.Search do
|
|||||||
- Artists
|
- Artists
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Ecto.Query, warn: false
|
alias MusicLibrary.{Artists, Collection, RecordSets, Wishlist}
|
||||||
|
|
||||||
alias MusicLibrary.Artists.ArtistInfo
|
|
||||||
alias MusicLibrary.{Collection, RecordSets, Repo, Wishlist}
|
|
||||||
alias MusicLibrary.Records.ArtistRecord
|
|
||||||
|
|
||||||
@pagination Application.compile_env!(:music_library, :pagination)
|
@pagination Application.compile_env!(:music_library, :pagination)
|
||||||
|
|
||||||
@@ -62,26 +58,7 @@ defmodule MusicLibrary.Search do
|
|||||||
"""
|
"""
|
||||||
@spec search_artists(String.t(), non_neg_integer()) :: [map()]
|
@spec search_artists(String.t(), non_neg_integer()) :: [map()]
|
||||||
def search_artists(query, limit \\ @pagination[:search_preview_limit]) do
|
def search_artists(query, limit \\ @pagination[:search_preview_limit]) do
|
||||||
case String.trim(query) do
|
Artists.search_by_name(query, limit)
|
||||||
"" ->
|
|
||||||
[]
|
|
||||||
|
|
||||||
trimmed_query ->
|
|
||||||
normalized_query = String.downcase(trimmed_query)
|
|
||||||
|
|
||||||
q =
|
|
||||||
from ar in ArtistRecord,
|
|
||||||
join: ai in ArtistInfo,
|
|
||||||
on: ar.musicbrainz_id == ai.id,
|
|
||||||
where:
|
|
||||||
fragment("lower(unaccent(artist ->> '$.name')) LIKE ?", ^"%#{normalized_query}%"),
|
|
||||||
group_by: ar.musicbrainz_id,
|
|
||||||
select: %{artist: ar.artist, image_data_hash: ai.image_data_hash},
|
|
||||||
limit: ^limit,
|
|
||||||
order_by: fragment("artist ->> '$.name'")
|
|
||||||
|
|
||||||
Repo.all(q)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
@@ -115,25 +92,6 @@ defmodule MusicLibrary.Search do
|
|||||||
"""
|
"""
|
||||||
@spec search_artists_count(String.t()) :: non_neg_integer()
|
@spec search_artists_count(String.t()) :: non_neg_integer()
|
||||||
def search_artists_count(query) do
|
def search_artists_count(query) do
|
||||||
case String.trim(query) do
|
Artists.search_by_name_count(query)
|
||||||
"" ->
|
|
||||||
0
|
|
||||||
|
|
||||||
trimmed_query ->
|
|
||||||
normalized_query = String.downcase(trimmed_query)
|
|
||||||
|
|
||||||
# Use a subquery to count distinct musicbrainz_ids
|
|
||||||
subquery =
|
|
||||||
from ar in ArtistRecord,
|
|
||||||
where: fragment("lower(artist ->> '$.name') LIKE ?", ^"%#{normalized_query}%"),
|
|
||||||
select: ar.musicbrainz_id,
|
|
||||||
distinct: true
|
|
||||||
|
|
||||||
q =
|
|
||||||
from s in subquery(subquery),
|
|
||||||
select: count()
|
|
||||||
|
|
||||||
Repo.one(q) || 0
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -31,6 +31,57 @@ defmodule MusicLibrary.ArtistsTest do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "search_by_name/2" do
|
||||||
|
test "returns artists matching the query" do
|
||||||
|
record = record_with_artist("Marillion")
|
||||||
|
[artist] = record.artists
|
||||||
|
artist_info(artist.musicbrainz_id)
|
||||||
|
|
||||||
|
results = Artists.search_by_name("Marillion", 10)
|
||||||
|
|
||||||
|
assert length(results) == 1
|
||||||
|
assert hd(results).artist.name == "Marillion"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns empty list for empty query" do
|
||||||
|
assert Artists.search_by_name("", 10) == []
|
||||||
|
assert Artists.search_by_name(" ", 10) == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "respects limit" do
|
||||||
|
for name <- ["Marillion", "Steven Wilson"] do
|
||||||
|
record = record_with_artist(name)
|
||||||
|
[artist] = record.artists
|
||||||
|
artist_info(artist.musicbrainz_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
results = Artists.search_by_name("i", 1)
|
||||||
|
|
||||||
|
assert length(results) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "search_by_name_count/1" do
|
||||||
|
test "returns count of matching artists" do
|
||||||
|
record = record_with_artist("Marillion")
|
||||||
|
_other = record_with_artist("Marillion")
|
||||||
|
|
||||||
|
[artist] = record.artists
|
||||||
|
artist_info(artist.musicbrainz_id)
|
||||||
|
|
||||||
|
assert Artists.search_by_name_count("Marillion") == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 0 for empty query" do
|
||||||
|
assert Artists.search_by_name_count("") == 0
|
||||||
|
assert Artists.search_by_name_count(" ") == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 0 for no matches" do
|
||||||
|
assert Artists.search_by_name_count("zzz_nonexistent_zzz") == 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "fetch_artist_info/1" do
|
describe "fetch_artist_info/1" do
|
||||||
test "it stores musicbrainz and discogs data" do
|
test "it stores musicbrainz and discogs data" do
|
||||||
steven_wilson_musicbrainz_id = "3a51b862-0144-40f6-aa17-6aaeefea29d9"
|
steven_wilson_musicbrainz_id = "3a51b862-0144-40f6-aa17-6aaeefea29d9"
|
||||||
|
|||||||
Reference in New Issue
Block a user