chore: Preparing to migrate History to SQLDelight

This commit is contained in:
Ahmad Ansori Palembani 2024-08-24 07:27:33 +07:00
parent 10b9fa53a6
commit 61e43e047f
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
5 changed files with 82 additions and 67 deletions

View file

@ -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<History>() {
class HistoryGetResolver : DefaultGetResolver<History>() {
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<History>() {

View file

@ -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
}
}
}

View file

@ -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

View file

@ -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, '/<INVALID>/') -- 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, '/<INVALID>/') -- 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

View file

@ -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, '/<INVALID>/') -- 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, '/<INVALID>/') -- 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;