Update manga metadata on library update with sqldelight
(#7293)
Co-Authored-By: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
This commit is contained in:
parent
5fbf454652
commit
5bb78eb77f
13 changed files with 220 additions and 96 deletions
|
@ -1,7 +1,10 @@
|
|||
package eu.kanade.data.manga
|
||||
|
||||
import eu.kanade.data.DatabaseHandler
|
||||
import eu.kanade.data.listOfStringsAdapter
|
||||
import eu.kanade.data.toLong
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -11,6 +14,10 @@ class MangaRepositoryImpl(
|
|||
private val handler: DatabaseHandler,
|
||||
) : MangaRepository {
|
||||
|
||||
override suspend fun getMangaById(id: Long): Manga {
|
||||
return handler.awaitOne { mangasQueries.getMangaById(id, mangaMapper) }
|
||||
}
|
||||
|
||||
override fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>> {
|
||||
return handler.subscribeToList { mangasQueries.getFavoriteBySourceId(sourceId, mangaMapper) }
|
||||
}
|
||||
|
@ -25,11 +32,33 @@ class MangaRepositoryImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun updateLastUpdate(mangaId: Long, lastUpdate: Long) {
|
||||
try {
|
||||
handler.await { mangasQueries.updateLastUpdate(lastUpdate, mangaId) }
|
||||
override suspend fun update(update: MangaUpdate): Boolean {
|
||||
return try {
|
||||
handler.await {
|
||||
mangasQueries.update(
|
||||
source = update.source,
|
||||
url = update.url,
|
||||
artist = update.artist,
|
||||
author = update.author,
|
||||
description = update.description,
|
||||
genre = update.genre?.let(listOfStringsAdapter::encode),
|
||||
title = update.title,
|
||||
status = update.status,
|
||||
thumbnailUrl = update.thumbnailUrl,
|
||||
favorite = update.favorite?.toLong(),
|
||||
lastUpdate = update.lastUpdate,
|
||||
initialized = update.initialized?.toLong(),
|
||||
viewer = update.viewerFlags,
|
||||
chapterFlags = update.chapterFlags,
|
||||
coverLastModified = update.coverLastModified,
|
||||
dateAdded = update.dateAdded,
|
||||
mangaId = update.id,
|
||||
)
|
||||
}
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,9 @@ import eu.kanade.domain.history.interactor.RemoveHistoryByMangaId
|
|||
import eu.kanade.domain.history.interactor.UpsertHistory
|
||||
import eu.kanade.domain.history.repository.HistoryRepository
|
||||
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
||||
import eu.kanade.domain.manga.interactor.UpdateMangaLastUpdate
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.domain.source.interactor.GetEnabledSources
|
||||
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
||||
|
@ -43,9 +44,10 @@ class DomainModule : InjektModule {
|
|||
override fun InjektRegistrar.registerInjectables() {
|
||||
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
||||
addFactory { GetFavoritesBySourceId(get()) }
|
||||
addFactory { GetMangaById(get()) }
|
||||
addFactory { GetNextChapter(get()) }
|
||||
addFactory { ResetViewerFlags(get()) }
|
||||
addFactory { UpdateMangaLastUpdate(get()) }
|
||||
addFactory { UpdateManga(get()) }
|
||||
|
||||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||
addFactory { UpdateChapter(get()) }
|
||||
|
|
|
@ -5,7 +5,7 @@ import eu.kanade.domain.chapter.model.Chapter
|
|||
import eu.kanade.domain.chapter.model.toChapterUpdate
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||
import eu.kanade.domain.manga.interactor.UpdateMangaLastUpdate
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
|
@ -24,7 +24,7 @@ class SyncChaptersWithSource(
|
|||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val chapterRepository: ChapterRepository = Injekt.get(),
|
||||
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
|
||||
private val updateMangaLastUpdate: UpdateMangaLastUpdate = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
) {
|
||||
|
||||
suspend fun await(
|
||||
|
@ -171,7 +171,7 @@ class SyncChaptersWithSource(
|
|||
|
||||
// Set this manga as updated since chapters were changed
|
||||
// Note that last_update actually represents last time the chapter list changed at all
|
||||
updateMangaLastUpdate.await(manga.id, Date().time)
|
||||
updateManga.awaitUpdateLastUpdate(manga.id)
|
||||
|
||||
@Suppress("ConvertArgumentToSet") // See tachiyomiorg/tachiyomi#6372.
|
||||
return Pair(updatedToAdd.subtract(reAdded).toList(), toDelete.subtract(reAdded).toList())
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import logcat.LogPriority
|
||||
|
||||
class GetMangaById(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(id: Long): Manga? {
|
||||
return try {
|
||||
mangaRepository.getMangaById(id)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
import eu.kanade.domain.manga.model.hasCustomCover
|
||||
import eu.kanade.domain.manga.model.isLocal
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
import java.util.Date
|
||||
|
||||
class UpdateManga(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun awaitUpdateFromSource(
|
||||
localManga: Manga,
|
||||
remoteManga: MangaInfo,
|
||||
manualFetch: Boolean,
|
||||
coverCache: CoverCache,
|
||||
): Boolean {
|
||||
// if the manga isn't a favorite, set its title from source and update in db
|
||||
val title = if (!localManga.favorite) remoteManga.title else null
|
||||
|
||||
// Never refresh covers if the url is empty to avoid "losing" existing covers
|
||||
val updateCover = remoteManga.cover.isNotEmpty() && (manualFetch || localManga.thumbnailUrl != remoteManga.cover)
|
||||
val coverLastModified = if (updateCover) {
|
||||
when {
|
||||
localManga.isLocal() -> Date().time
|
||||
localManga.hasCustomCover(coverCache) -> {
|
||||
coverCache.deleteFromCache(localManga.toDbManga(), false)
|
||||
null
|
||||
}
|
||||
else -> {
|
||||
coverCache.deleteFromCache(localManga.toDbManga(), false)
|
||||
Date().time
|
||||
}
|
||||
}
|
||||
} else null
|
||||
|
||||
return mangaRepository.update(
|
||||
MangaUpdate(
|
||||
id = localManga.id,
|
||||
title = title?.takeIf { it.isNotEmpty() },
|
||||
coverLastModified = coverLastModified,
|
||||
author = remoteManga.author,
|
||||
artist = remoteManga.artist,
|
||||
description = remoteManga.description,
|
||||
genre = remoteManga.genres,
|
||||
thumbnailUrl = remoteManga.cover.takeIf { it.isNotEmpty() },
|
||||
status = remoteManga.status.toLong(),
|
||||
initialized = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean {
|
||||
return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Date().time))
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
|
||||
class UpdateMangaLastUpdate(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(mangaId: Long, lastUpdate: Long) {
|
||||
mangaRepository.updateLastUpdate(mangaId, lastUpdate)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,11 @@
|
|||
package eu.kanade.domain.manga.model
|
||||
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga as DbManga
|
||||
|
||||
data class Manga(
|
||||
|
@ -62,3 +67,20 @@ fun Manga.toDbManga(): DbManga = DbManga.create(url, title, source).also {
|
|||
it.chapter_flags = chapterFlags.toInt()
|
||||
it.cover_last_modified = coverLastModified
|
||||
}
|
||||
|
||||
fun Manga.toMangaInfo(): MangaInfo = MangaInfo(
|
||||
artist = artist ?: "",
|
||||
author = author ?: "",
|
||||
cover = thumbnailUrl ?: "",
|
||||
description = description ?: "",
|
||||
genres = genre ?: emptyList(),
|
||||
key = url,
|
||||
status = status.toInt(),
|
||||
title = title,
|
||||
)
|
||||
|
||||
fun Manga.isLocal(): Boolean = source == LocalSource.ID
|
||||
|
||||
fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean {
|
||||
return coverCache.getCustomCoverFile(id).exists()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package eu.kanade.domain.manga.model
|
||||
|
||||
data class MangaUpdate(
|
||||
val id: Long,
|
||||
val source: Long? = null,
|
||||
val favorite: Boolean? = null,
|
||||
val lastUpdate: Long? = null,
|
||||
val dateAdded: Long? = null,
|
||||
val viewerFlags: Long? = null,
|
||||
val chapterFlags: Long? = null,
|
||||
val coverLastModified: Long? = null,
|
||||
val url: String? = null,
|
||||
val title: String? = null,
|
||||
val artist: String? = null,
|
||||
val author: String? = null,
|
||||
val description: String? = null,
|
||||
val genre: List<String>? = null,
|
||||
val status: Long? = null,
|
||||
val thumbnailUrl: String? = null,
|
||||
val initialized: Boolean? = null,
|
||||
)
|
|
@ -1,13 +1,16 @@
|
|||
package eu.kanade.domain.manga.repository
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface MangaRepository {
|
||||
|
||||
suspend fun getMangaById(id: Long): Manga
|
||||
|
||||
fun getFavoritesBySourceId(sourceId: Long): Flow<List<Manga>>
|
||||
|
||||
suspend fun resetViewerFlags(): Boolean
|
||||
|
||||
suspend fun updateLastUpdate(mangaId: Long, lastUpdate: Long)
|
||||
suspend fun update(update: MangaUpdate): Boolean
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import eu.kanade.tachiyomi.data.database.resolvers.LibraryMangaGetResolver
|
|||
import eu.kanade.tachiyomi.data.database.resolvers.MangaCoverLastModifiedPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaFlagsPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaLastUpdatedPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable
|
||||
|
@ -101,11 +100,6 @@ interface MangaQueries : DbProvider {
|
|||
.withPutResolver(MangaFlagsPutResolver(MangaTable.COL_VIEWER, Manga::viewer_flags))
|
||||
.prepare()
|
||||
|
||||
fun updateLastUpdated(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaLastUpdatedPutResolver())
|
||||
.prepare()
|
||||
|
||||
fun updateMangaFavorite(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaFavoritePutResolver())
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
|
||||
class MangaLastUpdatedPutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) =
|
||||
contentValuesOf(
|
||||
MangaTable.COL_LAST_UPDATE to manga.last_update,
|
||||
)
|
||||
}
|
|
@ -7,6 +7,11 @@ import android.os.IBinder
|
|||
import android.os.PowerManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import eu.kanade.data.chapter.NoChaptersException
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toMangaInfo
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
|
@ -14,6 +19,7 @@ import eu.kanade.tachiyomi.data.database.models.Category
|
|||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
|
@ -29,10 +35,8 @@ import eu.kanade.tachiyomi.data.track.TrackService
|
|||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.UnmeteredSource
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.model.toMangaInfo
|
||||
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||
import eu.kanade.tachiyomi.source.model.toSManga
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithTrackServiceTwoWay
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import eu.kanade.tachiyomi.util.prepUpdateCover
|
||||
|
@ -55,12 +59,15 @@ import kotlinx.coroutines.supervisorScope
|
|||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import eu.kanade.domain.chapter.model.Chapter as DomainChapter
|
||||
import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
|
||||
/**
|
||||
* This class will take care of updating the chapters of the manga from the library. It can be
|
||||
|
@ -77,6 +84,9 @@ class LibraryUpdateService(
|
|||
val downloadManager: DownloadManager = Injekt.get(),
|
||||
val trackManager: TrackManager = Injekt.get(),
|
||||
val coverCache: CoverCache = Injekt.get(),
|
||||
private val getMangaById: GetMangaById = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||
) : Service() {
|
||||
|
||||
private lateinit var wakeLock: PowerManager.WakeLock
|
||||
|
@ -302,7 +312,7 @@ class LibraryUpdateService(
|
|||
}
|
||||
|
||||
// Don't continue to update if manga not in library
|
||||
db.getManga(manga.id!!).executeAsBlocking() ?: return@forEach
|
||||
manga.id?.let { getMangaById.await(it) } ?: return@forEach
|
||||
|
||||
withUpdateNotification(
|
||||
currentlyUpdatingManga,
|
||||
|
@ -322,22 +332,25 @@ class LibraryUpdateService(
|
|||
|
||||
else -> {
|
||||
// Convert to the manga that contains new chapters
|
||||
val (newChapters, _) = updateManga(mangaWithNotif)
|
||||
mangaWithNotif.toDomainManga()?.let { domainManga ->
|
||||
val (newChapters, _) = updateManga(domainManga)
|
||||
val newDbChapters = newChapters.map { it.toDbChapter() }
|
||||
|
||||
if (newChapters.isNotEmpty()) {
|
||||
if (mangaWithNotif.shouldDownloadNewChapters(db, preferences)) {
|
||||
downloadChapters(mangaWithNotif, newChapters)
|
||||
downloadChapters(mangaWithNotif, newDbChapters)
|
||||
hasDownloads.set(true)
|
||||
}
|
||||
|
||||
// Convert to the manga that contains new chapters
|
||||
newUpdates.add(
|
||||
mangaWithNotif to newChapters.sortedByDescending { ch -> ch.source_order }
|
||||
mangaWithNotif to newDbChapters.sortedByDescending { ch -> ch.source_order }
|
||||
.toTypedArray(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
val errorMessage = when (e) {
|
||||
is NoChaptersException -> getString(R.string.no_chapters_error)
|
||||
|
@ -394,39 +407,27 @@ class LibraryUpdateService(
|
|||
* @param manga the manga to update.
|
||||
* @return a pair of the inserted and removed chapters.
|
||||
*/
|
||||
private suspend fun updateManga(manga: Manga): Pair<List<Chapter>, List<Chapter>> {
|
||||
private suspend fun updateManga(manga: DomainManga): Pair<List<DomainChapter>, List<DomainChapter>> {
|
||||
val source = sourceManager.getOrStub(manga.source)
|
||||
|
||||
var updatedManga: SManga = manga
|
||||
val mangaInfo: MangaInfo = manga.toMangaInfo()
|
||||
|
||||
// Update manga details metadata
|
||||
// Update manga metadata if needed
|
||||
if (preferences.autoUpdateMetadata()) {
|
||||
val updatedMangaDetails = source.getMangaDetails(manga.toMangaInfo())
|
||||
val sManga = updatedMangaDetails.toSManga()
|
||||
// Avoid "losing" existing cover
|
||||
if (!sManga.thumbnail_url.isNullOrEmpty()) {
|
||||
manga.prepUpdateCover(coverCache, sManga, false)
|
||||
} else {
|
||||
sManga.thumbnail_url = manga.thumbnail_url
|
||||
val updatedMangaInfo = source.getMangaDetails(manga.toMangaInfo())
|
||||
updateManga.awaitUpdateFromSource(manga, updatedMangaInfo, manualFetch = false, coverCache)
|
||||
}
|
||||
|
||||
updatedManga = sManga
|
||||
}
|
||||
|
||||
val chapters = source.getChapterList(updatedManga.toMangaInfo())
|
||||
val chapters = source.getChapterList(mangaInfo)
|
||||
.map { it.toSChapter() }
|
||||
|
||||
// Get manga from database to account for if it was removed during the update
|
||||
val dbManga = db.getManga(manga.id!!).executeAsBlocking()
|
||||
val dbManga = getMangaById.await(manga.id)
|
||||
?: return Pair(emptyList(), emptyList())
|
||||
|
||||
// Copy into [dbManga] to retain favourite value
|
||||
dbManga.copyFrom(updatedManga)
|
||||
db.insertManga(dbManga).executeAsBlocking()
|
||||
|
||||
// [dbmanga] was used so that manga data doesn't get overwritten
|
||||
// in case manga gets new chapter
|
||||
return syncChaptersWithSource(chapters, dbManga, source)
|
||||
return syncChaptersWithSource.await(chapters, dbManga, source)
|
||||
}
|
||||
|
||||
private suspend fun updateCovers() {
|
||||
|
|
|
@ -58,7 +58,22 @@ deleteMangasNotInLibraryBySourceIds:
|
|||
DELETE FROM mangas
|
||||
WHERE favorite = 0 AND source IN :sourceIds;
|
||||
|
||||
updateLastUpdate:
|
||||
UPDATE mangas
|
||||
SET last_update = :lastUpdate
|
||||
update:
|
||||
UPDATE mangas SET
|
||||
source = coalesce(:source, source),
|
||||
url = coalesce(:url, url),
|
||||
artist = coalesce(:artist, artist),
|
||||
author = coalesce(:author, author),
|
||||
description = coalesce(:description, description),
|
||||
genre = coalesce(:genre, genre),
|
||||
title = coalesce(:title, title),
|
||||
status = coalesce(:status, status),
|
||||
thumbnail_url = coalesce(:thumbnailUrl, thumbnail_url),
|
||||
favorite = coalesce(:favorite, favorite),
|
||||
last_update = coalesce(:lastUpdate, last_update),
|
||||
initialized = coalesce(:initialized, initialized),
|
||||
viewer = coalesce(:viewer, viewer),
|
||||
chapter_flags = coalesce(:chapterFlags, chapter_flags),
|
||||
cover_last_modified = coalesce(:coverLastModified, cover_last_modified),
|
||||
date_added = coalesce(:dateAdded, date_added)
|
||||
WHERE _id = :mangaId;
|
||||
|
|
Reference in a new issue