Browse Source

feat: previous / next track handling for tracks without any information

Fela Maslen 5 years ago
parent
commit
b0576b0517

+ 90 - 43
gmus-backend/pkg/repository/player.go

@@ -22,25 +22,47 @@ func GetNextSongId(db *sqlx.DB, prevSongId int64) (nextSongId int64, err error)
     select coalesce(id_next, 0) as id from (
       select
         prev.track_number, prev.title, prev.artist, prev.album
-          ,coalesce(next_artist.id, prev.id_next) as id_next
+          ,coalesce(prev.id_next, next_artist.id) as id_next
       from (
         select
           prev.track_number, prev.title, prev.artist, prev.album
-            ,coalesce(next_album.id, prev.id_next) as id_next
+            ,coalesce(prev.id_next, next_album.id) as id_next
         from (
           select
             prev.track_number, prev.title, prev.artist, prev.album
-              ,coalesce(next_title.id, prev.id_next) as id_next
+              ,coalesce(prev.id_next, next_title.id) as id_next
           from (
             select
               prev.track_number, prev.title, prev.artist, prev.album
-                ,next_track_number.id as id_next
+                ,coalesce(prev.id_next, next_track_number.id) as id_next
             from (
-              select track_number, title, artist, album from songs
-              where id = $1
+              select
+                prev.track_number, prev.title, prev.artist, prev.album
+                  ,next_no_info.id as id_next
+
+              from (
+                select track_number, title, artist, album from songs
+                where id = $1
+              ) prev
+
+              left join songs next_no_info on 1=1
+                and prev.artist = ''
+                and prev.album = ''
+                and next_no_info.id > $1
+
+              order by
+                next_no_info.artist
+                ,next_no_info.album
+                ,next_no_info.track_number
+                ,next_no_info.title
+                ,next_no_info.id
+
+              limit 1
+
             ) prev
 
             left join songs next_track_number on 1=1
+              and prev.id_next is null
               and next_track_number.artist = prev.artist
               and next_track_number.album = prev.album
               and next_track_number.track_number > prev.track_number
@@ -88,64 +110,89 @@ func GetPrevSongId(db *sqlx.DB, nextSongId int64) (prevSongId int64, err error)
 	prevSongId, err = getSongIdOrZero(
 		db,
 		`
-    select coalesce(id_prev, 0) as id from (
+    select coalesce(id_next, 0) as id from (
       select
-        next.track_number, next.title, next.artist, next.album
-          ,coalesce(prev_artist.id, next.id_prev) as id_prev
+        prev.track_number, prev.title, prev.artist, prev.album
+          ,coalesce(prev.id_next, next_no_info.id) as id_next
       from (
         select
-          next.track_number, next.title, next.artist, next.album
-            ,coalesce(prev_album.id, next.id_prev) as id_prev
+          prev.track_number, prev.title, prev.artist, prev.album
+            ,coalesce(prev.id_next, next_artist.id) as id_next
         from (
           select
-            next.track_number, next.title, next.artist, next.album
-              ,coalesce(prev_title.id, next.id_prev) as id_prev
+            prev.track_number, prev.title, prev.artist, prev.album
+              ,coalesce(prev.id_next, next_album.id) as id_next
           from (
             select
-              next.track_number, next.title, next.artist, next.album
-                ,prev_track_number.id as id_prev
+              prev.track_number, prev.title, prev.artist, prev.album
+                ,coalesce(prev.id_next, next_title.id) as id_next
             from (
-              select track_number, title, artist, album from songs
-              where id = $1
-            ) next
+              select
+                prev.track_number, prev.title, prev.artist, prev.album
+                  ,next_track_number.id as id_next
+              from (
+                select track_number, title, artist, album from songs
+                where id = $1
+              ) prev
+
+              left join songs next_track_number on 1=1
+                and next_track_number.artist = prev.artist
+                and next_track_number.album = prev.album
+                and next_track_number.track_number < prev.track_number
+
+              order by next_track_number.track_number desc
+              limit 1
 
-            left join songs prev_track_number on 1=1
-              and prev_track_number.artist = next.artist
-              and prev_track_number.album = next.album
-              and prev_track_number.track_number < next.track_number
+            ) prev
 
-            order by prev_track_number.track_number desc
+            left join songs next_title on 1=1
+              and prev.id_next is null
+              and next_title.artist = prev.artist
+              and next_title.album = prev.album
+              and next_title.track_number is null
+              and next_title.title < prev.title
+
+            order by next_title.title desc
             limit 1
 
-          ) next
+          ) prev
 
-          left join songs prev_title on 1=1
-            and next.id_prev is null
-            and prev_title.artist = next.artist
-            and prev_title.album = next.album
-            and prev_title.track_number is null
-            and prev_title.title < next.title
+          left join songs next_album on 1=1
+            and prev.id_next is null
+            and next_album.artist = prev.artist
+            and next_album.album < prev.album
 
-          order by prev_title.title desc
+          order by
+            next_album.album desc
+            ,next_album.track_number desc
+            ,next_album.title desc
           limit 1
+        ) prev
 
-        ) next
-
-        left join songs prev_album on 1=1
-          and next.id_prev is null
-          and prev_album.artist = next.artist
-          and prev_album.album < next.album
+        left join songs next_artist on 1=1
+          and prev.id_next is null
+          and next_artist.artist < prev.artist
 
-        order by prev_album.album desc, prev_album.track_number desc, prev_album.title desc
+        order by
+          next_artist.artist desc
+          ,next_artist.album desc
+          ,next_artist.track_number desc
+          ,next_artist.title desc
         limit 1
-      ) next
+      ) prev
 
-      left join songs prev_artist on 1=1
-        and next.id_prev is null
-        and prev_artist.artist < next.artist
+      inner join songs from_song on from_song.id = $1
 
-      order by prev_artist.artist desc, prev_artist.album desc, prev_artist.track_number desc, prev_artist.title desc
+      left join songs next_no_info on 1=1
+        and prev.id_next is null
+        and next_no_info.artist = ''
+        and next_no_info.album = ''
+        and next_no_info.id != $1
+        and (from_song.artist != '' or from_song.album != '' or next_no_info.id < $1)
+
+      order by next_no_info.id desc
       limit 1
+
     ) result
     `,
 		nextSongId,

+ 23 - 9
gmus-backend/pkg/repository/player_test.go

@@ -30,14 +30,14 @@ var _ = Describe("Player repository", func() {
         ,relative_path
       )
       select * from unnest(
-        array[1, 1, 2, 4]
-        ,array['T1', 'T2', 'T3', 'T4']
-        ,array['AR1', 'AR2', 'AR1', 'AR1']
-        ,array['AL1', 'AL2', 'AL1', 'AL3']
-        ,array[100, 200, 300, 250]
-        ,array[123, 456, 789, 120]
-        ,array['/music', '/music', '/music', '/music']
-        ,array['file1.ogg', 'file2.ogg', 'file3.ogg', 'file4.ogg']
+        array[1, 1, 2, 4, 0, 0]
+        ,array['T1', 'T2', 'T3', 'T4', '', '']
+        ,array['AR1', 'AR2', 'AR1', 'AR1', '', '']
+        ,array['AL1', 'AL2', 'AL1', 'AL3', '', '']
+        ,array[100, 200, 300, 250, 103, 107]
+        ,array[123, 456, 789, 120, 883, 1443]
+        ,array['/music', '/music', '/music', '/music', '/music', '/music']
+        ,array['file1.ogg', 'file2.ogg', 'file3.ogg', 'file4.ogg', 'file5.ogg', 'file6.ogg']
       )
       returning id
       `,
@@ -85,6 +85,13 @@ var _ = Describe("Player repository", func() {
 			})
 		})
 
+		Context("when the song has no information", func() {
+			It("should return the next song by ID", func() {
+				id, _ := repository.GetNextSongId(db, ids[4])
+				Expect(id).To(Equal(ids[5]))
+			})
+		})
+
 		Context("when the ID does not exist", func() {
 			It("should return nil", func() {
 				id, err := repository.GetNextSongId(db, 10000000)
@@ -117,9 +124,16 @@ var _ = Describe("Player repository", func() {
 			})
 		})
 
+		Context("when the song has no information", func() {
+			It("should return the previous song by ID", func() {
+				id, _ := repository.GetPrevSongId(db, ids[5])
+				Expect(id).To(Equal(ids[4]))
+			})
+		})
+
 		Context("when no further songs exist", func() {
 			It("should return zero", func() {
-				id, _ := repository.GetPrevSongId(db, ids[0])
+				id, _ := repository.GetPrevSongId(db, ids[4])
 				Expect(id).To(Equal(int64(0)))
 			})
 		})

+ 1 - 1
gmus-backend/pkg/repository/songs.go

@@ -96,7 +96,7 @@ func SelectSongsByArtist(db *sqlx.DB, artist string) (songs *[]*read.SongExterna
     ,duration
   from songs
   where artist = $1
-  order by album, track_number, title
+  order by album, track_number, title, id
   `, artist)
 
 	return