refactor(db): Replace some more StorIO queries with SQLDelight

This commit is contained in:
Ahmad Ansori Palembani 2024-11-24 19:08:42 +07:00
parent e9d22f4dba
commit 4f9e5bfe62
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
8 changed files with 68 additions and 44 deletions

View file

@ -22,6 +22,8 @@ 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
import yokai.domain.history.interactor.GetHistory
import yokai.domain.history.interactor.UpsertHistory
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.InsertManga import yokai.domain.manga.interactor.InsertManga
@ -37,6 +39,8 @@ class MangaBackupRestorer(
private val getManga: GetManga = Injekt.get(), private val getManga: GetManga = Injekt.get(),
private val insertManga: InsertManga = Injekt.get(), private val insertManga: InsertManga = Injekt.get(),
private val updateManga: UpdateManga = Injekt.get(), private val updateManga: UpdateManga = Injekt.get(),
private val getHistory: GetHistory = Injekt.get(),
private val upsertHistory: UpsertHistory = Injekt.get(),
) { ) {
suspend fun restoreManga( suspend fun restoreManga(
backupManga: BackupManga, backupManga: BackupManga,
@ -202,7 +206,7 @@ class MangaBackupRestorer(
// List containing history to be updated // List containing history to be updated
val historyToBeUpdated = ArrayList<History>(history.size) val historyToBeUpdated = ArrayList<History>(history.size)
for ((url, lastRead, readDuration) in history) { for ((url, lastRead, readDuration) in history) {
val dbHistory = db.getHistoryByChapterUrl(url).executeAsBlocking() val dbHistory = getHistory.awaitByChapterUrl(url)
// Check if history already in database and update // Check if history already in database and update
if (dbHistory != null) { if (dbHistory != null) {
dbHistory.apply { dbHistory.apply {
@ -221,7 +225,7 @@ class MangaBackupRestorer(
} }
} }
} }
db.upsertHistoryLastRead(historyToBeUpdated).executeAsBlocking() upsertHistory.awaitBulk(historyToBeUpdated)
} }
/** /**

View file

@ -92,32 +92,12 @@ interface HistoryQueries : DbProvider {
return cursor.getLong(0) return cursor.getLong(0)
} }
fun getHistoryByChapterUrl(chapterUrl: String) = db.get()
.`object`(History::class.java)
.withQuery(
RawQuery.builder()
.query(getHistoryByChapterUrl())
.args(chapterUrl)
.observesTables(HistoryTable.TABLE)
.build(),
)
.prepare()
/**
* Updates the history last read.
* Inserts history object if not yet in database
* @param history history object
*/
fun upsertHistoryLastRead(history: History) = db.put()
.`object`(history)
.withPutResolver(HistoryUpsertResolver())
.prepare()
/** /**
* Updates the history last read. * Updates the history last read.
* Inserts history object if not yet in database * Inserts history object if not yet in database
* @param historyList history object list * @param historyList history object list
*/ */
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
fun upsertHistoryLastRead(historyList: List<History>) = db.inTransactionReturn { fun upsertHistoryLastRead(historyList: List<History>) = db.inTransactionReturn {
db.put() db.put()
.objects(historyList) .objects(historyList)
@ -125,14 +105,6 @@ interface HistoryQueries : DbProvider {
.prepare() .prepare()
} }
fun deleteHistory() = db.delete()
.byQuery(
DeleteQuery.builder()
.table(HistoryTable.TABLE)
.build(),
)
.prepare()
fun deleteHistoryNoLastRead() = db.delete() fun deleteHistoryNoLastRead() = db.delete()
.byQuery( .byQuery(
DeleteQuery.builder() DeleteQuery.builder()

View file

@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
import eu.kanade.tachiyomi.util.chapter.ChapterFilter import eu.kanade.tachiyomi.util.chapter.ChapterFilter
import eu.kanade.tachiyomi.util.chapter.ChapterSort import eu.kanade.tachiyomi.util.chapter.ChapterSort
import eu.kanade.tachiyomi.util.system.launchIO import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.launchNonCancellableIO
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.system.withUIContext import eu.kanade.tachiyomi.util.system.withUIContext
@ -39,8 +40,11 @@ import kotlinx.coroutines.withContext
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.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.history.interactor.UpsertHistory
import yokai.domain.recents.RecentsPreferences import yokai.domain.recents.RecentsPreferences
import yokai.domain.recents.interactor.GetRecents import yokai.domain.recents.interactor.GetRecents
import yokai.domain.ui.UiPreferences import yokai.domain.ui.UiPreferences
@ -54,9 +58,13 @@ class RecentsPresenter(
val db: DatabaseHelper = Injekt.get(), val db: DatabaseHelper = Injekt.get(),
private val chapterFilter: ChapterFilter = Injekt.get(), private val chapterFilter: ChapterFilter = Injekt.get(),
) : BaseCoroutinePresenter<RecentsController>(), DownloadQueue.DownloadListener { ) : BaseCoroutinePresenter<RecentsController>(), DownloadQueue.DownloadListener {
private val handler: DatabaseHandler by injectLazy()
private val getChapter: GetChapter by injectLazy() private val getChapter: GetChapter by injectLazy()
private val getRecents: GetRecents by injectLazy() private val getRecents: GetRecents by injectLazy()
private val updateChapter: UpdateChapter by injectLazy() private val updateChapter: UpdateChapter by injectLazy()
private val getHistory: GetHistory by injectLazy()
private val upsertHistory: UpsertHistory by injectLazy()
private var recentsJob: Job? = null private var recentsJob: Job? = null
var recentItems = listOf<RecentMangaItem>() var recentItems = listOf<RecentMangaItem>()
@ -635,7 +643,7 @@ class RecentsPresenter(
lastRead: Int? = null, lastRead: Int? = null,
pagesLeft: Int? = null, pagesLeft: Int? = null,
) { ) {
presenterScope.launch(Dispatchers.IO) { presenterScope.launchNonCancellableIO {
chapter.apply { chapter.apply {
this.read = read this.read = read
if (!read) { if (!read) {
@ -654,25 +662,30 @@ class RecentsPresenter(
* @param history history belonging to chapter * @param history history belonging to chapter
*/ */
fun removeFromHistory(history: History) { fun removeFromHistory(history: History) {
presenterScope.launchNonCancellableIO {
history.last_read = 0L history.last_read = 0L
history.time_read = 0L history.time_read = 0L
db.upsertHistoryLastRead(history).executeAsBlocking() upsertHistory.await(history)
getRecents() getRecents()
} }
}
/** /**
* Removes all chapters belonging to manga from history. * Removes all chapters belonging to manga from history.
* @param mangaId id of manga * @param mangaId id of manga
*/ */
fun removeAllFromHistory(mangaId: Long) { fun removeAllFromHistory(mangaId: Long) {
val history = db.getHistoryByMangaId(mangaId).executeAsBlocking() presenterScope.launchNonCancellableIO {
history.forEach { val histories = getHistory.awaitAllByMangaId(mangaId).map {
it.last_read = 0L it.apply {
it.time_read = 0L last_read = 0L
time_read = 0L
} }
db.upsertHistoryLastRead(history).executeAsBlocking() }
upsertHistory.awaitBulk(histories)
getRecents() getRecents()
} }
}
fun requestNext() { fun requestNext() {
if (!isLoading) { if (!isLoading) {
@ -682,8 +695,8 @@ class RecentsPresenter(
} }
fun deleteAllHistory() { fun deleteAllHistory() {
presenterScope.launchIO { presenterScope.launchNonCancellableIO {
db.deleteHistory().executeAsBlocking() handler.await { historyQueries.deleteAll() }
withUIContext { withUIContext {
view?.activity?.toast(MR.strings.clear_history_completed) view?.activity?.toast(MR.strings.clear_history_completed)
getRecents() getRecents()

View file

@ -13,9 +13,26 @@ class HistoryRepositoryImpl(private val handler: DatabaseHandler) : HistoryRepos
historyQueries.selectLastInsertedRowId() historyQueries.selectLastInsertedRowId()
} }
override suspend fun bulkUpsert(histories: List<History>) =
handler.await(true) {
histories.forEach { history ->
historyQueries.upsert(
history.chapter_id,
history.last_read,
history.time_read,
)
}
}
override suspend fun getByChapterUrl(chapterUrl: String): History? = override suspend fun getByChapterUrl(chapterUrl: String): History? =
handler.awaitOneOrNull { historyQueries.getByChapterUrl(chapterUrl, History::mapper) } handler.awaitOneOrNull { historyQueries.getByChapterUrl(chapterUrl, History::mapper) }
override suspend fun getByMangaId(mangaId: Long): History? =
handler.awaitOneOrNull { historyQueries.getByMangaId(mangaId, History::mapper) }
override suspend fun getAllByMangaId(mangaId: Long): List<History> =
handler.awaitList { historyQueries.getByMangaId(mangaId, History::mapper) }
override suspend fun getRecentsUngrouped( override suspend fun getRecentsUngrouped(
filterScanlators: Boolean, filterScanlators: Boolean,
search: String, search: String,

View file

@ -5,7 +5,10 @@ import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
interface HistoryRepository { interface HistoryRepository {
suspend fun upsert(chapterId: Long, lastRead: Long, timeRead: Long): Long? suspend fun upsert(chapterId: Long, lastRead: Long, timeRead: Long): Long?
suspend fun bulkUpsert(histories: List<History>)
suspend fun getByChapterUrl(chapterUrl: String): History? suspend fun getByChapterUrl(chapterUrl: String): History?
suspend fun getByMangaId(mangaId: Long): History?
suspend fun getAllByMangaId(mangaId: Long): List<History>
suspend fun getRecentsUngrouped(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory> suspend fun getRecentsUngrouped(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory>
suspend fun getRecentsBySeries(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory> suspend fun getRecentsBySeries(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapterHistory>

View file

@ -6,4 +6,6 @@ class GetHistory(
private val historyRepository: HistoryRepository private val historyRepository: HistoryRepository
) { ) {
suspend fun awaitByChapterUrl(chapterUrl: String) = historyRepository.getByChapterUrl(chapterUrl) suspend fun awaitByChapterUrl(chapterUrl: String) = historyRepository.getByChapterUrl(chapterUrl)
suspend fun awaitByMangaId(mangaId: Long) = historyRepository.getByMangaId(mangaId)
suspend fun awaitAllByMangaId(mangaId: Long) = historyRepository.getAllByMangaId(mangaId)
} }

View file

@ -11,4 +11,7 @@ class UpsertHistory(
suspend fun await(history: History) = suspend fun await(history: History) =
historyRepository.upsert(history.chapter_id, history.last_read, history.time_read) historyRepository.upsert(history.chapter_id, history.last_read, history.time_read)
suspend fun awaitBulk(histories: List<History>) =
historyRepository.bulkUpsert(histories)
} }

View file

@ -22,6 +22,16 @@ WHERE history_chapter_id = history_chapter_id;
selectLastInsertedRowId: selectLastInsertedRowId:
SELECT last_insert_rowid(); SELECT last_insert_rowid();
deleteAll:
DELETE FROM history;
getByMangaId:
SELECT history.*
FROM history
JOIN chapters
ON history.history_chapter_id = chapters._id
WHERE chapters.manga_id = :mangaId AND history.history_chapter_id = chapters._id;
getByChapterUrl: getByChapterUrl:
SELECT history.* SELECT history.*
FROM history FROM history