Fix favourites and history deletion

This commit is contained in:
Koitharu
2022-07-21 11:15:08 +03:00
parent 9360787897
commit feb19c4eb5
6 changed files with 61 additions and 30 deletions

View File

@@ -24,8 +24,7 @@ abstract class FavouriteCategoriesDao {
@Update
abstract suspend fun update(category: FavouriteCategoryEntity): Int
@Query("UPDATE favourite_categories SET deleted_at = :now WHERE category_id = :id")
abstract suspend fun delete(id: Long, now: Long = System.currentTimeMillis())
suspend fun delete(id: Long) = setDeletedAt(id, System.currentTimeMillis())
@Query("UPDATE favourite_categories SET title = :title, `order` = :order, `track` = :tracker WHERE category_id = :id")
abstract suspend fun update(id: Long, title: String, order: String, tracker: Boolean)
@@ -33,8 +32,8 @@ abstract class FavouriteCategoriesDao {
@Query("UPDATE favourite_categories SET `order` = :order WHERE category_id = :id")
abstract suspend fun updateOrder(id: Long, order: String)
@Query("UPDATE favourite_categories SET `track` = :isEnabled WHERE category_id = :id")
abstract suspend fun updateTracking(id: Long, isEnabled: Boolean)
// @Query("UPDATE favourite_categories SET `track` = :isEnabled WHERE category_id = :id")
// abstract suspend fun updateTracking(id: Long, isEnabled: Boolean)
@Query("UPDATE favourite_categories SET `show_in_lib` = :isEnabled WHERE category_id = :id")
abstract suspend fun updateLibVisibility(id: Long, isEnabled: Boolean)
@@ -58,4 +57,7 @@ abstract class FavouriteCategoriesDao {
insert(entity)
}
}
@Query("UPDATE favourite_categories SET deleted_at = :deletedAt WHERE category_id = :id")
protected abstract suspend fun setDeletedAt(id: Long, deletedAt: Long)
}

View File

@@ -11,6 +11,8 @@ import org.koitharu.kotatsu.parsers.model.SortOrder
@Dao
abstract class FavouritesDao {
/** SELECT **/
@Transaction
@Query("SELECT * FROM favourites WHERE deleted_at = 0 GROUP BY manga_id ORDER BY created_at DESC")
abstract suspend fun findAll(): List<FavouriteManga>
@@ -61,12 +63,12 @@ abstract class FavouritesDao {
)
abstract suspend fun findAllManga(categoryId: Int): List<MangaEntity>
suspend fun findCovers(categoryId: Long, order: SortOrder, limit: Int): List<String> {
suspend fun findCovers(categoryId: Long, order: SortOrder): List<String> {
val orderBy = getOrderBy(order)
@Language("RoomSql") val query = SimpleSQLiteQuery(
"SELECT m.cover_url FROM favourites AS f LEFT JOIN manga AS m ON f.manga_id = m.manga_id " +
"WHERE f.category_id = ? AND deleted_at = 0 ORDER BY $orderBy LIMIT ?",
arrayOf<Any>(categoryId, limit),
"WHERE f.category_id = ? AND deleted_at = 0 ORDER BY $orderBy",
arrayOf<Any>(categoryId),
)
return findCoversImpl(query)
}
@@ -85,25 +87,33 @@ abstract class FavouritesDao {
@Query("SELECT DISTINCT category_id FROM favourites WHERE manga_id = :id AND deleted_at = 0")
abstract fun observeIds(id: Long): Flow<List<Long>>
/** INSERT **/
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun insert(favourite: FavouriteEntity)
/** UPDATE **/
@Update
abstract suspend fun update(favourite: FavouriteEntity): Int
@Query("UPDATE favourites SET deleted_at = :now WHERE manga_id = :mangaId")
abstract suspend fun delete(mangaId: Long, now: Long = System.currentTimeMillis())
/** DELETE **/
@Query("UPDATE favourites SET deleted_at = :now WHERE manga_id = :mangaId AND category_id = :categoryId")
abstract suspend fun delete(categoryId: Long, mangaId: Long, now: Long = System.currentTimeMillis())
suspend fun delete(mangaId: Long) = setDeletedAt(mangaId, System.currentTimeMillis())
suspend fun recover(mangaId: Long) = delete(mangaId, 0L)
suspend fun delete(mangaId: Long, categoryId: Long) = setDeletedAt(mangaId, categoryId, System.currentTimeMillis())
suspend fun recover(categoryId: Long, mangaId: Long) = delete(categoryId, mangaId, 0L)
suspend fun deleteAll(categoryId: Long) = setDeletedAtAll(categoryId, System.currentTimeMillis())
suspend fun recover(mangaId: Long) = setDeletedAt(mangaId, 0L)
suspend fun recover(mangaId: Long, categoryId: Long) = setDeletedAt(categoryId, mangaId, 0L)
@Query("DELETE FROM favourites WHERE deleted_at != 0 AND deleted_at < :maxDeletionTime")
abstract suspend fun gc(maxDeletionTime: Long)
/** TOOLS **/
@Transaction
open suspend fun upsert(entity: FavouriteEntity) {
if (update(entity) == 0) {
@@ -118,6 +128,15 @@ abstract class FavouritesDao {
@RawQuery
protected abstract suspend fun findCoversImpl(query: SupportSQLiteQuery): List<String>
@Query("UPDATE favourites SET deleted_at = :deletedAt WHERE manga_id = :mangaId")
protected abstract suspend fun setDeletedAt(mangaId: Long, deletedAt: Long)
@Query("UPDATE favourites SET deleted_at = :deletedAt WHERE manga_id = :mangaId AND category_id = :categoryId")
abstract suspend fun setDeletedAt(mangaId: Long, categoryId: Long, deletedAt: Long)
@Query("UPDATE favourites SET deleted_at = :deletedAt WHERE category_id = :categoryId AND deleted_at = 0")
protected abstract suspend fun setDeletedAtAll(categoryId: Long, deletedAt: Long)
private fun getOrderBy(sortOrder: SortOrder) = when (sortOrder) {
SortOrder.RATING -> "rating DESC"
SortOrder.NEWEST,

View File

@@ -51,7 +51,7 @@ class FavouritesRepository(
}.distinctUntilChanged()
}
fun observeCategoriesWithCovers(coversLimit: Int): Flow<Map<FavouriteCategory, List<String>>> {
fun observeCategoriesWithCovers(): Flow<Map<FavouriteCategory, List<String>>> {
return db.favouriteCategoriesDao.observeAll()
.map {
db.withTransaction {
@@ -61,7 +61,6 @@ class FavouritesRepository(
res[cat] = db.favouritesDao.findCovers(
categoryId = cat.id,
order = cat.order,
limit = coversLimit,
)
}
res
@@ -108,16 +107,24 @@ class FavouritesRepository(
}
suspend fun removeCategory(id: Long) {
db.favouriteCategoriesDao.delete(id)
db.withTransaction {
db.favouriteCategoriesDao.delete(id)
db.favouritesDao.deleteAll(id)
}
channels.deleteChannel(id)
}
suspend fun removeCategories(ids: Collection<Long>) {
db.withTransaction {
for (id in ids) {
removeCategory(id)
db.favouriteCategoriesDao.delete(id)
db.favouritesDao.deleteAll(id)
}
}
// run after transaction success
for (id in ids) {
channels.deleteChannel(id)
}
}
suspend fun setCategoryOrder(id: Long, order: SortOrder) {
@@ -179,7 +186,7 @@ class FavouritesRepository(
private suspend fun recoverToFavourites(ids: Collection<Long>) {
db.withTransaction {
for (id in ids) {
db.favouritesDao.recover(id)
db.favouritesDao.recover(mangaId = id)
}
}
}
@@ -187,7 +194,7 @@ class FavouritesRepository(
private suspend fun recoverToCategory(categoryId: Long, ids: Collection<Long>) {
db.withTransaction {
for (id in ids) {
db.favouritesDao.recover(categoryId, id)
db.favouritesDao.recover(mangaId = id, categoryId = categoryId)
}
}
}

View File

@@ -39,13 +39,13 @@ class FavouritesCategoriesViewModel(
}.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, emptyList())
val detalizedCategories = combine(
repository.observeCategoriesWithCovers(coversLimit = 3),
repository.observeCategoriesWithCovers(),
isReorder,
) { list, reordering ->
list.map { (category, covers) ->
CategoryListModel(
mangaCount = covers.size,
covers = covers,
covers = covers.take(3),
category = category,
isReorderMode = reordering,
)

View File

@@ -43,9 +43,6 @@ abstract class HistoryDao {
@Query("SELECT COUNT(*) FROM history WHERE deleted_at = 0")
abstract fun observeCount(): Flow<Int>
@Query("UPDATE history SET deleted_at = :now WHERE deleted_at = 0")
abstract suspend fun clear(now: Long = System.currentTimeMillis())
@Query("SELECT percent FROM history WHERE manga_id = :id AND deleted_at = 0")
abstract suspend fun findProgress(id: Long): Float?
@@ -62,16 +59,16 @@ abstract class HistoryDao {
updatedAt: Long,
): Int
@Query("UPDATE history SET deleted_at = :now WHERE manga_id = :mangaId")
abstract suspend fun delete(mangaId: Long, now: Long = System.currentTimeMillis())
suspend fun delete(mangaId: Long) = setDeletedAt(mangaId, System.currentTimeMillis())
suspend fun recover(mangaId: Long) = delete(mangaId, 0L)
suspend fun recover(mangaId: Long) = setDeletedAt(mangaId, 0L)
@Query("DELETE FROM history WHERE deleted_at != 0 AND deleted_at < :maxDeletionTime")
abstract suspend fun gc(maxDeletionTime: Long)
@Query("DELETE FROM history WHERE created_at >= :minDate")
abstract suspend fun deleteAfter(minDate: Long)
suspend fun deleteAfter(minDate: Long) = setDeletedAtAfter(minDate, System.currentTimeMillis())
suspend fun clear() = setDeletedAtAfter(0L, System.currentTimeMillis())
suspend fun update(entity: HistoryEntity) = update(
mangaId = entity.mangaId,
@@ -98,4 +95,10 @@ abstract class HistoryDao {
}
}
}
@Query("UPDATE history SET deleted_at = :deletedAt WHERE manga_id = :mangaId")
protected abstract suspend fun setDeletedAt(mangaId: Long, deletedAt: Long)
@Query("UPDATE history SET deleted_at = :deletedAt WHERE created_at >= :minDate AND deleted_at = 0")
protected abstract suspend fun setDeletedAtAfter(minDate: Long, deletedAt: Long)
}

View File

@@ -109,7 +109,7 @@ class HistoryRepository(
}
suspend fun deleteAfter(minDate: Long) {
db.historyDao.delete(minDate)
db.historyDao.deleteAfter(minDate)
}
suspend fun delete(ids: Collection<Long>): ReversibleHandle {