Make purchase order deterministic
Avoids ordering issues when records have the same purchased_at datetime (which is what happens when they're scanned in batches).
This commit is contained in:
@@ -5,6 +5,8 @@ defmodule MusicLibrary.Collection do
|
|||||||
alias MusicLibrary.Records.{Record, SearchIndex}
|
alias MusicLibrary.Records.{Record, SearchIndex}
|
||||||
alias MusicLibrary.Repo
|
alias MusicLibrary.Repo
|
||||||
|
|
||||||
|
import MusicLibrary.Records, only: [order_alphabetically: 0]
|
||||||
|
|
||||||
def search_records(query, opts \\ []) do
|
def search_records(query, opts \\ []) do
|
||||||
limit = Keyword.get(opts, :limit, 20)
|
limit = Keyword.get(opts, :limit, 20)
|
||||||
offset = Keyword.get(opts, :offset, 0)
|
offset = Keyword.get(opts, :offset, 0)
|
||||||
@@ -43,7 +45,7 @@ defmodule MusicLibrary.Collection do
|
|||||||
q =
|
q =
|
||||||
from r in Record,
|
from r in Record,
|
||||||
where: not is_nil(r.purchased_at),
|
where: not is_nil(r.purchased_at),
|
||||||
order_by: [desc: r.purchased_at],
|
order_by: [{:desc, r.purchased_at}, order_alphabetically()],
|
||||||
limit: 1,
|
limit: 1,
|
||||||
select: ^Records.essential_fields()
|
select: ^Records.essential_fields()
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ defmodule MusicLibrary.Records do
|
|||||||
Repo.aggregate(search, :count)
|
Repo.aggregate(search, :count)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defmacro order_alphabetically do
|
||||||
|
quote do
|
||||||
|
fragment(
|
||||||
|
"unaccent(json_extract(artists, '$[0].sort_name')) COLLATE NOCASE ASC, unaccent(title) COLLATE NOCASE ASC"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp build_search(initial_search, query, order \\ :alphabetical) do
|
defp build_search(initial_search, query, order \\ :alphabetical) do
|
||||||
{:ok, parsed_query} = SearchParser.parse(query)
|
{:ok, parsed_query} = SearchParser.parse(query)
|
||||||
|
|
||||||
@@ -54,15 +62,14 @@ defmodule MusicLibrary.Records do
|
|||||||
case order do
|
case order do
|
||||||
:alphabetical ->
|
:alphabetical ->
|
||||||
initial_search
|
initial_search
|
||||||
|> order_by(
|
|> order_by(order_alphabetically())
|
||||||
fragment(
|
|
||||||
"unaccent(json_extract(artists, '$[0].sort_name')) COLLATE NOCASE ASC, unaccent(title) COLLATE NOCASE ASC"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:purchase ->
|
:purchase ->
|
||||||
initial_search
|
initial_search
|
||||||
|> order_by([r], {:desc, r.purchased_at})
|
|> order_by([r], [
|
||||||
|
{:desc, r.purchased_at},
|
||||||
|
order_alphabetically()
|
||||||
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
Enum.reduce(parsed_query, search_with_order, fn
|
Enum.reduce(parsed_query, search_with_order, fn
|
||||||
|
|||||||
Reference in New Issue
Block a user