mirror of
https://github.com/mihonapp/mihon.git
synced 2026-10-16 13:48:09 -07:00
Update an existing track in place instead of replacing it
Upserting a track for an entry and tracker that already have one updates that row, instead of the table's REPLACE deleting it and inserting a new one under a new id. Anything keyed to the old id, such as a queued tracking update, keeps working. The query, repository methods and interactor are renamed from insert to upsert to say so.
This commit is contained in:
@@ -17,11 +17,11 @@ import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||
import tachiyomi.domain.history.interactor.GetHistory
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
|
||||
@Inject
|
||||
class AddTracks(
|
||||
private val insertTrack: InsertTrack,
|
||||
private val upsertTrack: UpsertTrack,
|
||||
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
|
||||
private val getChaptersByMangaId: GetChaptersByMangaId,
|
||||
private val trackerManager: TrackerManager,
|
||||
@@ -37,7 +37,7 @@ class AddTracks(
|
||||
|
||||
var track = item.toDomainTrack(idRequired = false) ?: return@withIOContext
|
||||
|
||||
insertTrack.await(track)
|
||||
upsertTrack.await(track)
|
||||
|
||||
// TODO: merge into [SyncChapterProgressWithTrack]?
|
||||
// Update chapter progress if newer chapters marked read locally
|
||||
@@ -87,7 +87,7 @@ class AddTracks(
|
||||
service.match(manga)?.let { track ->
|
||||
track.manga_id = manga.id
|
||||
(service as Tracker).bind(track)
|
||||
insertTrack.await(track.toDomainTrack(idRequired = false)!!)
|
||||
upsertTrack.await(track.toDomainTrack(idRequired = false)!!)
|
||||
|
||||
syncChapterProgressWithTrack.await(
|
||||
manga.id,
|
||||
|
||||
@@ -9,13 +9,13 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import tachiyomi.domain.track.interactor.GetTracks
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
|
||||
@Inject
|
||||
class RefreshTracks(
|
||||
private val getTracks: GetTracks,
|
||||
private val trackerManager: TrackerManager,
|
||||
private val insertTrack: InsertTrack,
|
||||
private val upsertTrack: UpsertTrack,
|
||||
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
|
||||
) {
|
||||
|
||||
@@ -33,7 +33,7 @@ class RefreshTracks(
|
||||
async {
|
||||
return@async try {
|
||||
val updatedTrack = service!!.refresh(track.toDbTrack()).toDomainTrack()!!
|
||||
insertTrack.await(updatedTrack)
|
||||
upsertTrack.await(updatedTrack)
|
||||
syncChapterProgressWithTrack.await(mangaId, updatedTrack, service)
|
||||
null
|
||||
} catch (e: Throwable) {
|
||||
|
||||
@@ -9,14 +9,14 @@ import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||
import tachiyomi.domain.chapter.interactor.UpdateChapter
|
||||
import tachiyomi.domain.chapter.model.ChapterUpdate
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
import tachiyomi.domain.track.model.Track
|
||||
import kotlin.math.max
|
||||
|
||||
@Inject
|
||||
class SyncChapterProgressWithTrack(
|
||||
private val updateChapter: UpdateChapter,
|
||||
private val insertTrack: InsertTrack,
|
||||
private val upsertTrack: UpsertTrack,
|
||||
private val getChaptersByMangaId: GetChaptersByMangaId,
|
||||
) {
|
||||
|
||||
@@ -45,7 +45,7 @@ class SyncChapterProgressWithTrack(
|
||||
try {
|
||||
tracker.update(updatedTrack.toDbTrack())
|
||||
updateChapter.awaitAll(chapterUpdates)
|
||||
insertTrack.await(updatedTrack)
|
||||
upsertTrack.await(updatedTrack)
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.WARN, e)
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ import logcat.LogPriority
|
||||
import tachiyomi.core.common.util.lang.withNonCancellableContext
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.track.interactor.GetTracks
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
|
||||
@Inject
|
||||
class TrackChapter(
|
||||
private val getTracks: GetTracks,
|
||||
private val trackerManager: TrackerManager,
|
||||
private val insertTrack: InsertTrack,
|
||||
private val upsertTrack: UpsertTrack,
|
||||
private val delayedTrackingStore: DelayedTrackingStore,
|
||||
) {
|
||||
|
||||
@@ -41,7 +41,7 @@ class TrackChapter(
|
||||
.toDomainTrack(idRequired = true)!!
|
||||
.copy(lastChapterRead = chapterNumber)
|
||||
service.update(updatedTrack.toDbTrack(), true)
|
||||
insertTrack.await(updatedTrack)
|
||||
upsertTrack.await(updatedTrack)
|
||||
delayedTrackingStore.remove(track.id)
|
||||
} catch (e: Exception) {
|
||||
delayedTrackingStore.add(track.id, chapterNumber)
|
||||
|
||||
@@ -21,7 +21,7 @@ import okhttp3.OkHttpClient
|
||||
import tachiyomi.core.common.util.lang.withIOContext
|
||||
import tachiyomi.core.common.util.lang.withUIContext
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||
@@ -38,7 +38,7 @@ abstract class BaseTracker(
|
||||
|
||||
private val context: Context by lazy { appGraph.context }
|
||||
private val addTracks: AddTracks by lazy { appGraph.addTracks }
|
||||
private val insertTrack: InsertTrack by lazy { appGraph.insertTrack }
|
||||
private val upsertTrack: UpsertTrack by lazy { appGraph.upsertTrack }
|
||||
|
||||
override val client: OkHttpClient
|
||||
get() = networkService.client
|
||||
@@ -169,7 +169,7 @@ abstract class BaseTracker(
|
||||
try {
|
||||
update(track)
|
||||
track.toDomainTrack(idRequired = false)?.let {
|
||||
insertTrack.await(it)
|
||||
upsertTrack.await(it)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e) { "Failed to update remote track data id=$id" }
|
||||
|
||||
@@ -54,7 +54,7 @@ import tachiyomi.domain.manga.interactor.GetFavorites
|
||||
import tachiyomi.domain.manga.interactor.ResetViewerFlags
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
import tachiyomi.domain.storage.service.StoragePreferences
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
|
||||
@DependencyGraph(
|
||||
scope = AppScope::class,
|
||||
@@ -119,7 +119,7 @@ interface AppGraph : ViewModelGraph {
|
||||
val resetViewerFlags: ResetViewerFlags
|
||||
val resetCategoryFlags: ResetCategoryFlags
|
||||
val addTracks: AddTracks
|
||||
val insertTrack: InsertTrack
|
||||
val upsertTrack: UpsertTrack
|
||||
|
||||
val getExtensionStoreCountAsFlow: GetExtensionStoreCountAsFlow
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.domain.manga.model.MangaUpdate
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
import tachiyomi.domain.track.interactor.GetTracks
|
||||
import tachiyomi.domain.track.interactor.InsertTrack
|
||||
import tachiyomi.domain.track.interactor.UpsertTrack
|
||||
import kotlin.time.Clock
|
||||
|
||||
@Inject
|
||||
@@ -35,7 +35,7 @@ class MigrateMangaUseCase(
|
||||
private val getCategories: GetCategories,
|
||||
private val setMangaCategories: SetMangaCategories,
|
||||
private val getTracks: GetTracks,
|
||||
private val insertTrack: InsertTrack,
|
||||
private val upsertTrack: UpsertTrack,
|
||||
private val coverCache: CoverCache,
|
||||
private val updateMangaFromRemote: UpdateMangaFromRemote,
|
||||
) {
|
||||
@@ -98,7 +98,7 @@ class MigrateMangaUseCase(
|
||||
}
|
||||
}
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?.let { insertTrack.awaitAll(it) }
|
||||
?.let { upsertTrack.awaitAll(it) }
|
||||
|
||||
// Delete downloaded
|
||||
if (MigrationFlag.REMOVE_DOWNLOAD in flags && currentSource != null) {
|
||||
|
||||
@@ -272,7 +272,7 @@ class RestoreRepositoryImpl(
|
||||
.partition { it.id > 0 }
|
||||
|
||||
if (newTracks.isNotEmpty()) {
|
||||
trackRepository.insertAll(newTracks)
|
||||
trackRepository.upsertAll(newTracks)
|
||||
}
|
||||
|
||||
existingTracks.forEach { track ->
|
||||
|
||||
@@ -50,18 +50,18 @@ class TrackRepositoryImpl(
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun insert(track: Track) {
|
||||
insertValues(track)
|
||||
override suspend fun upsert(track: Track) {
|
||||
upsertValues(track)
|
||||
}
|
||||
|
||||
override suspend fun insertAll(tracks: List<Track>) {
|
||||
insertValues(*tracks.toTypedArray())
|
||||
override suspend fun upsertAll(tracks: List<Track>) {
|
||||
upsertValues(*tracks.toTypedArray())
|
||||
}
|
||||
|
||||
private suspend fun insertValues(vararg tracks: Track) {
|
||||
private suspend fun upsertValues(vararg tracks: Track) {
|
||||
database.transaction {
|
||||
tracks.forEach { mangaTrack ->
|
||||
database.manga_syncQueries.insert(
|
||||
database.manga_syncQueries.upsert(
|
||||
mangaId = mangaTrack.mangaId,
|
||||
syncId = mangaTrack.trackerId,
|
||||
remoteId = mangaTrack.remoteId,
|
||||
|
||||
@@ -40,9 +40,24 @@ SELECT *
|
||||
FROM manga_sync
|
||||
WHERE manga_id = :mangaId;
|
||||
|
||||
insert:
|
||||
upsert:
|
||||
INSERT INTO manga_sync(manga_id,sync_id,remote_id,library_id,title,last_chapter_read,total_chapters,status,score,remote_url,start_date,finish_date,private)
|
||||
VALUES (:mangaId,:syncId,:remoteId,:libraryId,:title,:lastChapterRead,:totalChapters,:status,:score,:remoteUrl,:startDate,:finishDate,:private);
|
||||
VALUES (:mangaId,:syncId,:remoteId,:libraryId,:title,:lastChapterRead,:totalChapters,:status,:score,:remoteUrl,:startDate,:finishDate,:private)
|
||||
ON CONFLICT(manga_id, sync_id)
|
||||
DO UPDATE
|
||||
SET
|
||||
remote_id = :remoteId,
|
||||
library_id = :libraryId,
|
||||
title = :title,
|
||||
last_chapter_read = :lastChapterRead,
|
||||
total_chapters = :totalChapters,
|
||||
status = :status,
|
||||
score = :score,
|
||||
remote_url = :remoteUrl,
|
||||
start_date = :startDate,
|
||||
finish_date = :finishDate,
|
||||
private = :private
|
||||
WHERE manga_id = :mangaId AND sync_id = :syncId;
|
||||
|
||||
update:
|
||||
UPDATE manga_sync
|
||||
|
||||
+3
-3
@@ -7,13 +7,13 @@ import tachiyomi.domain.track.model.Track
|
||||
import tachiyomi.domain.track.repository.TrackRepository
|
||||
|
||||
@Inject
|
||||
class InsertTrack(
|
||||
class UpsertTrack(
|
||||
private val trackRepository: TrackRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(track: Track) {
|
||||
try {
|
||||
trackRepository.insert(track)
|
||||
trackRepository.upsert(track)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class InsertTrack(
|
||||
|
||||
suspend fun awaitAll(tracks: List<Track>) {
|
||||
try {
|
||||
trackRepository.insertAll(tracks)
|
||||
trackRepository.upsertAll(tracks)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
@@ -15,7 +15,7 @@ interface TrackRepository {
|
||||
|
||||
suspend fun delete(mangaId: Long, trackerId: Long)
|
||||
|
||||
suspend fun insert(track: Track)
|
||||
suspend fun upsert(track: Track)
|
||||
|
||||
suspend fun insertAll(tracks: List<Track>)
|
||||
suspend fun upsertAll(tracks: List<Track>)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user