mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-15 00:42:54 +01:00
library: share the artist credit membership queries
The artist page, shuffle, download attribution and artist badge each spelled out the four credit paths. Reuse the shared credited song and album rows, and keep only the download-aware album queries hand-written, where the per-credit download visibility genuinely differs. The shared song and album rows use UNION ALL so the artist list filter can push its artist predicate into every branch instead of materialising a deduplicated union; callers that need a set use DISTINCT or COUNT(DISTINCT).
This commit is contained in:
@@ -857,6 +857,25 @@ class LibraryDaoTest {
|
||||
assertTrue(dao.searchSongs(sourceId, "ga", 50).first().isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun theArtistPageAlbumQueryFindsArtistCreditsThroughArtistIndexes() =
|
||||
runTest {
|
||||
val plan =
|
||||
plan(
|
||||
"SELECT albums.* FROM (SELECT DISTINCT albumId FROM ($CREDITED_ALBUM_ROWS) " +
|
||||
"WHERE artistId = :artistId) credits " +
|
||||
"JOIN albums ON albums.sourceId = :sourceId AND albums.id = credits.albumId " +
|
||||
"ORDER BY year DESC, sortName COLLATE NOCASE, id",
|
||||
)
|
||||
|
||||
assertTrue(plan, plan.contains("index_albums_sourceId_artistId"))
|
||||
assertTrue(plan, plan.contains("index_album_artists_sourceId_artistId"))
|
||||
assertTrue(plan, plan.contains("index_songs_sourceId_artistId"))
|
||||
assertTrue(plan, plan.contains("index_song_artists_sourceId_artistId"))
|
||||
assertFalse(plan, plan.contains("SCAN albums"))
|
||||
assertFalse(plan, plan.contains("SCAN songs"))
|
||||
}
|
||||
|
||||
private suspend fun plan(sql: String): String =
|
||||
db.useReaderConnection { connection ->
|
||||
connection.usePrepared("EXPLAIN QUERY PLAN $sql") { statement ->
|
||||
|
||||
@@ -1636,6 +1636,68 @@ class SyncServiceTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun everyArtistConsumerAgreesOnTheCreditedSet() =
|
||||
runTest {
|
||||
insertSource()
|
||||
val source =
|
||||
FakeMusicSource(
|
||||
artists = listOf(artist("a1", "Album Artist"), artist("a2", "Guest"), artist("a3", "Track Only")),
|
||||
albums =
|
||||
listOf(
|
||||
album("al1").copy(artistId = "a1", artists = listOf(ArtistRef("a1", "Album Artist"))),
|
||||
album("al2").copy(artistId = "a2", artists = listOf(ArtistRef("a2", "Guest"))),
|
||||
),
|
||||
songs =
|
||||
listOf(
|
||||
song("s1").copy(
|
||||
albumId = "al1",
|
||||
artistId = "a1",
|
||||
artists = listOf(ArtistRef("a1", "Album Artist"), ArtistRef("a2", "Guest")),
|
||||
playCount = 1,
|
||||
played = 100,
|
||||
),
|
||||
song("s2").copy(
|
||||
albumId = "al1",
|
||||
artistId = "a2",
|
||||
artists = listOf(ArtistRef("a2", "Guest"), ArtistRef("a3", "Track Only")),
|
||||
),
|
||||
song("s3").copy(
|
||||
albumId = null,
|
||||
artistId = "a3",
|
||||
artists = listOf(ArtistRef("a3", "Track Only")),
|
||||
),
|
||||
song("s4").copy(
|
||||
albumId = "missing",
|
||||
artistId = "a2",
|
||||
artists = listOf(ArtistRef("a2", "Guest")),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
SyncService(db, source).sync()
|
||||
db.downloadDao().upsert(SongDownload(1, "s1", DownloadStatus.Completed))
|
||||
db.downloadDao().upsert(SongDownload(1, "s3", DownloadStatus.Completed))
|
||||
|
||||
for (artistId in listOf("a1", "a2", "a3")) {
|
||||
val artist = db.libraryDao().artistOnce(1, artistId)!!
|
||||
val songIds = db.queueDao().artistSongIds(1, artistId)
|
||||
val albums = db.libraryDao().albumsForArtist(1, artistId).first()
|
||||
val status = db.downloadDao().artistStatus(1, artistId).first()
|
||||
val downloaded =
|
||||
db
|
||||
.downloadDao()
|
||||
.all()
|
||||
.count { it.status == DownloadStatus.Completed && it.songId in songIds }
|
||||
|
||||
assertEquals("$artistId albums", albums.size.toLong(), artist.albumCount)
|
||||
assertEquals("$artistId songs", songIds.size.toLong(), artist.songCount)
|
||||
assertEquals("$artistId length", songIds.size.toLong(), db.queueDao().artistLength(1, artistId))
|
||||
assertEquals("$artistId total", songIds.size.toLong(), status.total)
|
||||
assertEquals("$artistId downloaded", downloaded.toLong(), status.downloaded)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changingOnlyTheLeadArtistRecomputesTheCreditedCounts() =
|
||||
runTest {
|
||||
|
||||
Reference in New Issue
Block a user