Use SQLDelight for all Chapter related queries (#7440)

This commit is contained in:
Andreas 2022-07-03 00:51:33 +02:00 committed by GitHub
parent 76c0ead1db
commit 29633b64aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 65 deletions

View file

@ -99,4 +99,8 @@ class ChapterRepositoryImpl(
override suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> { override suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> {
return handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) } return handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
} }
override suspend fun getChapterByUrlAndMangaId(url: String, mangaId: Long): Chapter? {
return handler.awaitOneOrNull { chaptersQueries.getChapterByUrlAndMangaId(url, mangaId, chapterMapper) }
}
} }

View file

@ -17,4 +17,13 @@ class GetChapter(
null null
} }
} }
suspend fun await(url: String, mangaId: Long): Chapter? {
return try {
chapterRepository.getChapterByUrlAndMangaId(url, mangaId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
null
}
}
} }

View file

@ -19,4 +19,6 @@ interface ChapterRepository {
suspend fun getChapterById(id: Long): Chapter? suspend fun getChapterById(id: Long): Chapter?
suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>>
suspend fun getChapterByUrlAndMangaId(url: String, mangaId: Long): Chapter?
} }

View file

@ -8,7 +8,6 @@ import eu.kanade.tachiyomi.data.database.mappers.MangaTypeMapping
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.database.queries.ChapterQueries
import eu.kanade.tachiyomi.data.database.queries.MangaCategoryQueries import eu.kanade.tachiyomi.data.database.queries.MangaCategoryQueries
import eu.kanade.tachiyomi.data.database.queries.MangaQueries import eu.kanade.tachiyomi.data.database.queries.MangaQueries
@ -18,7 +17,7 @@ import eu.kanade.tachiyomi.data.database.queries.MangaQueries
class DatabaseHelper( class DatabaseHelper(
openHelper: SupportSQLiteOpenHelper, openHelper: SupportSQLiteOpenHelper,
) : ) :
MangaQueries, ChapterQueries, MangaCategoryQueries { MangaQueries, MangaCategoryQueries {
override val db = DefaultStorIOSQLite.builder() override val db = DefaultStorIOSQLite.builder()
.sqliteOpenHelper(openHelper) .sqliteOpenHelper(openHelper)

View file

@ -1,37 +0,0 @@
package eu.kanade.tachiyomi.data.database.queries
import com.pushtorefresh.storio.sqlite.queries.Query
import eu.kanade.tachiyomi.data.database.DbProvider
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.resolvers.ChapterProgressPutResolver
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
interface ChapterQueries : DbProvider {
fun getChapter(id: Long) = db.get()
.`object`(Chapter::class.java)
.withQuery(
Query.builder()
.table(ChapterTable.TABLE)
.where("${ChapterTable.COL_ID} = ?")
.whereArgs(id)
.build(),
)
.prepare()
fun getChapter(url: String, mangaId: Long) = db.get()
.`object`(Chapter::class.java)
.withQuery(
Query.builder()
.table(ChapterTable.TABLE)
.where("${ChapterTable.COL_URL} = ? AND ${ChapterTable.COL_MANGA_ID} = ?")
.whereArgs(url, mangaId)
.build(),
)
.prepare()
fun updateChapterProgress(chapter: Chapter) = db.put()
.`object`(chapter)
.withPutResolver(ChapterProgressPutResolver())
.prepare()
}

View file

@ -2,11 +2,15 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.domain.chapter.interactor.GetChapter
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.manga.interactor.GetMangaById
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
@ -29,7 +33,9 @@ class DownloadStore(
private val preferences = context.getSharedPreferences("active_downloads", Context.MODE_PRIVATE) private val preferences = context.getSharedPreferences("active_downloads", Context.MODE_PRIVATE)
private val json: Json by injectLazy() private val json: Json by injectLazy()
private val db: DatabaseHelper by injectLazy()
private val getMangaById: GetMangaById by injectLazy()
private val getChapter: GetChapter by injectLazy()
/** /**
* Counter used to keep the queue order. * Counter used to keep the queue order.
@ -90,10 +96,10 @@ class DownloadStore(
val cachedManga = mutableMapOf<Long, Manga?>() val cachedManga = mutableMapOf<Long, Manga?>()
for ((mangaId, chapterId) in objs) { for ((mangaId, chapterId) in objs) {
val manga = cachedManga.getOrPut(mangaId) { val manga = cachedManga.getOrPut(mangaId) {
db.getManga(mangaId).executeAsBlocking() runBlocking { getMangaById.await(mangaId)?.toDbManga() }
} ?: continue } ?: continue
val source = sourceManager.get(manga.source) as? HttpSource ?: continue val source = sourceManager.get(manga.source) as? HttpSource ?: continue
val chapter = db.getChapter(chapterId).executeAsBlocking() ?: continue val chapter = runBlocking { getChapter.await(chapterId) }?.toDbChapter() ?: continue
downloads.add(Download(source, manga, chapter)) downloads.add(Download(source, manga, chapter))
} }
} }

View file

@ -7,9 +7,14 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import eu.kanade.domain.chapter.interactor.GetChapter
import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.toChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.manga.interactor.GetMangaById
import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupRestoreService import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
@ -27,6 +32,7 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
import eu.kanade.tachiyomi.util.system.toShareIntent import eu.kanade.tachiyomi.util.system.toShareIntent
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
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
@ -40,6 +46,9 @@ import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
*/ */
class NotificationReceiver : BroadcastReceiver() { class NotificationReceiver : BroadcastReceiver() {
private val getMangaById: GetMangaById by injectLazy()
private val getChapter: GetChapter by injectLazy()
private val updateChapter: UpdateChapter by injectLazy()
private val downloadManager: DownloadManager by injectLazy() private val downloadManager: DownloadManager by injectLazy()
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
@ -169,9 +178,8 @@ class NotificationReceiver : BroadcastReceiver() {
* @param chapterId id of chapter * @param chapterId id of chapter
*/ */
private fun openChapter(context: Context, mangaId: Long, chapterId: Long) { private fun openChapter(context: Context, mangaId: Long, chapterId: Long) {
val db = Injekt.get<DatabaseHelper>() val manga = runBlocking { getMangaById.await(mangaId) }
val manga = db.getManga(mangaId).executeAsBlocking() val chapter = runBlocking { getChapter.await(chapterId) }
val chapter = db.getChapter(chapterId).executeAsBlocking()
if (manga != null && chapter != null) { if (manga != null && chapter != null) {
val intent = ReaderActivity.newIntent(context, manga.id, chapter.id).apply { val intent = ReaderActivity.newIntent(context, manga.id, chapter.id).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
@ -232,25 +240,25 @@ class NotificationReceiver : BroadcastReceiver() {
* @param mangaId id of manga * @param mangaId id of manga
*/ */
private fun markAsRead(chapterUrls: Array<String>, mangaId: Long) { private fun markAsRead(chapterUrls: Array<String>, mangaId: Long) {
val db: DatabaseHelper = Injekt.get()
val preferences: PreferencesHelper = Injekt.get() val preferences: PreferencesHelper = Injekt.get()
val sourceManager: SourceManager = Injekt.get() val sourceManager: SourceManager = Injekt.get()
launchIO { launchIO {
chapterUrls.mapNotNull { db.getChapter(it, mangaId).executeAsBlocking() } val toUpdate = chapterUrls.mapNotNull { getChapter.await(it, mangaId) }
.forEach { .map {
it.read = true val chapter = it.copy(read = true)
db.updateChapterProgress(it).executeAsBlocking()
if (preferences.removeAfterMarkedAsRead()) { if (preferences.removeAfterMarkedAsRead()) {
val manga = db.getManga(mangaId).executeAsBlocking() val manga = getMangaById.await(mangaId)
if (manga != null) { if (manga != null) {
val source = sourceManager.get(manga.source) val source = sourceManager.get(manga.source)
if (source != null) { if (source != null) {
downloadManager.deleteChapters(listOf(it), manga, source) downloadManager.deleteChapters(listOf(it.toDbChapter()), manga.toDbManga(), source)
} }
} }
} }
chapter.toChapterUpdate()
} }
updateChapter.awaitAll(toUpdate)
} }
} }
@ -261,12 +269,10 @@ class NotificationReceiver : BroadcastReceiver() {
* @param mangaId id of manga * @param mangaId id of manga
*/ */
private fun downloadChapters(chapterUrls: Array<String>, mangaId: Long) { private fun downloadChapters(chapterUrls: Array<String>, mangaId: Long) {
val db: DatabaseHelper = Injekt.get()
launchIO { launchIO {
val chapters = chapterUrls.mapNotNull { db.getChapter(it, mangaId).executeAsBlocking() } val manga = getMangaById.await(mangaId)?.toDbManga()
val manga = db.getManga(mangaId).executeAsBlocking() val chapters = chapterUrls.mapNotNull { getChapter.await(it, mangaId)?.toDbChapter() }
if (chapters.isNotEmpty() && manga != null) { if (manga != null && chapters.isNotEmpty()) {
downloadManager.downloadChapters(manga, chapters) downloadManager.downloadChapters(manga, chapters)
} }
} }

View file

@ -540,13 +540,16 @@ class ReaderPresenter(
* Bookmarks the currently active chapter. * Bookmarks the currently active chapter.
*/ */
fun bookmarkCurrentChapter(bookmarked: Boolean) { fun bookmarkCurrentChapter(bookmarked: Boolean) {
if (getCurrentChapter()?.chapter == null) { val chapter = getCurrentChapter()?.chapter ?: return
return chapter.bookmark = bookmarked // Otherwise the bookmark icon doesn't update
launchIO {
updateChapter.await(
ChapterUpdate(
id = chapter.id!!.toLong(),
bookmark = bookmarked,
),
)
} }
val chapter = getCurrentChapter()?.chapter!!
chapter.bookmark = bookmarked
db.updateChapterProgress(chapter).executeAsBlocking()
} }
/** /**

View file

@ -33,6 +33,12 @@ SELECT *
FROM chapters FROM chapters
WHERE url = :chapterUrl; WHERE url = :chapterUrl;
getChapterByUrlAndMangaId:
SELECT *
FROM chapters
WHERE url = :chapterUrl
AND manga_id = :mangaId;
removeChaptersWithIds: removeChaptersWithIds:
DELETE FROM chapters DELETE FROM chapters
WHERE _id IN :chapterIds; WHERE _id IN :chapterIds;