refactor(db): Migrate last history queries (that can be migrated) to SQLDelight

This commit is contained in:
Ahmad Ansori Palembani 2024-11-29 17:05:59 +07:00
parent 8cef33d9c6
commit 17b07cd836
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
5 changed files with 36 additions and 72 deletions

View file

@ -4,70 +4,12 @@ import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DbProvider import eu.kanade.tachiyomi.data.database.DbProvider
import eu.kanade.tachiyomi.data.database.inTransactionReturn import eu.kanade.tachiyomi.data.database.inTransactionReturn
import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.data.database.resolvers.HistoryUpsertResolver import eu.kanade.tachiyomi.data.database.resolvers.HistoryUpsertResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver
import eu.kanade.tachiyomi.data.database.tables.HistoryTable import eu.kanade.tachiyomi.data.database.tables.HistoryTable
import eu.kanade.tachiyomi.util.lang.sqLite
interface HistoryQueries : DbProvider { interface HistoryQueries : DbProvider {
/** // FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
* Insert history into database
* @param history object containing history information
*/
// fun insertHistory(history: History) = db.put().`object`(history).prepare()
// /**
// * Returns history of recent manga containing last read chapter in 25s
// * @param date recent date range
// * @offset offset the db by
// */
// fun getRecentManga(date: Date, offset: Int = 0, search: String = "") = db.get()
// .listOfObjects(MangaChapterHistory::class.java)
// .withQuery(
// RawQuery.builder()
// .query(getRecentMangasQuery(offset, search.sqLite))
// .args(date.time)
// .observesTables(HistoryTable.TABLE)
// .build()
// )
// .withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
// .prepare()
/**
* Returns history of recent manga containing last read chapter in 25s
* @param date recent date range
* @offset offset the db by
*/
fun getHistoryUngrouped(search: String = "", offset: Int, isResuming: Boolean) = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentHistoryUngrouped(search.sqLite, offset, isResuming))
.observesTables(HistoryTable.TABLE)
.build(),
)
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
/**
* Returns history of manga read during period
* @param startDate start date of the period
* @param endDate end date of the period
* @offset offset the db by
*/
fun getHistoryPerPeriod(startDate: Long, endDate: Long) = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getHistoryPerPeriodQuery(startDate, endDate))
.observesTables(HistoryTable.TABLE)
.build(),
)
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
fun getHistoryByMangaId(mangaId: Long) = db.get() fun getHistoryByMangaId(mangaId: Long) = db.get()
.listOfObjects(History::class.java) .listOfObjects(History::class.java)
.withQuery( .withQuery(

View file

@ -106,7 +106,6 @@ import eu.kanade.tachiyomi.util.showNotificationPermissionPrompt
import eu.kanade.tachiyomi.util.system.contextCompatDrawable import eu.kanade.tachiyomi.util.system.contextCompatDrawable
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.e import eu.kanade.tachiyomi.util.system.e
import eu.kanade.tachiyomi.util.system.executeOnIO
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.hasSideNavBar import eu.kanade.tachiyomi.util.system.hasSideNavBar
import eu.kanade.tachiyomi.util.system.ignoredSystemInsets import eu.kanade.tachiyomi.util.system.ignoredSystemInsets
@ -134,6 +133,10 @@ import eu.kanade.tachiyomi.util.view.setTitle
import eu.kanade.tachiyomi.util.view.snack import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.withFadeInTransaction import eu.kanade.tachiyomi.util.view.withFadeInTransaction
import eu.kanade.tachiyomi.util.view.withFadeTransaction import eu.kanade.tachiyomi.util.view.withFadeTransaction
import kotlin.collections.set
import kotlin.math.abs
import kotlin.math.min
import kotlin.math.roundToLong
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -142,15 +145,12 @@ import kotlinx.coroutines.withContext
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import yokai.core.migration.Migrator import yokai.core.migration.Migrator
import yokai.domain.base.BasePreferences import yokai.domain.base.BasePreferences
import yokai.domain.recents.interactor.GetRecents
import yokai.i18n.MR import yokai.i18n.MR
import yokai.presentation.core.Constants import yokai.presentation.core.Constants
import yokai.presentation.extension.repo.ExtensionRepoController import yokai.presentation.extension.repo.ExtensionRepoController
import yokai.presentation.onboarding.OnboardingController import yokai.presentation.onboarding.OnboardingController
import yokai.util.lang.getString import yokai.util.lang.getString
import kotlin.collections.set
import kotlin.math.abs
import kotlin.math.min
import kotlin.math.roundToLong
import android.R as AR import android.R as AR
@SuppressLint("ResourceType") @SuppressLint("ResourceType")
@ -170,7 +170,10 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
private val downloadManager: DownloadManager by injectLazy() private val downloadManager: DownloadManager by injectLazy()
private val mangaShortcutManager: MangaShortcutManager by injectLazy() private val mangaShortcutManager: MangaShortcutManager by injectLazy()
private val extensionManager: ExtensionManager by injectLazy() private val extensionManager: ExtensionManager by injectLazy()
private val db: DatabaseHelper by injectLazy() private val db: DatabaseHelper by injectLazy()
private val getRecents: GetRecents by injectLazy()
private val hideBottomNav private val hideBottomNav
get() = router.backstackSize > 1 && router.backstack[1].controller !is DialogController get() = router.backstackSize > 1 && router.backstack[1].controller !is DialogController
private val hideAppBar private val hideAppBar
@ -408,8 +411,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
} }
BasePreferences.LongTapRecents.LAST_READ -> { BasePreferences.LongTapRecents.LAST_READ -> {
lifecycleScope.launchUI { lifecycleScope.launchUI {
val lastReadChapter = val lastReadChapter = getRecents.awaitUngrouped(true, true, "", 0).maxByOrNull { it.history.last_read }
db.getHistoryUngrouped("", 0, true).executeOnIO().maxByOrNull { it.history.last_read }
lastReadChapter ?: return@launchUI lastReadChapter ?: return@launchUI
val manga = lastReadChapter.manga val manga = lastReadChapter.manga
@ -1031,6 +1033,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
requestColourProfile.launch(arrayOf("*/*")) requestColourProfile.launch(arrayOf("*/*"))
} }
@SuppressLint("MissingSuperCall")
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {
if (!handleIntentAction(intent)) { if (!handleIntentAction(intent)) {
super.onNewIntent(intent) super.onNewIntent(intent)

View file

@ -88,6 +88,7 @@ import yokai.domain.category.interactor.GetCategories
import yokai.domain.chapter.interactor.GetAvailableScanlators import yokai.domain.chapter.interactor.GetAvailableScanlators
import yokai.domain.chapter.interactor.GetChapter import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.UpdateChapter import yokai.domain.chapter.interactor.UpdateChapter
import yokai.domain.history.interactor.GetHistory
import yokai.domain.library.custom.model.CustomMangaInfo import yokai.domain.library.custom.model.CustomMangaInfo
import yokai.domain.manga.interactor.GetManga import yokai.domain.manga.interactor.GetManga
import yokai.domain.manga.interactor.UpdateManga import yokai.domain.manga.interactor.UpdateManga
@ -117,6 +118,7 @@ class MangaDetailsPresenter(
private val updateManga: UpdateManga by injectLazy() private val updateManga: UpdateManga by injectLazy()
private val deleteTrack: DeleteTrack by injectLazy() private val deleteTrack: DeleteTrack by injectLazy()
private val getTrack: GetTrack by injectLazy() private val getTrack: GetTrack by injectLazy()
private val getHistory: GetHistory by injectLazy()
private val networkPreferences: NetworkPreferences by injectLazy() private val networkPreferences: NetworkPreferences by injectLazy()
@ -263,7 +265,7 @@ class MangaDetailsPresenter(
private fun getHistory() { private fun getHistory() {
presenterScope.launchIO { presenterScope.launchIO {
allHistory = db.getHistoryByMangaId(mangaId).executeAsBlocking() allHistory = getHistory.awaitAllByMangaId(mangaId)
} }
} }
@ -1139,8 +1141,8 @@ class MangaDetailsPresenter(
updateRemote(track, item.service) updateRemote(track, item.service)
} }
fun getSuggestedDate(readingDate: TrackingBottomSheet.ReadingDate): Long? { suspend fun getSuggestedDate(readingDate: TrackingBottomSheet.ReadingDate): Long? {
val chapters = db.getHistoryByMangaId(manga.id ?: 0L).executeAsBlocking() val chapters = getHistory.awaitAllByMangaId(manga.id ?: 0L)
val date = when (readingDate) { val date = when (readingDate) {
TrackingBottomSheet.ReadingDate.Start -> chapters.minOfOrNull { it.last_read } TrackingBottomSheet.ReadingDate.Start -> chapters.minOfOrNull { it.last_read }
TrackingBottomSheet.ReadingDate.Finish -> chapters.maxOfOrNull { it.last_read } TrackingBottomSheet.ReadingDate.Finish -> chapters.maxOfOrNull { it.last_read }

View file

@ -38,6 +38,7 @@ import kotlinx.coroutines.runBlocking
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.data.DatabaseHandler
import yokai.domain.category.interactor.GetCategories import yokai.domain.category.interactor.GetCategories
import yokai.domain.chapter.interactor.GetChapter import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.history.interactor.GetHistory import yokai.domain.history.interactor.GetHistory
@ -52,6 +53,7 @@ class StatsDetailsPresenter(
val trackManager: TrackManager = Injekt.get(), val trackManager: TrackManager = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(),
) : BaseCoroutinePresenter<StatsDetailsController>() { ) : BaseCoroutinePresenter<StatsDetailsController>() {
private val handler: DatabaseHandler by injectLazy()
private val getCategories: GetCategories by injectLazy() private val getCategories: GetCategories by injectLazy()
private val getChapter: GetChapter by injectLazy() private val getChapter: GetChapter by injectLazy()
private val getLibraryManga: GetLibraryManga by injectLazy() private val getLibraryManga: GetLibraryManga by injectLazy()
@ -588,15 +590,19 @@ class StatsDetailsPresenter(
return runBlocking { getCategories.await() }.toMutableList() return runBlocking { getCategories.await() }.toMutableList()
} }
private fun List<LibraryManga>.getReadDuration(): Long { private suspend fun List<LibraryManga>.getReadDuration(): Long {
return sumOf { manga -> db.getHistoryByMangaId(manga.id!!).executeAsBlocking().sumOf { it.time_read } } return sumOf { manga -> getHistory.awaitAllByMangaId(manga.id!!).sumOf { it.time_read } }
} }
/** /**
* Get the manga and history grouped by day during the selected period * Get the manga and history grouped by day during the selected period
*/ */
fun getMangaHistoryGroupedByDay(): Map<Calendar, List<MangaChapterHistory>> { fun getMangaHistoryGroupedByDay(): Map<Calendar, List<MangaChapterHistory>> {
val history = db.getHistoryPerPeriod(startDate.timeInMillis, endDate.timeInMillis).executeAsBlocking() val history = runBlocking {
handler.awaitList {
historyQueries.getPerPeriod(startDate.timeInMillis, endDate.timeInMillis, MangaChapterHistory::mapper)
}
}
val calendar = Calendar.getInstance().apply { val calendar = Calendar.getInstance().apply {
timeInMillis = startDate.timeInMillis timeInMillis = startDate.timeInMillis
} }

View file

@ -45,6 +45,17 @@ WHERE chapters.url = :chapterUrl AND history.history_chapter_id = chapters._id;
getTotalReadDuration: getTotalReadDuration:
SELECT sum(history_time_read) FROM history; SELECT sum(history_time_read) FROM history;
getPerPeriod:
SELECT mangas.*, chapters.*, history.*
FROM mangas
JOIN chapters
ON mangas._id = chapters.manga_id
JOIN history
ON chapters._id = history.history_chapter_id
AND history.history_last_read >= :startDate
AND history.history_last_read <= :endDate
ORDER BY history.history_last_read DESC;
getRecentsUngrouped: getRecentsUngrouped:
SELECT SELECT
M.*, M.*,