refactor(db): Migrate most getCategoriesForManga queries to SQLDelight

This commit is contained in:
Ahmad Ansori Palembani 2024-11-29 10:24:03 +07:00
parent 87bd36d025
commit fa846d68e2
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
6 changed files with 54 additions and 29 deletions

View file

@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.domain.manga.models.Manga
interface CategoryQueries : DbProvider { interface CategoryQueries : DbProvider {
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
fun getCategoriesForManga(manga: Manga) = db.get() fun getCategoriesForManga(manga: Manga) = db.get()
.listOfObjects(Category::class.java) .listOfObjects(Category::class.java)
.withQuery( .withQuery(

View file

@ -57,6 +57,7 @@ import yokai.util.lang.getString
import java.io.File import java.io.File
import java.util.* import java.util.*
import java.util.zip.* import java.util.zip.*
import yokai.domain.category.interactor.GetCategories
/** /**
* This class is the one in charge of downloading chapters. * This class is the one in charge of downloading chapters.
@ -83,6 +84,7 @@ class Downloader(
private val chapterCache: ChapterCache by injectLazy() private val chapterCache: ChapterCache by injectLazy()
private val xml: XML by injectLazy() private val xml: XML by injectLazy()
private val db: DatabaseHelper by injectLazy() private val db: DatabaseHelper by injectLazy()
private val getCategories: GetCategories by injectLazy()
/** /**
* Store for persisting downloads across restarts. * Store for persisting downloads across restarts.
@ -644,8 +646,15 @@ class Downloader(
chapter: Chapter, chapter: Chapter,
source: HttpSource, source: HttpSource,
) { ) {
val categories = val categories = manga.id?.let { mangaId ->
db.getCategoriesForManga(manga).executeAsBlocking().map { it.name.trim() }.takeUnless { it.isEmpty() } // 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 } val url = try { source.getChapterUrl(chapter) } catch (_: Exception) { null }
?: source.getChapterUrl(manga, chapter).takeIf { !it.isNullOrBlank() } // FIXME: Not sure if this is necessary ?: source.getChapterUrl(manga, chapter).takeIf { !it.isNullOrBlank() } // FIXME: Not sure if this is necessary

View file

@ -20,6 +20,9 @@ import yokai.domain.ui.UiPreferences
import yokai.i18n.MR import yokai.i18n.MR
import yokai.util.lang.getString import yokai.util.lang.getString
import java.util.* 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. * 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 { override fun onCreateBubbleText(position: Int): String {
val preferences: PreferencesHelper by injectLazy() 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 val context = recyclerView.context
if (position == itemCount - 1) return context.getString(MR.strings.bottom) if (position == itemCount - 1) return context.getString(MR.strings.bottom)
return when (val item: IFlexible<*>? = getItem(position)) { return when (val item: IFlexible<*>? = getItem(position)) {
@ -204,8 +209,9 @@ class LibraryCategoryAdapter(val controller: LibraryController?) :
} else { } else {
when (getSort(position)) { when (getSort(position)) {
LibrarySort.DragAndDrop -> { LibrarySort.DragAndDrop -> {
if (item.header.category.isDynamic) { if (item.header.category.isDynamic && item.manga.id != null) {
val category = db.getCategoriesForManga(item.manga).executeAsBlocking().firstOrNull()?.name // FIXME: Don't do blocking
val category = runBlocking { getCategories.awaitByMangaId(item.manga.id!!) }.firstOrNull()?.name
category ?: context.getString(MR.strings.default_value) category ?: context.getString(MR.strings.default_value)
} else { } else {
val title = item.manga.title val title = item.manga.title
@ -218,13 +224,15 @@ class LibraryCategoryAdapter(val controller: LibraryController?) :
} }
LibrarySort.DateFetched -> { LibrarySort.DateFetched -> {
val id = item.manga.id ?: return "" 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 } val last = history.maxOfOrNull { it.date_fetch }
context.timeSpanFromNow(MR.strings.fetched_, last ?: 0) context.timeSpanFromNow(MR.strings.fetched_, last ?: 0)
} }
LibrarySort.LastRead -> { LibrarySort.LastRead -> {
val id = item.manga.id ?: return "" 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 } val last = history.maxOfOrNull { it.last_read }
context.timeSpanFromNow(MR.strings.read_, last ?: 0) context.timeSpanFromNow(MR.strings.read_, last ?: 0)
} }

View file

@ -1362,7 +1362,7 @@ class LibraryPresenter(
if (catId == 0) { if (catId == 0) {
emptyList() emptyList()
} else { } else {
db.getCategoriesForManga(manga).executeOnIO() getCategories.awaitByMangaId(manga.id!!)
.filter { it.id != oldCatId } + listOf(category) .filter { it.id != oldCatId } + listOf(category)
} }
@ -1389,7 +1389,8 @@ class LibraryPresenter(
/** Returns if manga is in a category by id */ /** Returns if manga is in a category by id */
fun mangaIsInCategory(manga: LibraryManga, catId: Int?): Boolean { 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 return catId in categories
} }

View file

@ -76,6 +76,7 @@ import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import yokai.domain.category.interactor.GetCategories
import yokai.domain.chapter.interactor.GetChapter import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.InsertChapter import yokai.domain.chapter.interactor.InsertChapter
import yokai.domain.chapter.interactor.UpdateChapter import yokai.domain.chapter.interactor.UpdateChapter
@ -106,6 +107,7 @@ class ReaderViewModel(
private val storageManager: StorageManager = Injekt.get(), private val storageManager: StorageManager = Injekt.get(),
private val downloadPreferences: DownloadPreferences = Injekt.get(), private val downloadPreferences: DownloadPreferences = Injekt.get(),
) : ViewModel() { ) : ViewModel() {
private val getCategories: GetCategories by injectLazy()
private val getChapter: GetChapter by injectLazy() private val getChapter: GetChapter by injectLazy()
private val insertChapter: InsertChapter by injectLazy() private val insertChapter: InsertChapter by injectLazy()
private val updateChapter: UpdateChapter 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. * @param currentChapter current chapter, which is going to be marked as read.
*/ */
private fun deleteChapterIfNeeded(currentChapter: ReaderChapter) { private fun deleteChapterIfNeeded(currentChapter: ReaderChapter) {
// Determine which chapter should be deleted and enqueue viewModelScope.launchNonCancellableIO {
val currentChapterPosition = chapterList.indexOf(currentChapter) // Determine which chapter should be deleted and enqueue
val removeAfterReadSlots = preferences.removeAfterReadSlots().get() val currentChapterPosition = chapterList.indexOf(currentChapter)
val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots) val removeAfterReadSlots = preferences.removeAfterReadSlots().get()
val chapterToDelete = chapterList.getOrNull(currentChapterPosition - removeAfterReadSlots)
if (removeAfterReadSlots != 0 && chapterToDownload != null) { if (removeAfterReadSlots != 0 && chapterToDownload != null) {
downloadManager.addDownloadsToStartOfQueue(listOf(chapterToDownload!!)) downloadManager.addDownloadsToStartOfQueue(listOf(chapterToDownload!!))
} else { } else {
chapterToDownload = null 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
} }
// 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)
}
} }
} }

View file

@ -308,8 +308,10 @@ private fun Manga.showSetCategoriesSheet(
categories: List<Category>, categories: List<Category>,
onMangaAdded: (Pair<Long, Boolean>?) -> Unit, onMangaAdded: (Pair<Long, Boolean>?) -> Unit,
onMangaMoved: () -> 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() val ids = categoriesForManga.mapNotNull { it.id }.toTypedArray()
SetCategoriesSheet( SetCategoriesSheet(