From fa846d68e20de1183ccbdf9724c97930524720c4 Mon Sep 17 00:00:00 2001 From: Ahmad Ansori Palembani Date: Fri, 29 Nov 2024 10:24:03 +0700 Subject: [PATCH] refactor(db): Migrate most getCategoriesForManga queries to SQLDelight --- .../data/database/queries/CategoryQueries.kt | 1 + .../tachiyomi/data/download/Downloader.kt | 13 +++++- .../ui/library/LibraryCategoryAdapter.kt | 18 +++++--- .../tachiyomi/ui/library/LibraryPresenter.kt | 5 ++- .../tachiyomi/ui/reader/ReaderViewModel.kt | 42 ++++++++++--------- .../kanade/tachiyomi/util/MangaExtensions.kt | 4 +- 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/CategoryQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/CategoryQueries.kt index 665f134bde..a557479e4b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/CategoryQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/CategoryQueries.kt @@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.domain.manga.models.Manga interface CategoryQueries : DbProvider { + // FIXME: Migrate to SQLDelight, on halt: in StorIO transaction fun getCategoriesForManga(manga: Manga) = db.get() .listOfObjects(Category::class.java) .withQuery( diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 552d9d2be9..a25bb34258 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -57,6 +57,7 @@ import yokai.util.lang.getString import java.io.File import java.util.* import java.util.zip.* +import yokai.domain.category.interactor.GetCategories /** * This class is the one in charge of downloading chapters. @@ -83,6 +84,7 @@ class Downloader( private val chapterCache: ChapterCache by injectLazy() private val xml: XML by injectLazy() private val db: DatabaseHelper by injectLazy() + private val getCategories: GetCategories by injectLazy() /** * Store for persisting downloads across restarts. @@ -644,8 +646,15 @@ class Downloader( chapter: Chapter, source: HttpSource, ) { - val categories = - db.getCategoriesForManga(manga).executeAsBlocking().map { it.name.trim() }.takeUnless { it.isEmpty() } + val categories = manga.id?.let { mangaId -> + // FIXME: Don't do blocking + runBlocking { + getCategories.awaitByMangaId(mangaId) + } + } + .orEmpty() + .map { it.name.trim() } + .takeUnless { it.isEmpty() } val url = try { source.getChapterUrl(chapter) } catch (_: Exception) { null } ?: source.getChapterUrl(manga, chapter).takeIf { !it.isNullOrBlank() } // FIXME: Not sure if this is necessary diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt index 6f6287cae1..e4bf62a479 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt @@ -20,6 +20,9 @@ import yokai.domain.ui.UiPreferences import yokai.i18n.MR import yokai.util.lang.getString import java.util.* +import yokai.domain.category.interactor.GetCategories +import yokai.domain.chapter.interactor.GetChapter +import yokai.domain.history.interactor.GetHistory /** * Adapter storing a list of manga in a certain category. @@ -190,7 +193,9 @@ class LibraryCategoryAdapter(val controller: LibraryController?) : override fun onCreateBubbleText(position: Int): String { val preferences: PreferencesHelper by injectLazy() - val db: DatabaseHelper by injectLazy() + val getCategories: GetCategories by injectLazy() + val getChapter: GetChapter by injectLazy() + val getHistory: GetHistory by injectLazy() val context = recyclerView.context if (position == itemCount - 1) return context.getString(MR.strings.bottom) return when (val item: IFlexible<*>? = getItem(position)) { @@ -204,8 +209,9 @@ class LibraryCategoryAdapter(val controller: LibraryController?) : } else { when (getSort(position)) { LibrarySort.DragAndDrop -> { - if (item.header.category.isDynamic) { - val category = db.getCategoriesForManga(item.manga).executeAsBlocking().firstOrNull()?.name + if (item.header.category.isDynamic && item.manga.id != null) { + // FIXME: Don't do blocking + val category = runBlocking { getCategories.awaitByMangaId(item.manga.id!!) }.firstOrNull()?.name category ?: context.getString(MR.strings.default_value) } else { val title = item.manga.title @@ -218,13 +224,15 @@ class LibraryCategoryAdapter(val controller: LibraryController?) : } LibrarySort.DateFetched -> { val id = item.manga.id ?: return "" - val history = db.getChapters(id).executeAsBlocking() + // FIXME: Don't do blocking + val history = runBlocking { getChapter.awaitAll(id, false) } val last = history.maxOfOrNull { it.date_fetch } context.timeSpanFromNow(MR.strings.fetched_, last ?: 0) } LibrarySort.LastRead -> { val id = item.manga.id ?: return "" - val history = db.getHistoryByMangaId(id).executeAsBlocking() + // FIXME: Don't do blocking + val history = runBlocking { getHistory.awaitAllByMangaId(id) } val last = history.maxOfOrNull { it.last_read } context.timeSpanFromNow(MR.strings.read_, last ?: 0) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index cf0470e922..3685340dee 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -1362,7 +1362,7 @@ class LibraryPresenter( if (catId == 0) { emptyList() } else { - db.getCategoriesForManga(manga).executeOnIO() + getCategories.awaitByMangaId(manga.id!!) .filter { it.id != oldCatId } + listOf(category) } @@ -1389,7 +1389,8 @@ class LibraryPresenter( /** Returns if manga is in a category by id */ fun mangaIsInCategory(manga: LibraryManga, catId: Int?): Boolean { - val categories = db.getCategoriesForManga(manga).executeAsBlocking().map { it.id } + // FIXME: Don't do blocking + val categories = runBlocking { getCategories.awaitByMangaId(manga.id!!) }.map { it.id } return catId in categories } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt index fedc294743..2bfd8bc7f4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt @@ -76,6 +76,7 @@ import rx.schedulers.Schedulers import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy +import yokai.domain.category.interactor.GetCategories import yokai.domain.chapter.interactor.GetChapter import yokai.domain.chapter.interactor.InsertChapter import yokai.domain.chapter.interactor.UpdateChapter @@ -106,6 +107,7 @@ class ReaderViewModel( private val storageManager: StorageManager = Injekt.get(), private val downloadPreferences: DownloadPreferences = Injekt.get(), ) : ViewModel() { + private val getCategories: GetCategories by injectLazy() private val getChapter: GetChapter by injectLazy() private val insertChapter: InsertChapter by injectLazy() private val updateChapter: UpdateChapter by injectLazy() @@ -593,28 +595,30 @@ class ReaderViewModel( * @param currentChapter current chapter, which is going to be marked as read. */ private fun deleteChapterIfNeeded(currentChapter: ReaderChapter) { - // Determine which chapter should be deleted and enqueue - val currentChapterPosition = chapterList.indexOf(currentChapter) - val removeAfterReadSlots = preferences.removeAfterReadSlots().get() - val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots) + viewModelScope.launchNonCancellableIO { + // Determine which chapter should be deleted and enqueue + val currentChapterPosition = chapterList.indexOf(currentChapter) + val removeAfterReadSlots = preferences.removeAfterReadSlots().get() + val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots) - if (removeAfterReadSlots != 0 && chapterToDownload != null) { - downloadManager.addDownloadsToStartOfQueue(listOf(chapterToDownload!!)) - } else { - chapterToDownload = null - } - // Check if deleting option is enabled and chapter exists - if (removeAfterReadSlots != -1 && chapterToDelete != null) { - val excludedCategories = preferences.removeExcludeCategories().get().map(String::toInt) - if (excludedCategories.any()) { - val categories = db.getCategoriesForManga(manga!!).executeAsBlocking() - .mapNotNull { it.id } - .ifEmpty { listOf(0) } - - if (categories.any { it in excludedCategories }) return + if (removeAfterReadSlots != 0 && chapterToDownload != null) { + downloadManager.addDownloadsToStartOfQueue(listOf(chapterToDownload!!)) + } else { + chapterToDownload = null } + // Check if deleting option is enabled and chapter exists + if (removeAfterReadSlots != -1 && chapterToDelete != null) { + val excludedCategories = preferences.removeExcludeCategories().get().map(String::toInt) + if (excludedCategories.any()) { + val categories = getCategories.awaitByMangaId(manga!!.id!!) + .mapNotNull { it.id } + .ifEmpty { listOf(0) } - enqueueDeleteReadChapters(chapterToDelete) + if (categories.any { it in excludedCategories }) return@launchNonCancellableIO + } + + enqueueDeleteReadChapters(chapterToDelete) + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt index 13fdc39e0f..a7e7d36a6c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/MangaExtensions.kt @@ -308,8 +308,10 @@ private fun Manga.showSetCategoriesSheet( categories: List, onMangaAdded: (Pair?) -> Unit, onMangaMoved: () -> Unit, + getCategories: GetCategories = Injekt.get(), ) { - val categoriesForManga = db.getCategoriesForManga(this).executeAsBlocking() + // FIXME: Don't do blocking + val categoriesForManga = runBlocking { getCategories.awaitByMangaId(this@showSetCategoriesSheet.id!!) } val ids = categoriesForManga.mapNotNull { it.id }.toTypedArray() SetCategoriesSheet(