فهرست منبع

feat: repository method to select previous track

Fela Maslen 5 سال پیش
والد
کامیت
9631f26bae
2فایلهای تغییر یافته به همراه99 افزوده شده و 0 حذف شده
  1. 69 0
      gmus-backend/pkg/repository/player.go
  2. 30 0
      gmus-backend/pkg/repository/player_test.go

+ 69 - 0
gmus-backend/pkg/repository/player.go

@@ -70,3 +70,72 @@ func GetNextSongId(db *sqlx.DB, prevSongId int64) (nextSongId int64, err error)
 
 	return
 }
+
+func GetPrevSongId(db *sqlx.DB, nextSongId int64) (prevSongId int64, err error) {
+	err = db.QueryRowx(
+		`
+    select coalesce(id_prev, 0) as id from (
+      select
+        next.track_number, next.title, next.artist, next.album
+          ,coalesce(prev_artist.id, next.id_prev) as id_prev
+      from (
+        select
+          next.track_number, next.title, next.artist, next.album
+            ,coalesce(prev_album.id, next.id_prev) as id_prev
+        from (
+          select
+            next.track_number, next.title, next.artist, next.album
+              ,coalesce(prev_title.id, next.id_prev) as id_prev
+          from (
+            select
+              next.track_number, next.title, next.artist, next.album
+                ,prev_track_number.id as id_prev
+            from (
+              select track_number, title, artist, album from songs
+              where id = $1
+            ) next
+
+            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
+
+            order by prev_track_number.track_number desc
+            limit 1
+
+          ) next
+
+          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
+
+          order by prev_title.title desc
+          limit 1
+
+        ) 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
+
+        order by prev_album.album desc, prev_album.track_number desc, prev_album.title desc
+        limit 1
+      ) next
+
+      left join songs prev_artist on 1=1
+        and next.id_prev is null
+        and prev_artist.artist < next.artist
+
+      order by prev_artist.artist desc, prev_artist.album desc, prev_artist.track_number desc, prev_artist.title desc
+      limit 1
+    ) result
+    `,
+		nextSongId,
+	).Scan(&prevSongId)
+
+	return
+}

+ 30 - 0
gmus-backend/pkg/repository/player_test.go

@@ -85,4 +85,34 @@ var _ = Describe("Player repository", func() {
 			})
 		})
 	})
+
+	Describe("GetPrevSongId", func() {
+		Context("when another song exists in the same album", func() {
+			It("should return the correct song ID", func() {
+				id, _ := repository.GetPrevSongId(db, ids[2])
+				Expect(id).To(Equal(ids[0]))
+			})
+		})
+
+		Context("when another song exists from the same artist", func() {
+			It("should return the correct song ID", func() {
+				id, _ := repository.GetPrevSongId(db, ids[3])
+				Expect(id).To(Equal(ids[2]))
+			})
+		})
+
+		Context("when another song exists by a different artist", func() {
+			It("should return the correct song ID", func() {
+				id, _ := repository.GetPrevSongId(db, ids[1])
+				Expect(id).To(Equal(ids[3]))
+			})
+		})
+
+		Context("when no further songs exist", func() {
+			It("should return zero", func() {
+				id, _ := repository.GetPrevSongId(db, ids[0])
+				Expect(id).To(Equal(int64(0)))
+			})
+		})
+	})
 })