refactor(recents): Migrate getRecentChapters to SQLDelight

This commit is contained in:
Ahmad Ansori Palembani 2024-08-16 19:46:14 +07:00
parent eb8727afcf
commit a6ef46a90f
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
10 changed files with 139 additions and 31 deletions

View file

@ -2,4 +2,78 @@ package eu.kanade.tachiyomi.data.database.models
import eu.kanade.tachiyomi.domain.manga.models.Manga
class MangaChapter(val manga: Manga, val chapter: Chapter)
class MangaChapter(val manga: Manga, val chapter: Chapter) {
companion object {
fun mapper(
mangaId: Long,
source: Long,
mangaUrl: String,
artist: String?,
author: String?,
description: String?,
genre: String?,
title: String,
status: Long,
thumbnailUrl: String?,
favorite: Long,
lastUpdate: Long?,
initialized: Boolean,
viewer: Long,
hideTitle: Long,
chapterFlags: Long,
dateAdded: Long?,
filteredScanlators: String?,
updateStrategy: Long,
chapterId: Long,
_mangaId: Long,
chapterUrl: String,
name: String,
scanlator: String?,
read: Boolean,
bookmark: Boolean,
lastPageRead: Long,
pagesLeft: Long,
chapterNumber: Double,
sourceOrder: Long,
dateFetch: Long,
dateUpload: Long,
) = MangaChapter(
Manga.mapper(
id = mangaId,
source = source,
url = mangaUrl,
artist = artist,
author = author,
description = description,
genre = genre,
title = title,
status = status,
thumbnailUrl = thumbnailUrl,
favorite = favorite,
lastUpdate = lastUpdate,
initialized = initialized,
viewerFlags = viewer,
hideTitle = hideTitle,
chapterFlags = chapterFlags,
dateAdded = dateAdded,
filteredScanlators = filteredScanlators,
updateStrategy = updateStrategy,
),
Chapter.mapper(
id = chapterId,
mangaId = _mangaId,
url = chapterUrl,
name = name,
scanlator = scanlator,
read = read,
bookmark = bookmark,
lastPageRead = lastPageRead,
pagesLeft = pagesLeft,
chapterNumber = chapterNumber,
sourceOrder = sourceOrder,
dateFetch = dateFetch,
dateUpload = dateUpload,
),
)
}
}

View file

@ -1,16 +1,12 @@
package eu.kanade.tachiyomi.data.database.queries
import com.pushtorefresh.storio.sqlite.queries.Query
import com.pushtorefresh.storio.sqlite.queries.RawQuery
import eu.kanade.tachiyomi.data.database.DbProvider
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.data.database.resolvers.ChapterKnownBackupPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.ChapterProgressPutResolver
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterGetResolver
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
import eu.kanade.tachiyomi.domain.manga.models.Manga
import eu.kanade.tachiyomi.util.lang.sqLite
interface ChapterQueries : DbProvider {
@ -27,17 +23,6 @@ interface ChapterQueries : DbProvider {
)
.prepare()
fun getRecentChapters(search: String = "", offset: Int, isResuming: Boolean) = db.get()
.listOfObjects(MangaChapter::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentsQuery(search.sqLite, offset, isResuming))
.observesTables(ChapterTable.TABLE)
.build(),
)
.withGetResolver(MangaChapterGetResolver.INSTANCE)
.prepare()
fun getChapter(id: Long) = db.get()
.`object`(Chapter::class.java)
.withQuery(

View file

@ -22,6 +22,14 @@ import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.system.withUIContext
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.TreeMap
import java.util.concurrent.TimeUnit
import kotlin.math.abs
import kotlin.math.roundToInt
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.drop
@ -33,14 +41,10 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.RecentChapter
import yokai.domain.recents.RecentsPreferences
import yokai.domain.ui.UiPreferences
import yokai.i18n.MR
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.*
import kotlin.math.abs
import kotlin.math.roundToInt
class RecentsPresenter(
val uiPreferences: UiPreferences = Injekt.get(),
@ -51,6 +55,7 @@ class RecentsPresenter(
private val chapterFilter: ChapterFilter = Injekt.get(),
) : BaseCoroutinePresenter<RecentsController>(), DownloadQueue.DownloadListener {
private val getChapter: GetChapter by injectLazy()
private val recentChapter: RecentChapter by injectLazy()
private var recentsJob: Job? = null
var recentItems = listOf<RecentMangaItem>()
@ -235,11 +240,12 @@ class RecentsPresenter(
dateFormat.applyPattern("yyyy-MM-dd")
dateFormat.calendar.firstDayOfWeek =
Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
db.getRecentChapters(
query,
if (isCustom) ENDLESS_LIMIT else pageOffset,
recentChapter.await(
true,
!updatePageCount && !isOnFirstPage,
).executeOnIO().groupBy {
query,
(if (isCustom) ENDLESS_LIMIT else pageOffset).toLong(),
).groupBy {
val date = it.chapter.date_fetch
it.manga.id to if (date <= 0L) "-1" else dateFormat.format(Date(date))
}

View file

@ -17,6 +17,7 @@ import yokai.domain.chapter.interactor.DeleteChapter
import yokai.domain.chapter.interactor.GetAvailableScanlators
import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.InsertChapter
import yokai.domain.chapter.interactor.RecentChapter
import yokai.domain.chapter.interactor.UpdateChapter
import yokai.domain.extension.interactor.TrustExtension
import yokai.domain.extension.repo.ExtensionRepoRepository
@ -66,6 +67,7 @@ class DomainModule : InjektModule {
addFactory { GetAvailableScanlators(get()) }
addFactory { GetChapter(get()) }
addFactory { InsertChapter(get()) }
addFactory { RecentChapter(get()) }
addFactory { UpdateChapter(get()) }
addSingletonFactory<CategoryRepository> { CategoryRepositoryImpl(get()) }

View file

@ -2,6 +2,7 @@ package yokai.data.chapter
import co.touchlab.kermit.Logger
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.util.system.toInt
import kotlinx.coroutines.flow.Flow
import yokai.data.DatabaseHandler
@ -15,6 +16,9 @@ class ChapterRepositoryImpl(private val handler: DatabaseHandler) : ChapterRepos
override fun getChaptersAsFlow(mangaId: Long, filterScanlators: Boolean): Flow<List<Chapter>> =
handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, filterScanlators.toInt().toLong(), Chapter::mapper) }
override suspend fun getRecents(filterScanlators: Boolean, search: String, limit: Long, offset: Long): List<MangaChapter> =
handler.awaitList { chaptersQueries.getRecents(search, filterScanlators.toInt().toLong(), limit, offset, MangaChapter::mapper) }
override suspend fun getScanlatorsByChapter(mangaId: Long): List<String> =
handler.awaitList { chaptersQueries.getScanlatorsByMangaId(mangaId) { it.orEmpty() } }

View file

@ -1,6 +1,7 @@
package yokai.domain.chapter
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import kotlinx.coroutines.flow.Flow
import yokai.domain.chapter.models.ChapterUpdate
@ -8,6 +9,8 @@ interface ChapterRepository {
suspend fun getChapters(mangaId: Long, filterScanlators: Boolean): List<Chapter>
fun getChaptersAsFlow(mangaId: Long, filterScanlators: Boolean): Flow<List<Chapter>>
suspend fun getRecents(filterScanlators: Boolean, search: String = "", limit: Long = 25L, offset: Long = 0L): List<MangaChapter>
suspend fun getScanlatorsByChapter(mangaId: Long): List<String>
fun getScanlatorsByChapterAsFlow(mangaId: Long): Flow<List<String>>

View file

@ -0,0 +1,21 @@
package yokai.domain.chapter.interactor
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.util.lang.sqLite
import yokai.domain.chapter.ChapterRepository
import yokai.util.limitAndOffset
class RecentChapter(
private val chapterRepository: ChapterRepository,
) {
suspend fun await(filterScanlators: Boolean, isResuming: Boolean, search: String = "", offset: Long = 0L): List<MangaChapter> {
val (limit, actualOffset) = limitAndOffset(true, isResuming, offset)
return chapterRepository.getRecents(
filterScanlators,
"%${search.sqLite}%",
limit,
actualOffset,
)
}
}

View file

@ -0,0 +1,17 @@
package yokai.util
import eu.kanade.tachiyomi.ui.recents.RecentsPresenter
fun limitAndOffset(isEndless: Boolean, isResuming: Boolean, offset: Long): Pair<Long, Long> {
return when {
isResuming && isEndless && offset > 0 -> {
offset to 0L
}
isEndless -> {
RecentsPresenter.ENDLESS_LIMIT.toLong() to offset
}
else -> {
RecentsPresenter.SHORT_LIMIT.toLong() to 0L
}
}
}

View file

@ -34,7 +34,6 @@ AND (
getRecents:
SELECT
M.url AS mangaUrl,
M.*,
C.*
FROM mangas AS M
@ -54,7 +53,6 @@ LIMIT :limit OFFSET :offset;
getRecentsUngrouped:
SELECT
M.url AS mangaUrl,
M.*,
C.*,
H.*

View file

@ -1,10 +1,8 @@
import kotlin.Long;
CREATE TABLE history(
history_id INTEGER NOT NULL PRIMARY KEY,
history_chapter_id INTEGER NOT NULL UNIQUE,
history_last_read INTEGER AS Long,
history_time_read INTEGER AS Long,
history_last_read INTEGER,
history_time_read INTEGER,
FOREIGN KEY(history_chapter_id) REFERENCES chapters (_id)
ON DELETE CASCADE
);