From c9259c5a71032f2d226f4ff2ca499c0d06b8efda Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Sat, 2 Mar 2024 22:15:13 +0100 Subject: [PATCH] Make foldersAndFeeds queries aware of main filters --- .../app/compose/feeds/FeedViewModel.kt | 3 +- .../repositories/GetFoldersWithFeeds.kt | 13 +++-- .../app/compose/timelime/TimelineViewModel.kt | 2 +- .../com/readrops/db/dao/newdao/NewFeedDao.kt | 11 ++-- .../readrops/db/dao/newdao/NewFolderDao.kt | 19 +++---- .../queries/FoldersAndFeedsQueriesBuilder.kt | 51 +++++++++++++++++++ 6 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueriesBuilder.kt diff --git a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt index 92f96557..f2177ea6 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/feeds/FeedViewModel.kt @@ -11,6 +11,7 @@ import com.readrops.db.Database import com.readrops.db.entities.Feed import com.readrops.db.entities.Folder import com.readrops.db.entities.account.Account +import com.readrops.db.filters.FilterType import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow @@ -46,7 +47,7 @@ class FeedViewModel( viewModelScope.launch(context = Dispatchers.IO) { accountEvent .flatMapConcat { account -> - getFoldersWithFeeds.get(account.id) + getFoldersWithFeeds.get(account.id, FilterType.NO_FILTER) } .catch { throwable -> _feedState.update { 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 0f68e6ad..813eb4f5 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 @@ -3,6 +3,8 @@ package com.readrops.app.compose.repositories import com.readrops.db.Database import com.readrops.db.entities.Feed import com.readrops.db.entities.Folder +import com.readrops.db.filters.FilterType +import com.readrops.db.queries.FoldersAndFeedsQueriesBuilder import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -10,12 +12,17 @@ class GetFoldersWithFeeds( private val database: Database, ) { - fun get(accountId: Int): Flow>> { + fun get(accountId: Int, filterType: FilterType): Flow>> { + val foldersAndFeedsQuery = + FoldersAndFeedsQueriesBuilder.buildFoldersAndFeedsQuery(accountId, filterType) + val feedsWithoutFolderQuery = + FoldersAndFeedsQueriesBuilder.buildFeedsWithoutFolderQuery(accountId, filterType) + return combine( flow = database.newFolderDao() - .selectFoldersAndFeeds(accountId), + .selectFoldersAndFeeds(foldersAndFeedsQuery), flow2 = database.newFeedDao() - .selectFeedsWithoutFolder(accountId) + .selectFeedsWithoutFolder(feedsWithoutFolderQuery) ) { folders, feedsWithoutFolder -> val foldersWithFeeds = folders.groupBy( keySelector = { diff --git a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt index 51ddee87..be4807d3 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineViewModel.kt @@ -67,7 +67,7 @@ class TimelineViewModel( ) } - getFoldersWithFeeds.get(account.id) + getFoldersWithFeeds.get(account.id, filters.filterType) .collect { foldersAndFeeds -> _timelineState.update { it.copy( diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt index 6e1d5171..c26b272a 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewFeedDao.kt @@ -2,7 +2,10 @@ 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.Item import com.readrops.db.pojo.FeedWithCount import kotlinx.coroutines.flow.Flow @@ -21,12 +24,8 @@ abstract class NewFeedDao : NewBaseDao { @Query("Select case When :feedUrl In (Select url from Feed Where account_id = :accountId) Then 1 else 0 end") abstract suspend fun feedExists(feedUrl: String, accountId: Int): Boolean - @Query("With main As (Select Feed.id as feedId, Feed.name as feedName, Feed.icon_url as feedIcon, " + - "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)" + - "Select feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId, " + - "(Select count(*) From main Where (itemRead = 0)) as unreadCount From main Group by feedId Order By feedName") - abstract fun selectFeedsWithoutFolder(accountId: Int): Flow> + @RawQuery(observedEntities = [Feed::class, Item::class]) + abstract fun selectFeedsWithoutFolder(query: SupportSQLiteQuery): Flow> @Query("Update Feed set name = :feedName, url = :feedUrl, folder_id = :folderId Where id = :feedId") abstract fun updateFeedFields(feedId: Int, feedName: String, feedUrl: String, folderId: Int?) 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 05f9e643..175a8dcc 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,23 +2,20 @@ 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 -abstract class NewFolderDao : NewBaseDao { +interface NewFolderDao : NewBaseDao { - @Query("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, " + - "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 ) " + - "Select folderId, folderName, feedId, feedName, feedIcon, feedUrl, feedSiteUrl, accountId," + - " (Select count(*) From main Where (itemRead = 0)) as unreadCount " + - "From main Group by feedId, folderId Order By folderName, feedName") - abstract fun selectFoldersAndFeeds(accountId: Int): Flow> + @RawQuery(observedEntities = [Folder::class, Feed::class, Item::class]) + fun selectFoldersAndFeeds(query: SupportSQLiteQuery): Flow> @Query("Select * From Folder Where account_id = :accountId") - abstract fun selectFolders(accountId: Int): Flow> + fun selectFolders(accountId: Int): Flow> } \ 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 new file mode 100644 index 00000000..e0e675b8 --- /dev/null +++ b/db/src/main/java/com/readrops/db/queries/FoldersAndFeedsQueriesBuilder.kt @@ -0,0 +1,51 @@ +package com.readrops.db.queries + +import androidx.sqlite.db.SimpleSQLiteQuery +import androidx.sqlite.db.SupportSQLiteQuery +import com.readrops.db.filters.FilterType +import org.intellij.lang.annotations.Language + +object FoldersAndFeedsQueriesBuilder { + + fun buildFoldersAndFeedsQuery(accountId: Int, filterType: FilterType): SupportSQLiteQuery { + val filter = when (filterType) { + FilterType.STARS_FILTER -> "And Item.starred = 1" + FilterType.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, + 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, + (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, filterType: FilterType): SupportSQLiteQuery { + val filter = when (filterType) { + FilterType.STARS_FILTER -> "And Item.starred = 1 " + FilterType.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.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, + (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