From 614839bb550181c957ad01f3c50acf02907c3557 Mon Sep 17 00:00:00 2001 From: Christophe Henry Date: Mon, 17 Feb 2025 15:52:39 +0100 Subject: [PATCH] Fix unread feed selection in FoldersAndFeedsQueryBuilder --- .../readrops/app/GetFoldersWithFeedsTest.kt | 30 +++++++++++++++-- .../app/repositories/GetFoldersWithFeeds.kt | 2 +- .../db/queries/FoldersAndFeedsQueryBuilder.kt | 32 +++++++++++++------ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/app/src/androidTest/java/com/readrops/app/GetFoldersWithFeedsTest.kt b/app/src/androidTest/java/com/readrops/app/GetFoldersWithFeedsTest.kt index cfdfe499..6b0ffe60 100644 --- a/app/src/androidTest/java/com/readrops/app/GetFoldersWithFeedsTest.kt +++ b/app/src/androidTest/java/com/readrops/app/GetFoldersWithFeedsTest.kt @@ -8,6 +8,7 @@ import com.readrops.db.Database import com.readrops.db.entities.Feed import com.readrops.db.entities.Folder import com.readrops.db.entities.Item +import com.readrops.db.entities.ItemState import com.readrops.db.entities.account.Account import com.readrops.db.entities.account.AccountType import com.readrops.db.filters.MainFilter @@ -16,6 +17,7 @@ import kotlinx.coroutines.test.runTest import java.time.LocalDateTime import org.junit.Before import org.junit.Test +import kotlin.test.assertEquals import kotlin.test.assertTrue class GetFoldersWithFeedsTest { @@ -67,14 +69,34 @@ class GetFoldersWithFeedsTest { ) ) } + + // insert 4 read items items linked to second feed (feed 1) + repeat(4) { time -> + val item = Item( + title = "Item ${time + 3}", + feedId = 4, + isRead = true, + pubDate = LocalDateTime.now(), + remoteId = "remote/$time" + ) + database.itemDao().insert(item) + database.itemStateDao().insert( + ItemState( + read = false, + remoteId = "remote/$time", + accountId = account.id + ) + ) + + } } } @Test fun getFoldersWithFeedsTest() = runTest { getFoldersWithFeeds = GetFoldersWithFeeds(database) - val foldersAndFeeds = - getFoldersWithFeeds.get(account.id, MainFilter.ALL, account.config.useSeparateState) + var foldersAndFeeds = + getFoldersWithFeeds.get(account.id, MainFilter.ALL, false) .first() assertTrue { foldersAndFeeds.size == 4 } @@ -82,5 +104,9 @@ class GetFoldersWithFeedsTest { assertTrue { foldersAndFeeds.entries.last().key == null } assertTrue { foldersAndFeeds[null]!!.size == 2 } assertTrue { foldersAndFeeds[null]!!.first().unreadCount == 3 } + + foldersAndFeeds = getFoldersWithFeeds.get(account.id, MainFilter.ALL, true).first() + val feed = foldersAndFeeds.values.flatten().first { it.id == 4 } + assertEquals(4, feed.unreadCount) } } \ No newline at end of file diff --git a/app/src/main/java/com/readrops/app/repositories/GetFoldersWithFeeds.kt b/app/src/main/java/com/readrops/app/repositories/GetFoldersWithFeeds.kt index 10976a9a..d0899718 100644 --- a/app/src/main/java/com/readrops/app/repositories/GetFoldersWithFeeds.kt +++ b/app/src/main/java/com/readrops/app/repositories/GetFoldersWithFeeds.kt @@ -20,7 +20,7 @@ class GetFoldersWithFeeds( useSeparateState: Boolean, hideReadFeeds: Boolean = false ): Flow>> { - val foldersAndFeedsQuery = FoldersAndFeedsQueryBuilder.build(accountId, hideReadFeeds) + val foldersAndFeedsQuery = FoldersAndFeedsQueryBuilder.build(accountId, hideReadFeeds, useSeparateState) val unreadItemsCountQuery = FeedUnreadCountQueryBuilder.build(accountId, mainFilter, useSeparateState) return combine( diff --git a/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueryBuilder.kt b/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueryBuilder.kt index 3bebfa57..edad6490 100644 --- a/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueryBuilder.kt +++ b/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueryBuilder.kt @@ -1,5 +1,6 @@ package com.readrops.db.queries +import androidx.room.util.newStringBuilder import androidx.sqlite.db.SimpleSQLiteQuery import androidx.sqlite.db.SupportSQLiteQuery import androidx.sqlite.db.SupportSQLiteQueryBuilder @@ -25,7 +26,9 @@ object FoldersAndFeedsQueryBuilder { ) private val FEED_JOIN = """(Select * From Feed Where account_id = :accountId) Feed - Left Join Folder On Folder.id = Feed.folder_id """.trimMargin() + Left Join Folder On Folder.id = Feed.folder_id""".trimMargin() + + private val SEPARATE_STATE = " Left Join ItemState On ItemState.remote_id = Item.remote_id" private const val FOLDER_JOIN = "Folder Left Join Feed On Folder.id = Feed.folder_id " @@ -35,12 +38,10 @@ object FoldersAndFeedsQueryBuilder { private const val FOLDER_SELECTION = "Feed.id is NULL And Folder.account_id = :accountId" - private const val ITEM_SELECTION = "And Item.read = 0" - - fun build(accountId: Int, hideReadFeeds: Boolean = false): SupportSQLiteQuery { - return SimpleSQLiteQuery( + fun build(accountId: Int, hideReadFeeds: Boolean, useSeparateState: Boolean): SupportSQLiteQuery { + val result = SimpleSQLiteQuery( """ - ${buildFeedQuery(accountId, hideReadFeeds).sql} + ${buildFeedQuery(accountId, hideReadFeeds, useSeparateState).sql} ${ if (!hideReadFeeds) { """UNION ALL @@ -51,11 +52,24 @@ object FoldersAndFeedsQueryBuilder { } }""".trimIndent() ) + return result } - private fun buildFeedQuery(accountId: Int, hideReadFeeds: Boolean): SupportSQLiteQuery { - val tables = if (hideReadFeeds) FEED_JOIN + ITEM_JOIN else FEED_JOIN - val selection = if (hideReadFeeds) FEED_SELECTION + ITEM_SELECTION else FEED_SELECTION + private fun buildFeedQuery(accountId: Int, hideReadFeeds: Boolean, useSeparateState: Boolean): SupportSQLiteQuery { + val tables = buildString { + append(FEED_JOIN) + if (hideReadFeeds) { + append(ITEM_JOIN) + if(useSeparateState) append(SEPARATE_STATE) + } + } + val selection = buildString { + append(FEED_SELECTION) + if (hideReadFeeds) { + if(useSeparateState) append("AND ItemState.read = 0") + else append("And Item.read = 0") + } + } return SupportSQLiteQueryBuilder.builder(tables.replace(":accountId", "$accountId")).run { columns(COLUMNS)