refactor(db): Migrate getChapters query to SQLDelight

This commit is contained in:
Ahmad Ansori Palembani 2024-11-29 15:08:42 +07:00
parent 83cb898068
commit e25f330118
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
10 changed files with 54 additions and 43 deletions

View file

@ -8,15 +8,14 @@ import eu.kanade.tachiyomi.domain.manga.models.Manga
interface ChapterQueries : DbProvider {
fun getChapters(manga: Manga) = getChapters(manga.id)
fun getChapters(mangaId: Long?) = db.get()
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
fun getChapters(manga: Manga) = db.get()
.listOfObjects(Chapter::class.java)
.withQuery(
Query.builder()
.table(ChapterTable.TABLE)
.where("${ChapterTable.COL_MANGA_ID} = ?")
.whereArgs(mangaId)
.whereArgs(manga.id)
.build(),
)
.prepare()

View file

@ -79,18 +79,6 @@ interface HistoryQueries : DbProvider {
)
.prepare()
fun getTotalReadDuration(): Long {
val cursor = db.lowLevel()
.rawQuery(
RawQuery.builder()
.query("SELECT SUM(${HistoryTable.COL_TIME_READ}) FROM ${HistoryTable.TABLE}")
.observesTables(HistoryTable.TABLE)
.build(),
)
cursor.moveToFirst()
return cursor.getLong(0)
}
/**
* Updates the history last read.
* Inserts history object if not yet in database

View file

@ -8,16 +8,22 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.database.models.isOneShotOrCompleted
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.util.system.executeOnIO
import kotlinx.collections.immutable.ImmutableList
import okhttp3.OkHttpClient
import uy.kohesive.injekt.injectLazy
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.history.interactor.GetHistory
import yokai.domain.manga.interactor.GetManga
abstract class TrackService(val id: Long) {
val trackPreferences: TrackPreferences by injectLazy()
val networkService: NetworkHelper by injectLazy()
val db: DatabaseHelper by injectLazy()
val getChapter: GetChapter by injectLazy()
val getManga: GetManga by injectLazy()
val getHistory: GetHistory by injectLazy()
open fun canRemoveFromService() = false
open val client: OkHttpClient
get() = networkService.client
@ -110,9 +116,9 @@ abstract class TrackService(val id: Long) {
}
suspend fun TrackService.updateNewTrackInfo(track: Track) {
val manga = db.getManga(track.manga_id).executeOnIO()
val manga = getManga.awaitById(track.manga_id)
val allRead = manga?.isOneShotOrCompleted() == true &&
db.getChapters(track.manga_id).executeOnIO().all { it.read }
getChapter.awaitAll(track.manga_id, false).all { it.read }
if (supportsReadingDates) {
track.started_reading_date = getStartDate(track)
track.finished_reading_date = getCompletedDate(track, allRead)
@ -129,8 +135,8 @@ suspend fun TrackService.updateNewTrackInfo(track: Track) {
}
suspend fun TrackService.getStartDate(track: Track): Long {
if (db.getChapters(track.manga_id).executeOnIO().any { it.read }) {
val chapters = db.getHistoryByMangaId(track.manga_id).executeOnIO().filter { it.last_read > 0 }
if (getChapter.awaitAll(track.manga_id, false).any { it.read }) {
val chapters = getHistory.awaitAllByMangaId(track.manga_id).filter { it.last_read > 0 }
val date = chapters.minOfOrNull { it.last_read } ?: return 0L
return if (date <= 0L) 0L else date
}
@ -139,7 +145,7 @@ suspend fun TrackService.getStartDate(track: Track): Long {
suspend fun TrackService.getCompletedDate(track: Track, allRead: Boolean): Long {
if (allRead) {
val chapters = db.getHistoryByMangaId(track.manga_id).executeOnIO()
val chapters = getHistory.awaitAllByMangaId(track.manga_id)
val date = chapters.maxOfOrNull { it.last_read } ?: return 0L
return if (date <= 0L) 0L else date
}
@ -147,7 +153,7 @@ suspend fun TrackService.getCompletedDate(track: Track, allRead: Boolean): Long
}
suspend fun TrackService.getLastChapterRead(track: Track): Float {
val chapters = db.getChapters(track.manga_id).executeOnIO()
val chapters = getChapter.awaitAll(track.manga_id, false)
val lastChapterRead = chapters.filter { it.read }.minByOrNull { it.source_order }
return lastChapterRead?.takeIf { it.isRecognizedNumber }?.chapter_number ?: 0f
}

View file

@ -70,6 +70,7 @@ import yokai.domain.category.models.CategoryUpdate
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.UpdateChapter
import yokai.domain.chapter.models.ChapterUpdate
import yokai.domain.history.interactor.GetHistory
import yokai.domain.manga.interactor.GetLibraryManga
import yokai.domain.manga.interactor.GetManga
import yokai.domain.manga.interactor.UpdateManga
@ -98,6 +99,7 @@ class LibraryPresenter(
private val updateChapter: UpdateChapter by injectLazy()
private val updateManga: UpdateManga by injectLazy()
private val getTrack: GetTrack by injectLazy()
private val getHistory: GetHistory by injectLazy()
private val context = preferences.context
private val viewContext
@ -544,9 +546,9 @@ class LibraryPresenter(
return if (scoresList.isEmpty()) -1 else scoresList.average().roundToInt().coerceIn(1..10)
}
private fun LibraryManga.getStartYear(): Int {
if (db.getChapters(id).executeAsBlocking().any { it.read }) {
val chapters = db.getHistoryByMangaId(id!!).executeAsBlocking().filter { it.last_read > 0 }
private suspend fun LibraryManga.getStartYear(): Int {
if (getChapter.awaitAll(id!!, false).any { it.read }) {
val chapters = getHistory.awaitAllByMangaId(id!!).filter { it.last_read > 0 }
val date = chapters.minOfOrNull { it.last_read } ?: return -1
val cal = Calendar.getInstance().apply { timeInMillis = date }
return if (date <= 0L) -1 else cal.get(Calendar.YEAR)

View file

@ -24,6 +24,7 @@ import java.text.DecimalFormat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import uy.kohesive.injekt.injectLazy
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.manga.models.cover
import yokai.i18n.MR
import yokai.presentation.core.util.coil.loadManga
@ -35,6 +36,8 @@ class MigrationProcessHolder(
) : BaseFlexibleViewHolder(view, adapter) {
private val db: DatabaseHelper by injectLazy()
private val getChapter: GetChapter by injectLazy()
private val sourceManager: SourceManager by injectLazy()
private var item: MigrationProcessItem? = null
private val binding = MigrationProcessItemBinding.bind(view)
@ -142,7 +145,7 @@ class MigrationProcessHolder(
root.setOnClickListener(null)
}
private fun MangaGridItemBinding.attachManga(manga: Manga, source: Source) {
private suspend fun MangaGridItemBinding.attachManga(manga: Manga, source: Source) {
(root.layoutParams as ConstraintLayout.LayoutParams).verticalBias = 1f
progress.isVisible = false
@ -159,7 +162,7 @@ class MigrationProcessHolder(
gradient.isVisible = true
title.text = source.toString()
val mangaChapters = db.getChapters(manga).executeAsBlocking()
val mangaChapters = getChapter.awaitAll(manga, false)
unreadDownloadBadge.badgeView.setChapters(mangaChapters.size)
val latestChapter = mangaChapters.maxOfOrNull { it.chapter_number } ?: -1f

View file

@ -80,7 +80,9 @@ object StatsHelper {
201..Int.MAX_VALUE,
)
fun Long.getReadDuration(blankValue: String = "0"): String {
fun Long?.getReadDuration(blankValue: String = "0"): String {
if (this == null) return blankValue
val days = TimeUnit.MILLISECONDS.toDays(this)
val hours = TimeUnit.MILLISECONDS.toHours(this) % 24
val minutes = TimeUnit.MILLISECONDS.toMinutes(this) % 60

View file

@ -20,6 +20,7 @@ import kotlinx.coroutines.runBlocking
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import yokai.data.DatabaseHandler
import yokai.domain.manga.interactor.GetLibraryManga
import yokai.domain.track.interactor.GetTrack
import yokai.i18n.MR
@ -35,6 +36,7 @@ class StatsPresenter(
private val downloadManager: DownloadManager = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),
): BaseCoroutinePresenter<StatsController>() {
private val handler: DatabaseHandler by injectLazy()
private val getLibraryManga: GetLibraryManga by injectLazy()
private val getTrack: GetTrack by injectLazy()
@ -86,7 +88,9 @@ class StatsPresenter(
}
fun getReadDuration(): String {
val chaptersTime = db.getTotalReadDuration()
val chaptersTime = runBlocking {
handler.awaitOneOrNull { historyQueries.getTotalReadDuration() }?.sum?.toLong()
}
return chaptersTime.getReadDuration(prefs.context.getString(MR.strings.none))
}
}

View file

@ -29,18 +29,21 @@ import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.roundToTwoDecimal
import eu.kanade.tachiyomi.util.system.withUIContext
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlinx.coroutines.runBlocking
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.history.interactor.GetHistory
import yokai.domain.manga.interactor.GetLibraryManga
import yokai.domain.track.interactor.GetTrack
import yokai.i18n.MR
import yokai.util.lang.getString
import java.util.*
import java.util.concurrent.*
import kotlin.math.roundToInt
import yokai.domain.category.interactor.GetCategories
import yokai.domain.track.interactor.GetTrack
class StatsDetailsPresenter(
private val db: DatabaseHelper = Injekt.get(),
@ -49,8 +52,10 @@ class StatsDetailsPresenter(
private val sourceManager: SourceManager = Injekt.get(),
) : BaseCoroutinePresenter<StatsDetailsController>() {
private val getCategories: GetCategories by injectLazy()
private val getChapter: GetChapter by injectLazy()
private val getLibraryManga: GetLibraryManga by injectLazy()
private val getTrack: GetTrack by injectLazy()
private val getHistory: GetHistory by injectLazy()
private val context
get() = view?.view?.context ?: prefs.context
@ -357,7 +362,7 @@ class StatsDetailsPresenter(
currentStats = currentStats?.take(100)?.let { ArrayList(it) }
}
private fun setupStartYear() {
private suspend fun setupStartYear() {
currentStats = ArrayList()
val libraryFormat = mangasDistinct.filterByChip().groupBy { it.getStartYear() }
@ -537,9 +542,9 @@ class StatsDetailsPresenter(
return service?.get10PointScore(this.score)
}
private fun LibraryManga.getStartYear(): Int? {
if (db.getChapters(id).executeAsBlocking().any { it.read }) {
val chapters = db.getHistoryByMangaId(id!!).executeAsBlocking().filter { it.last_read > 0 }
private suspend fun LibraryManga.getStartYear(): Int? {
if (getChapter.awaitAll(id!!, false).any { it.read }) {
val chapters = getHistory.awaitAllByMangaId(id!!).filter { it.last_read > 0 }
val date = chapters.minOfOrNull { it.last_read } ?: return null
val cal = Calendar.getInstance().apply { timeInMillis = date }
return if (date <= 0L) null else cal.get(Calendar.YEAR)

View file

@ -18,7 +18,6 @@ import co.touchlab.kermit.Logger
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadProvider
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
@ -87,6 +86,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import yokai.domain.base.BasePreferences.ExtensionInstaller
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.extension.interactor.TrustExtension
import yokai.domain.manga.interactor.GetManga
import yokai.domain.source.SourcePreferences
@ -104,8 +104,7 @@ class SettingsAdvancedController : SettingsLegacyController() {
private val readerPreferences: ReaderPreferences by injectLazy()
private val sourcePreferences: SourcePreferences by injectLazy()
private val db: DatabaseHelper by injectLazy()
private val getChapter: GetChapter by injectLazy()
private val getManga: GetManga by injectLazy()
private val downloadManager: DownloadManager by injectLazy()
@ -511,7 +510,7 @@ class SettingsAdvancedController : SettingsLegacyController() {
}
continue
}
val chapterList = db.getChapters(manga).executeAsBlocking()
val chapterList = getChapter.awaitAll(manga, false)
foldersCleared += downloadManager.cleanupChapters(chapterList, manga, source, removeRead, removeNonFavorite)
}
}

View file

@ -42,6 +42,9 @@ JOIN chapters
ON history.history_chapter_id = chapters._id
WHERE chapters.url = :chapterUrl AND history.history_chapter_id = chapters._id;
getTotalReadDuration:
SELECT sum(history_time_read) FROM history;
getRecentsUngrouped:
SELECT
M.*,