Refactor favorites DAO

This commit is contained in:
MM20 2022-09-15 20:27:21 +02:00
parent 9243f85735
commit f04f9be4b6
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
2 changed files with 67 additions and 26 deletions

View File

@ -1,6 +1,5 @@
package de.mm20.launcher2.database
import androidx.lifecycle.LiveData
import androidx.room.*
import de.mm20.launcher2.database.entities.FavoritesItemEntity
import de.mm20.launcher2.database.entities.WebsearchEntity
@ -18,11 +17,46 @@ interface SearchDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertSkipExisting(items: FavoritesItemEntity)
@Query("SELECT * FROM Searchable WHERE pinned > 0 AND (NOT :excludeCalendarEvents OR NOT `key` LIKE 'calendar://%') ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
fun getFavorites(excludeCalendarEvents: Boolean = false, limit: Int): Flow<List<FavoritesItemEntity>>
@Query("SELECT * FROM Searchable WHERE pinned > 0 AND `key` LIKE 'calendar://%' ORDER BY pinned DESC, launchCount DESC")
fun getPinnedCalendarEvents(): Flow<List<FavoritesItemEntity>>
@Query("SELECT * FROM Searchable " +
"WHERE ((:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
fun getFavorites(
manuallySorted: Boolean = false,
automaticallySorted: Boolean = false,
frequentlyUsed: Boolean = false,
limit: Int,
): Flow<List<FavoritesItemEntity>>
@Query("SELECT * FROM Searchable " +
"WHERE SUBSTR(`key`, 0, INSTR(`key`, '://')) IN (:includeTypes) AND (" +
"(:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
fun getFavoritesWithTypes(
includeTypes: List<String>,
manuallySorted: Boolean = false,
automaticallySorted: Boolean = false,
frequentlyUsed: Boolean = false,
limit: Int,
): Flow<List<FavoritesItemEntity>>
@Query("SELECT * FROM Searchable " +
"WHERE SUBSTR(`key`, 0, INSTR(`key`, '://')) NOT IN (:excludeTypes) AND (" +
"(:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
fun getFavoritesWithoutTypes(
excludeTypes: List<String>,
manuallySorted: Boolean = false,
automaticallySorted: Boolean = false,
frequentlyUsed: Boolean = false,
limit: Int,
): Flow<List<FavoritesItemEntity>>
@Query("SELECT `key` FROM Searchable WHERE hidden = 1 AND `key` LIKE 'calendar://%'")
fun getHiddenCalendarEventKeys(): Flow<List<String>>
@ -112,9 +146,6 @@ interface SearchDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertReplaceExisting(toDatabaseEntity: FavoritesItemEntity)
@Query("SELECT * FROM Searchable WHERE (pinned > 0 OR launchCount > 0) AND hidden = 0 ORDER BY pinned DESC, launchCount DESC")
fun getAllFavoriteItems(): List<FavoritesItemEntity>
@Transaction
fun saveFavorites(favorites: List<FavoritesItemEntity>) {
deleteAllFavorites()

View File

@ -10,10 +10,7 @@ import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.data.CalendarEvent
import de.mm20.launcher2.search.data.Searchable
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.*
import org.json.JSONArray
import org.json.JSONException
import org.koin.core.component.KoinComponent
@ -35,7 +32,6 @@ interface FavoritesRepository {
fun hideItem(searchable: Searchable)
fun unhideItem(searchable: Searchable)
fun incrementLaunchCounter(searchable: Searchable)
suspend fun getAllFavoriteItems(): List<FavoritesItem>
fun saveFavorites(favorites: List<FavoritesItem>)
fun getHiddenItems(): Flow<List<Searchable>>
fun getHiddenItemKeys(): Flow<List<String>>
@ -73,7 +69,21 @@ internal class FavoritesRepositoryImpl(
withContext(Dispatchers.IO) {
val dao = database.searchDao()
val pinnedFavorites =
dao.getFavorites(excludeCalendarEvents, columns * (maxRows ?: 20)).map {
if (excludeCalendarEvents) {
dao.getFavoritesWithoutTypes(
excludeTypes = listOf("calendar"),
manuallySorted = true,
automaticallySorted = true,
frequentlyUsed = false,
limit = columns * (maxRows ?: 20)
)
} else {
dao.getFavorites(
manuallySorted = true,
automaticallySorted = true,
frequentlyUsed = false,
limit = columns * (maxRows ?: 20))
}.map {
it.mapNotNull {
val item = fromDatabaseEntity(it).searchable
if (item == null) {
@ -86,9 +96,12 @@ internal class FavoritesRepositoryImpl(
pinnedFavorites.collectLatest { pinned ->
var favCount = (pinned.size.toDouble() / columns).ceilToInt() * columns
if (pinned.size < columns) favCount += columns
val autoFavs = dao.getAutoFavorites(
favCount.coerceAtMost((maxRows ?: 20) * columns) - pinned.size
).mapNotNull {
val autoFavs = dao.getFavorites(
manuallySorted = false,
automaticallySorted = false,
frequentlyUsed = true,
limit = favCount.coerceAtMost((maxRows ?: 20) * columns) - pinned.size
).first().mapNotNull {
val item = fromDatabaseEntity(it).searchable
if (item == null) {
dao.deleteByKey(it.key)
@ -101,7 +114,12 @@ internal class FavoritesRepositoryImpl(
}
override fun getPinnedCalendarEvents(): Flow<List<CalendarEvent>> {
return database.searchDao().getPinnedCalendarEvents().map {
return database.searchDao().getFavoritesWithTypes(
includeTypes = listOf("calendar"),
automaticallySorted = true,
manuallySorted = true,
limit = 50
).map {
it.mapNotNull { fromDatabaseEntity(it).searchable as? CalendarEvent }
}
}
@ -180,14 +198,6 @@ internal class FavoritesRepositoryImpl(
}
}
override suspend fun getAllFavoriteItems(): List<FavoritesItem> {
return withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).searchDao().getAllFavoriteItems().mapNotNull {
fromDatabaseEntity(it).takeIf { it.searchable != null }
}
}
}
override fun saveFavorites(favorites: List<FavoritesItem>) {
scope.launch {
withContext(Dispatchers.IO) {