From 6893e9a199f0466a52f21315077cfe19d87e312d Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Fri, 26 Apr 2024 17:08:58 +0200 Subject: [PATCH] Fix once and for all folders and feeds query with simple read state --- .../repositories/GetFoldersWithFeeds.kt | 53 +++++++------------ .../readrops/db/dao/newdao/NewFolderDao.kt | 12 ++--- .../com/readrops/db/dao/newdao/NewItemDao.kt | 5 ++ .../com/readrops/db/pojo/FeedWithFolder.kt | 5 +- .../FeedUnreadItemsCountQueryBuilder.kt | 25 +++++++++ .../queries/FoldersAndFeedsQueriesBuilder.kt | 51 ------------------ 6 files changed, 56 insertions(+), 95 deletions(-) create mode 100644 db/src/main/java/com/readrops/db/queries/FeedUnreadItemsCountQueryBuilder.kt delete mode 100644 db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueriesBuilder.kt diff --git a/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt b/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt index 7ea8166a..13f0b06c 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/repositories/GetFoldersWithFeeds.kt @@ -4,7 +4,7 @@ import com.readrops.db.Database import com.readrops.db.entities.Feed import com.readrops.db.entities.Folder import com.readrops.db.filters.MainFilter -import com.readrops.db.queries.FoldersAndFeedsQueriesBuilder +import com.readrops.db.queries.FeedUnreadItemsCountQueryBuilder import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -13,24 +13,24 @@ class GetFoldersWithFeeds( ) { fun get(accountId: Int, mainFilter: MainFilter): Flow>> { - val foldersAndFeedsQuery = - FoldersAndFeedsQueriesBuilder.buildFoldersAndFeedsQuery(accountId, mainFilter) - val feedsWithoutFolderQuery = - FoldersAndFeedsQueriesBuilder.buildFeedsWithoutFolderQuery(accountId, mainFilter) + val query = FeedUnreadItemsCountQueryBuilder.build(accountId, mainFilter) return combine( - flow = database.newFolderDao() - .selectFoldersAndFeeds(foldersAndFeedsQuery), - flow2 = database.newFeedDao() - .selectFeedsWithoutFolder(feedsWithoutFolderQuery) - ) { folders, feedsWithoutFolder -> + flow = database.newFolderDao().selectFoldersAndFeeds(accountId), + flow2 = database.newItemDao().selectFeedUnreadItemsCount(query) + ) { folders, itemCounts -> val foldersWithFeeds = folders.groupBy( keySelector = { - Folder( - id = it.folderId, - name = it.folderName, - accountId = it.accountId - ) as Folder? + if (it.folderId != null) { + Folder( + id = it.folderId!!, + name = it.folderName, + accountId = it.accountId + ) + } else { + null + } + }, valueTransform = { Feed( @@ -40,10 +40,11 @@ class GetFoldersWithFeeds( url = it.feedUrl, siteUrl = it.feedSiteUrl, description = it.feedDescription, - unreadCount = it.unreadCount + unreadCount = itemCounts[it.feedId] ?: 0 ) } ).mapValues { listEntry -> + // Empty folder case if (listEntry.value.any { it.id == 0 }) { listOf() } else { @@ -51,25 +52,7 @@ class GetFoldersWithFeeds( } } - if (feedsWithoutFolder.isNotEmpty()) { - foldersWithFeeds + mapOf( - Pair( - null, - feedsWithoutFolder.map { feedWithoutFolder -> - Feed( - id = feedWithoutFolder.feedId, - name = feedWithoutFolder.feedName, - iconUrl = feedWithoutFolder.feedIcon, - url = feedWithoutFolder.feedUrl, - siteUrl = feedWithoutFolder.feedSiteUrl, - description = feedWithoutFolder.feedDescription, - unreadCount = feedWithoutFolder.unreadCount - ) - }) - ) - } else { - foldersWithFeeds - } + foldersWithFeeds } } } \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt index ac7ec4ce..0e78dd05 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewFolderDao.kt @@ -2,19 +2,19 @@ package com.readrops.db.dao.newdao import androidx.room.Dao import androidx.room.Query -import androidx.room.RawQuery -import androidx.sqlite.db.SupportSQLiteQuery -import com.readrops.db.entities.Feed import com.readrops.db.entities.Folder -import com.readrops.db.entities.Item import com.readrops.db.pojo.FolderWithFeed import kotlinx.coroutines.flow.Flow @Dao interface NewFolderDao : NewBaseDao { - @RawQuery(observedEntities = [Folder::class, Feed::class, Item::class]) - fun selectFoldersAndFeeds(query: SupportSQLiteQuery): Flow> + @Query("Select Feed.id As feedId, Feed.name As feedName, Feed.icon_url As feedIcon, Feed.url As feedUrl, " + + "Feed.siteUrl As feedSiteUrl, Feed.description as feedDescription, Feed.account_id As accountId, " + + "Folder.id As folderId, Folder.name As folderName, 0 as unreadCount " + + " From Feed Left Join Folder On Folder.id = Feed.folder_id " + + "Where Feed.folder_id is NULL OR Feed.folder_id is NOT NULL And Feed.account_id = :accountId Group By Feed.id") + fun selectFoldersAndFeeds(accountId: Int): Flow> @Query("Select * From Folder Where account_id = :accountId") fun selectFolders(accountId: Int): Flow> diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt index aed4fa8c..9c04f24e 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt @@ -2,6 +2,7 @@ package com.readrops.db.dao.newdao import androidx.paging.PagingSource import androidx.room.Dao +import androidx.room.MapColumn import androidx.room.Query import androidx.room.RawQuery import androidx.sqlite.db.SupportSQLiteQuery @@ -49,4 +50,8 @@ abstract class NewItemDao : NewBaseDao { @Query("Select count(*) From Item Inner Join Feed On Item.feed_id = Feed.id Where read = 0 and account_id = :accountId " + "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\")") abstract fun selectUnreadNewItemsCount(accountId: Int): Flow + + @RawQuery(observedEntities = [Item::class]) + abstract fun selectFeedUnreadItemsCount(query: SupportSQLiteQuery): + Flow> } \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt b/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt index 75b4600f..067f13be 100644 --- a/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt +++ b/db/src/main/java/com/readrops/db/pojo/FeedWithFolder.kt @@ -13,15 +13,14 @@ data class FeedWithFolder( ) : Parcelable data class FolderWithFeed( - val folderId: Int, - val folderName: String, + val folderId: Int?, + val folderName: String?, val feedId: Int = 0, val feedName: String? = null, val feedIcon: String? = null, val feedUrl: String? = null, val feedDescription: String? = null, val feedSiteUrl: String? = null, - val unreadCount: Int = 0, val accountId: Int = 0 ) diff --git a/db/src/main/java/com/readrops/db/queries/FeedUnreadItemsCountQueryBuilder.kt b/db/src/main/java/com/readrops/db/queries/FeedUnreadItemsCountQueryBuilder.kt new file mode 100644 index 00000000..843acd2e --- /dev/null +++ b/db/src/main/java/com/readrops/db/queries/FeedUnreadItemsCountQueryBuilder.kt @@ -0,0 +1,25 @@ +package com.readrops.db.queries + +import androidx.sqlite.db.SimpleSQLiteQuery +import androidx.sqlite.db.SupportSQLiteQuery +import com.readrops.db.filters.MainFilter +import org.intellij.lang.annotations.Language + +object FeedUnreadItemsCountQueryBuilder { + + fun build(accountId: Int, mainFilter: MainFilter): SupportSQLiteQuery { + val filter = when (mainFilter) { + MainFilter.STARS -> "And Item.starred = 1" + MainFilter.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") " + else -> "" + } + + @Language("SQL") + val query = SimpleSQLiteQuery(""" + Select feed_id, count(*) AS item_count From Item Inner Join Feed On Feed.id = Item.feed_id + Where read = 0 And account_id = $accountId $filter Group By feed_id + """.trimIndent()) + + return query + } +} \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueriesBuilder.kt b/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueriesBuilder.kt deleted file mode 100644 index ee78ec0f..00000000 --- a/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueriesBuilder.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.readrops.db.queries - -import androidx.sqlite.db.SimpleSQLiteQuery -import androidx.sqlite.db.SupportSQLiteQuery -import com.readrops.db.filters.MainFilter -import org.intellij.lang.annotations.Language - -object FoldersAndFeedsQueriesBuilder { - - fun buildFoldersAndFeedsQuery(accountId: Int, mainFilter: MainFilter): SupportSQLiteQuery { - val filter = when (mainFilter) { - MainFilter.STARS -> "And Item.starred = 1" - MainFilter.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") " - else -> "" - } - - @Language("SQL") - val query = SimpleSQLiteQuery(""" - With main As (Select Folder.id As folderId, Folder.name As folderName, Feed.id As feedId, - Feed.name As feedName, Feed.icon_url As feedIcon, Feed.url As feedUrl, Feed.siteUrl As feedSiteUrl, Feed.description as feedDescription, - Folder.account_id As accountId, Item.read as itemRead - From Folder Left Join Feed On Folder.id = Feed.folder_id Left Join Item On Item.feed_id = Feed.id - Where Feed.folder_id is NULL OR Feed.folder_id is NOT NULL And Feed.account_id = $accountId $filter) - Select folderId, folderName, feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId, feedDescription, - (Select count(*) From main Where (itemRead = 0)) as unreadCount - From main Group by feedId, folderId Order By folderName, feedName - """.trimIndent()) - - return query - } - - fun buildFeedsWithoutFolderQuery(accountId: Int, mainFilter: MainFilter): SupportSQLiteQuery { - val filter = when (mainFilter) { - MainFilter.STARS -> "And Item.starred = 1 " - MainFilter.NEW -> "And DateTime(Round(Item.pub_date / 1000), 'unixepoch') Between DateTime(DateTime(\"now\"), \"-24 hour\") And DateTime(\"now\") " - else -> "" - } - - @Language("SQL") - val query = SimpleSQLiteQuery(""" - With main As (Select Feed.id As feedId, Feed.name As feedName, Feed.icon_url As feedIcon, feed.description as feedDescription, - Feed.url As feedUrl, Feed.siteUrl As feedSiteUrl, Feed.account_id As accountId, Item.read As itemRead - From Feed Left Join Item On Feed.id = Item.feed_id Where Feed.folder_id is Null And Feed.account_id = $accountId $filter) - Select feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId, feedDescription, - (Select count(*) From main Where (itemRead = 0)) as unreadCount From main Group by feedId Order By feedName - """.trimIndent()) - - return query - } - -} \ No newline at end of file