From 61e43e047f13cb398a6f78d03066f8d9eabd5c78 Mon Sep 17 00:00:00 2001 From: Ahmad Ansori Palembani Date: Sat, 24 Aug 2024 07:27:33 +0700 Subject: [PATCH] chore: Preparing to migrate History to SQLDelight --- .../database/mappers/HistoryTypeMapping.kt | 13 +++-- .../tachiyomi/data/database/models/History.kt | 12 +++++ .../tachiyomi/ui/reader/ReaderViewModel.kt | 16 +++--- .../sqldelight/tachiyomi/data/chapters.sq | 54 ------------------- .../sqldelight/tachiyomi/data/history.sq | 54 +++++++++++++++++++ 5 files changed, 82 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/HistoryTypeMapping.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/HistoryTypeMapping.kt index bf842a7d2d..844d98a9c5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/HistoryTypeMapping.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/HistoryTypeMapping.kt @@ -10,7 +10,6 @@ import com.pushtorefresh.storio.sqlite.queries.DeleteQuery import com.pushtorefresh.storio.sqlite.queries.InsertQuery import com.pushtorefresh.storio.sqlite.queries.UpdateQuery import eu.kanade.tachiyomi.data.database.models.History -import eu.kanade.tachiyomi.data.database.models.HistoryImpl import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_CHAPTER_ID import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_ID import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_LAST_READ @@ -45,12 +44,12 @@ open class HistoryPutResolver : DefaultPutResolver() { class HistoryGetResolver : DefaultGetResolver() { - override fun mapFromCursor(cursor: Cursor): History = HistoryImpl().apply { - id = cursor.getLong(cursor.getColumnIndex(COL_ID)) - chapter_id = cursor.getLong(cursor.getColumnIndex(COL_CHAPTER_ID)) - last_read = cursor.getLong(cursor.getColumnIndex(COL_LAST_READ)) - time_read = cursor.getLong(cursor.getColumnIndex(COL_TIME_READ)) - } + override fun mapFromCursor(cursor: Cursor): History = History.mapper( + id = cursor.getLong(cursor.getColumnIndex(COL_ID)), + chapterId = cursor.getLong(cursor.getColumnIndex(COL_CHAPTER_ID)), + lastRead = cursor.getLong(cursor.getColumnIndex(COL_LAST_READ)), + timeRead = cursor.getLong(cursor.getColumnIndex(COL_TIME_READ)), + ) } class HistoryDeleteResolver : DefaultDeleteResolver() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/History.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/History.kt index 10429f8b1d..5966f54a33 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/History.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/History.kt @@ -38,5 +38,17 @@ interface History : Serializable { fun create(chapter: Chapter): History = HistoryImpl().apply { this.chapter_id = chapter.id!! } + + fun mapper( + id: Long, + chapterId: Long, + lastRead: Long, + timeRead: Long + ) = HistoryImpl().apply { + this.id = id + this.chapter_id = chapterId + this.last_read = lastRead + this.time_read = timeRead + } } } 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 6a4fa3f281..318622de72 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 @@ -221,7 +221,9 @@ class ReaderViewModel( */ fun onSaveInstanceState() { val currentChapter = getCurrentChapter() ?: return - saveChapterProgress(currentChapter) + viewModelScope.launchNonCancellableIO { + saveChapterProgress(currentChapter) + } } /** @@ -618,9 +620,11 @@ class ReaderViewModel( * Called when reader chapter is changed in reader or when activity is paused. */ private fun saveReadingProgress(readerChapter: ReaderChapter) { - db.inTransaction { - saveChapterProgress(readerChapter) - saveChapterHistory(readerChapter) + viewModelScope.launchNonCancellableIO { + db.inTransaction { + saveChapterProgress(readerChapter) + saveChapterHistory(readerChapter) + } } } @@ -631,7 +635,7 @@ class ReaderViewModel( * If incognito mode isn't on or has at least 1 tracker */ // FIXME: Migrate to SQLDelight, on halt: in StorIO transaction - private fun saveChapterProgress(readerChapter: ReaderChapter) { + private suspend fun saveChapterProgress(readerChapter: ReaderChapter) { readerChapter.requestedPage = readerChapter.chapter.last_page_read db.getChapter(readerChapter.chapter.id!!).executeAsBlocking()?.let { dbChapter -> readerChapter.chapter.bookmark = dbChapter.bookmark @@ -645,7 +649,7 @@ class ReaderViewModel( * Saves this [readerChapter] last read history. */ // FIXME: Migrate to SQLDelight, on halt: in StorIO transaction - private fun saveChapterHistory(readerChapter: ReaderChapter) { + private suspend fun saveChapterHistory(readerChapter: ReaderChapter) { if (!preferences.incognitoMode().get()) { val readAt = Date().time val sessionReadDuration = chapterReadStartTime?.let { readAt - it } ?: 0 diff --git a/data/src/commonMain/sqldelight/tachiyomi/data/chapters.sq b/data/src/commonMain/sqldelight/tachiyomi/data/chapters.sq index 22bc691453..f5d5e36b9b 100644 --- a/data/src/commonMain/sqldelight/tachiyomi/data/chapters.sq +++ b/data/src/commonMain/sqldelight/tachiyomi/data/chapters.sq @@ -77,60 +77,6 @@ AND ( ORDER BY C.date_fetch DESC LIMIT :limit OFFSET :offset; -getRecentsUngrouped: -SELECT - M.*, - C.*, - H.* -FROM mangas AS M -JOIN chapters AS C -ON M._id = C.manga_id -JOIN history AS H -ON C._id = H.history_chapter_id -AND H.history_last_read > 0 -LEFT JOIN scanlators_view AS S -ON C.manga_id = S.manga_id -AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '//') -- I assume if it's N/A it shouldn't be filtered -WHERE lower(M.title) LIKE '%' || :search || '%' -AND ( - :apply_filter = 0 OR S.name IS NULL -) -ORDER BY H.history_last_read DESC -LIMIT :limit OFFSET :offset; - -getRecentsBySeries: -SELECT - M.url AS mangaUrl, - M.*, - C.*, - H.* -FROM mangas AS M -JOIN chapters AS C -ON M._id = C.manga_id -JOIN history AS H -ON C._id = H.history_chapter_id -JOIN ( - SELECT - C2.manga_id AS manga_id, - C2._id AS history_chapter_id, - MAX(H2.history_last_read) AS history_last_read - FROM chapters AS C2 JOIN history AS H2 - ON C2._id = H2.history_chapter_id - GROUP BY C2.manga_id -) AS max_last_read -ON C.manga_id = max_last_read.manga_id -AND max_last_read.history_chapter_id = H.history_chapter_id -AND max_last_read.history_last_read > 0 -LEFT JOIN scanlators_view AS S -ON C.manga_id = S.manga_id -AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '//') -- I assume if it's N/A it shouldn't be filtered -WHERE lower(M.title) LIKE '%' || :search || '%' -AND ( - :apply_filter = 0 OR S.name IS NULL -) -ORDER BY max_last_read.history_last_read DESC -LIMIT :limit OFFSET :offset; - getScanlatorsByMangaId: SELECT scanlator FROM chapters diff --git a/data/src/commonMain/sqldelight/tachiyomi/data/history.sq b/data/src/commonMain/sqldelight/tachiyomi/data/history.sq index 0e4efe018c..8556216296 100644 --- a/data/src/commonMain/sqldelight/tachiyomi/data/history.sq +++ b/data/src/commonMain/sqldelight/tachiyomi/data/history.sq @@ -8,3 +8,57 @@ CREATE TABLE history( ); CREATE INDEX history_history_chapter_id_index ON history(history_chapter_id); + +getRecentsUngrouped: +SELECT + M.*, + C.*, + H.* +FROM mangas AS M +JOIN chapters AS C +ON M._id = C.manga_id +JOIN history AS H +ON C._id = H.history_chapter_id +AND H.history_last_read > 0 +LEFT JOIN scanlators_view AS S +ON C.manga_id = S.manga_id +AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '//') -- I assume if it's N/A it shouldn't be filtered +WHERE lower(M.title) LIKE '%' || :search || '%' +AND ( + :apply_filter = 0 OR S.name IS NULL +) +ORDER BY H.history_last_read DESC +LIMIT :limit OFFSET :offset; + +getRecentsBySeries: +SELECT + M.url AS mangaUrl, + M.*, + C.*, + H.* +FROM mangas AS M +JOIN chapters AS C +ON M._id = C.manga_id +JOIN history AS H +ON C._id = H.history_chapter_id +JOIN ( + SELECT + C2.manga_id AS manga_id, + C2._id AS history_chapter_id, + MAX(H2.history_last_read) AS history_last_read + FROM chapters AS C2 JOIN history AS H2 + ON C2._id = H2.history_chapter_id + GROUP BY C2.manga_id +) AS max_last_read +ON C.manga_id = max_last_read.manga_id +AND max_last_read.history_chapter_id = H.history_chapter_id +AND max_last_read.history_last_read > 0 +LEFT JOIN scanlators_view AS S +ON C.manga_id = S.manga_id +AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '//') -- I assume if it's N/A it shouldn't be filtered +WHERE lower(M.title) LIKE '%' || :search || '%' +AND ( + :apply_filter = 0 OR S.name IS NULL +) +ORDER BY max_last_read.history_last_read DESC +LIMIT :limit OFFSET :offset;