Quellcode durchsuchen

feat: repository method to query the next song

Fela Maslen vor 5 Jahren
Ursprung
Commit
3234b9cc0a
2 geänderte Dateien mit 160 neuen und 0 gelöschten Zeilen
  1. 72 0
      gmus-backend/pkg/repository/player.go
  2. 88 0
      gmus-backend/pkg/repository/player_test.go

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

@@ -0,0 +1,72 @@
+package repository
+
+import "github.com/jmoiron/sqlx"
+
+func GetNextSongId(db *sqlx.DB, prevSongId int64) (nextSongId int64, err error) {
+	err = db.QueryRowx(
+		`
+    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
+      from (
+        select
+          prev.track_number, prev.title, prev.artist, prev.album
+            ,coalesce(next_album.id, prev.id_next) as id_next
+        from (
+          select
+            prev.track_number, prev.title, prev.artist, prev.album
+              ,coalesce(next_title.id, prev.id_next) as id_next
+          from (
+            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
+            limit 1
+
+          ) prev
+
+          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
+          limit 1
+
+        ) prev
+
+        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 next_album.album, next_album.track_number, next_album.title
+        limit 1
+      ) prev
+
+      left join songs next_artist on 1=1
+        and prev.id_next is null
+        and next_artist.artist > prev.artist
+
+      order by next_artist.artist, next_artist.album, next_artist.track_number, next_artist.title
+      limit 1
+    ) result
+    `,
+		prevSongId,
+	).Scan(&nextSongId)
+
+	return
+}

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

@@ -0,0 +1,88 @@
+package repository_test
+
+import (
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+
+	"github.com/felamaslen/gmus-backend/pkg/database"
+	"github.com/felamaslen/gmus-backend/pkg/repository"
+	"github.com/felamaslen/gmus-backend/pkg/testing"
+)
+
+var _ = Describe("Player repository", func() {
+	db := database.GetConnection()
+
+	var ids []int64
+
+	BeforeEach(func() {
+		testing.PrepareDatabaseForTesting()
+
+		rows, err := db.Queryx(
+			`
+      insert into songs (
+        track_number
+        ,title
+        ,artist
+        ,album
+        ,duration
+        ,modified_date
+        ,base_path
+        ,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']
+      )
+      returning id
+      `,
+		)
+		if err != nil {
+			panic(err)
+		}
+
+		var id int64
+		ids = []int64{}
+
+		for rows.Next() {
+			rows.Scan(&id)
+			ids = append(ids, id)
+		}
+		rows.Close()
+	})
+
+	Describe("GetNextSongId", func() {
+		Context("when another song exists in the same album", func() {
+			It("should return the correct song ID", func() {
+				id, _ := repository.GetNextSongId(db, ids[0])
+				Expect(id).To(Equal(ids[2]))
+			})
+		})
+
+		Context("when another song exists from the same artist", func() {
+			It("should return the correct song ID", func() {
+				id, _ := repository.GetNextSongId(db, ids[2])
+				Expect(id).To(Equal(ids[3]))
+			})
+		})
+
+		Context("when another song exists by a different artist", func() {
+			It("should return the correct song ID", func() {
+				id, _ := repository.GetNextSongId(db, ids[3])
+				Expect(id).To(Equal(ids[1]))
+			})
+		})
+
+		Context("when no further songs exist", func() {
+			It("should return zero", func() {
+				id, _ := repository.GetNextSongId(db, ids[1])
+				Expect(id).To(Equal(int64(0)))
+			})
+		})
+	})
+})