library: route the rediscover list through the download-free query too

Also assert the default pager still observes album writes and cover the
quoted-search path.
This commit is contained in:
austinried
2026-10-04 00:30:07 +00:00
parent c2acbd0eae
commit ea74fce758
5 changed files with 48 additions and 24 deletions
@@ -677,15 +677,6 @@ interface LibraryDao {
downloadedFilter: Int = 0,
): PagingSource<Int, Playlist>
@Query("SELECT * $ALBUMS_FILTER AND played IS NOT NULL AND played < :cutoff ORDER BY played ASC, name COLLATE NOCASE, id")
fun albumsByRediscover(
sourceId: Long,
starredFilter: Int,
search: String,
cutoff: Long,
downloadedFilter: Int = 0,
): PagingSource<Int, Album>
@Query("SELECT * FROM albums WHERE sourceId = :sourceId AND played IS NOT NULL ORDER BY played DESC, name COLLATE NOCASE, id")
fun homeRecentlyPlayedAlbums(sourceId: Long): PagingSource<Int, Album>
@@ -1,6 +1,7 @@
package com.subtracks.data.db
import androidx.room3.RoomRawQuery
import androidx.sqlite.SQLiteStatement
import com.subtracks.data.prefs.AlbumSort
import com.subtracks.data.prefs.ArtistSort
import com.subtracks.data.prefs.PlaylistSort
@@ -40,19 +41,41 @@ internal fun albumsDefaultQuery(
): RoomRawQuery {
val order = albumOrder(sort, descending)
return RoomRawQuery("SELECT * $ALBUMS_FILTER_BASE ORDER BY $order") { stmt ->
stmt.bindLong(1, sourceId)
stmt.bindInt(2, starredFilter)
stmt.bindInt(3, starredFilter)
stmt.bindInt(4, starredFilter)
stmt.bindText(5, search)
stmt.bindText(6, search)
stmt.bindText(7, search)
stmt.bindText(8, search)
stmt.bindText(9, search)
stmt.bindText(10, search)
stmt.bindAlbumFilters(sourceId, starredFilter, search)
}
}
internal fun rediscoverAlbumsQuery(
sourceId: Long,
starredFilter: Int,
search: String,
cutoff: Long,
): RoomRawQuery =
RoomRawQuery(
"SELECT * $ALBUMS_FILTER_BASE AND played IS NOT NULL AND played < ? " +
"ORDER BY played ASC, name COLLATE NOCASE, id",
) { stmt ->
stmt.bindAlbumFilters(sourceId, starredFilter, search)
stmt.bindLong(11, cutoff)
}
private fun SQLiteStatement.bindAlbumFilters(
sourceId: Long,
starredFilter: Int,
search: String,
) {
bindLong(1, sourceId)
bindInt(2, starredFilter)
bindInt(3, starredFilter)
bindInt(4, starredFilter)
bindText(5, search)
bindText(6, search)
bindText(7, search)
bindText(8, search)
bindText(9, search)
bindText(10, search)
}
internal fun artistsDefaultQuery(
sourceId: Long,
starredFilter: Int,
@@ -8,6 +8,7 @@ import com.subtracks.data.db.SubtracksDatabase
import com.subtracks.data.db.albumsDefaultQuery
import com.subtracks.data.db.artistsDefaultQuery
import com.subtracks.data.db.playlistsDefaultQuery
import com.subtracks.data.db.rediscoverAlbumsQuery
import com.subtracks.data.model.Album
import com.subtracks.data.model.AlbumSongItem
import com.subtracks.data.model.Artist
@@ -87,7 +88,9 @@ class LibraryRepository(
fun decades(sourceId: Long): Flow<List<Long>> = db.libraryDao().decades(sourceId)
fun rediscoverAlbumsPage(sourceId: Long): Flow<PagingData<Album>> =
pager(40) { db.libraryDao().albumsByRediscover(sourceId, starredFilter = 0, search = "", cutoff = rediscoverCutoff()) }
pager(
40,
) { db.libraryDao().albumsPaging(rediscoverAlbumsQuery(sourceId, starredFilter = 0, search = "", cutoff = rediscoverCutoff())) }
fun starredSongs(sourceId: Long): Flow<PagingData<AlbumSongItem>> = pager(60) { db.libraryDao().starredSongs(sourceId) }
@@ -150,10 +153,10 @@ class LibraryRepository(
): Flow<PagingData<Album>> =
pager(40) {
val dao = db.libraryDao()
val downloadedFilter = if (downloaded) 1 else 0
if (!downloaded) {
dao.albumsPaging(albumsDefaultQuery(sourceId, starred.ordinal, search, sort, descending))
} else {
val downloadedFilter = 1
when (sort) {
AlbumSort.Name -> {
if (descending) {
@@ -224,10 +227,10 @@ class LibraryRepository(
): Flow<PagingData<Artist>> =
pager(60) {
val dao = db.libraryDao()
val downloadedFilter = if (downloaded) 1 else 0
if (!downloaded) {
dao.artistsPaging(artistsDefaultQuery(sourceId, starred.ordinal, search, sort, descending))
} else {
val downloadedFilter = 1
when (sort) {
ArtistSort.Name -> {
if (descending) {
@@ -281,10 +284,10 @@ class LibraryRepository(
): Flow<PagingData<Playlist>> =
pager(40) {
val dao = db.libraryDao()
val downloadedFilter = if (downloaded) 1 else 0
if (!downloaded) {
dao.playlistsPaging(playlistsDefaultQuery(sourceId, search, sort, descending))
} else {
val downloadedFilter = 1
when (sort) {
PlaylistSort.Name -> {
if (descending) {
@@ -675,6 +675,10 @@ class LibraryDaoTest {
)
assertEquals(listOf("Say \"Hello\""), dao.albumsByName(sourceId, 0, "\"Hel").page().map { it.name })
assertEquals(
listOf("Say \"Hello\""),
dao.albumsPaging(albumsDefaultQuery(sourceId, 0, "\"Hel", AlbumSort.Name, false)).page().map { it.name },
)
}
@Test
@@ -817,6 +821,9 @@ class LibraryDaoTest {
awaitUntil("the downloaded list observes download writes") { downloadedInvalidated.get() }
assertFalse("the default list must not observe download writes", defaultInvalidated.get())
dao.upsertAlbums(listOf(album(sourceId, "a", "Renamed", year = null, starred = null)))
awaitUntil("the default list observes album writes") { defaultInvalidated.get() }
}
private suspend fun source(): Long =
@@ -371,7 +371,7 @@ class LibraryHomeDaoTest {
assertEquals(
listOf("Older", "Old"),
dao.albumsByRediscover(sourceId, starredFilter = 0, search = "", cutoff = 500).page().map { it.name },
dao.albumsPaging(rediscoverAlbumsQuery(sourceId, starredFilter = 0, search = "", cutoff = 500)).page().map { it.name },
)
}