diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt index b18bb9044..ce395ad1c 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt +++ b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt @@ -80,17 +80,14 @@ class OfflineFirstNewsRepository @Inject constructor( val hasOnboarded = userData.shouldHideOnboarding val followedTopicIds = userData.followedTopics - // TODO: Make this more efficient, there is no need to retrieve populated - // news resources when all that's needed are the ids val existingNewsResourceIdsThatHaveChanged = when { - hasOnboarded -> newsResourceDao.getNewsResources( + hasOnboarded -> newsResourceDao.getNewsResourceIds( useFilterTopicIds = true, filterTopicIds = followedTopicIds, useFilterNewsIds = true, filterNewsIds = changedIds.toSet(), ) .first() - .map { it.entity.id } .toSet() // No need to retrieve anything if notifications won't be sent else -> emptySet() diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt b/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt index d5d8932e7..6e5c45305 100644 --- a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt +++ b/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt @@ -67,6 +67,33 @@ class TestNewsResourceDao : NewsResourceDao { result } + override fun getNewsResourceIds( + useFilterTopicIds: Boolean, + filterTopicIds: Set, + useFilterNewsIds: Boolean, + filterNewsIds: Set, + ): Flow> = + entitiesStateFlow + .map { newsResourceEntities -> + newsResourceEntities.map { entity -> + entity.asPopulatedNewsResource(topicCrossReferences) + } + } + .map { resources -> + var result = resources + if (useFilterTopicIds) { + result = result.filter { resource -> + resource.topics.any { it.id in filterTopicIds } + } + } + if (useFilterNewsIds) { + result = result.filter { resource -> + resource.entity.id in filterNewsIds + } + } + result.map { it.entity.id } + } + override suspend fun insertOrIgnoreNewsResources( entities: List, ): List { diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt b/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt index a05507a8b..0ad1e4f7d 100644 --- a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt +++ b/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt @@ -65,6 +65,37 @@ interface NewsResourceDao { filterNewsIds: Set = emptySet(), ): Flow> + /** + * Fetches ids of news resources that match the query parameters + */ + @Transaction + @Query( + value = """ + SELECT id FROM news_resources + WHERE + CASE WHEN :useFilterNewsIds + THEN id IN (:filterNewsIds) + ELSE 1 + END + AND + CASE WHEN :useFilterTopicIds + THEN id IN + ( + SELECT news_resource_id FROM news_resources_topics + WHERE topic_id IN (:filterTopicIds) + ) + ELSE 1 + END + ORDER BY publish_date DESC + """, + ) + fun getNewsResourceIds( + useFilterTopicIds: Boolean = false, + filterTopicIds: Set = emptySet(), + useFilterNewsIds: Boolean = false, + filterNewsIds: Set = emptySet(), + ): Flow> + /** * Inserts [entities] into the db if they don't exist, and ignores those that do */