diff --git a/db/migrations/20260104203627_playlist_case_insensitive_name.sql b/db/migrations/20260104203627_playlist_case_insensitive_name.sql new file mode 100644 index 00000000..64b079cc --- /dev/null +++ b/db/migrations/20260104203627_playlist_case_insensitive_name.sql @@ -0,0 +1,99 @@ +-- +goose Up +-- Fix case-insensitive sorting for playlist names +create table playlist_dg_tmp +( + id varchar(255) not null + primary key, + name varchar(255) collate NOCASE default '' not null, + comment varchar(255) default '' not null, + duration real default 0 not null, + song_count integer default 0 not null, + public bool default FALSE not null, + created_at datetime, + updated_at datetime, + path string default '' not null, + sync bool default false not null, + size integer default 0 not null, + rules varchar, + evaluated_at datetime, + owner_id varchar(255) not null + constraint playlist_user_user_id_fk + references user + on update cascade on delete cascade +); + +insert into playlist_dg_tmp(id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size, + rules, evaluated_at, owner_id) +select id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size, rules, evaluated_at, + owner_id +from playlist; + +drop table playlist; + +alter table playlist_dg_tmp + rename to playlist; + +create index playlist_name + on playlist (name); + +create index playlist_created_at + on playlist (created_at); + +create index playlist_updated_at + on playlist (updated_at); + +create index playlist_evaluated_at + on playlist (evaluated_at); + +create index playlist_size + on playlist (size); + +-- +goose Down +-- Note: Downgrade loses the collation but preserves data +create table playlist_dg_tmp +( + id varchar(255) not null + primary key, + name varchar(255) default '' not null, + comment varchar(255) default '' not null, + duration real default 0 not null, + song_count integer default 0 not null, + public bool default FALSE not null, + created_at datetime, + updated_at datetime, + path string default '' not null, + sync bool default false not null, + size integer default 0 not null, + rules varchar, + evaluated_at datetime, + owner_id varchar(255) not null + constraint playlist_user_user_id_fk + references user + on update cascade on delete cascade +); + +insert into playlist_dg_tmp(id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size, + rules, evaluated_at, owner_id) +select id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size, rules, evaluated_at, + owner_id +from playlist; + +drop table playlist; + +alter table playlist_dg_tmp + rename to playlist; + +create index playlist_name + on playlist (name); + +create index playlist_created_at + on playlist (created_at); + +create index playlist_updated_at + on playlist (updated_at); + +create index playlist_evaluated_at + on playlist (evaluated_at); + +create index playlist_size + on playlist (size); diff --git a/persistence/collation_test.go b/persistence/collation_test.go index 7e114475..bb127657 100644 --- a/persistence/collation_test.go +++ b/persistence/collation_test.go @@ -32,6 +32,7 @@ var _ = Describe("Collation", func() { Entry("media_file.sort_title", "media_file", "sort_title"), Entry("media_file.sort_album_name", "media_file", "sort_album_name"), Entry("media_file.sort_artist_name", "media_file", "sort_artist_name"), + Entry("playlist.name", "playlist", "name"), Entry("radio.name", "radio", "name"), Entry("user.name", "user", "name"), ) @@ -53,6 +54,7 @@ var _ = Describe("Collation", func() { Entry("media_file.sort_album_name", "media_file", "coalesce(nullif(sort_album_name,''),order_album_name) collate nocase"), Entry("media_file.sort_artist_name", "media_file", "coalesce(nullif(sort_artist_name,''),order_artist_name) collate nocase"), Entry("media_file.path", "media_file", "path collate nocase"), + Entry("playlist.name", "playlist", "name collate nocase"), Entry("radio.name", "radio", "name collate nocase"), Entry("user.user_name", "user", "user_name collate nocase"), ) diff --git a/ui/src/playlist/PlaylistList.jsx b/ui/src/playlist/PlaylistList.jsx index c1856675..eae9d863 100644 --- a/ui/src/playlist/PlaylistList.jsx +++ b/ui/src/playlist/PlaylistList.jsx @@ -170,6 +170,7 @@ const PlaylistList = (props) => { } actions={} bulkActionButtons={!isXsmall && }