diff --git a/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt index cd0e593d5..a10831222 100644 --- a/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/category/CategoryRepositoryImpl.kt @@ -32,10 +32,11 @@ class CategoryRepositoryImpl( } } + // SY --> @Throws(DuplicateNameException::class) - override suspend fun insert(name: String, order: Long) { + override suspend fun insert(name: String, order: Long): Long { if (checkDuplicateName(name)) throw DuplicateNameException(name) - handler.await { + return handler.awaitOne(true) { categoriesQueries.insert( name = name, order = order, @@ -44,8 +45,10 @@ class CategoryRepositoryImpl( mangaOrder = emptyList(), // SY <-- ) + categoriesQueries.selectLastInsertedRowId() } } + // SY <-- @Throws(DuplicateNameException::class) override suspend fun update(payload: CategoryUpdate) { diff --git a/app/src/main/java/eu/kanade/data/chapter/ChapterRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/chapter/ChapterRepositoryImpl.kt index 699976e42..623eab4a7 100644 --- a/app/src/main/java/eu/kanade/data/chapter/ChapterRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/chapter/ChapterRepositoryImpl.kt @@ -94,6 +94,10 @@ class ChapterRepositoryImpl( } // SY --> + override suspend fun getChapterByUrl(url: String): List { + return handler.awaitList { chaptersQueries.getChapterByUrl(url, chapterMapper) } + } + override suspend fun getMergedChapterByMangaId(mangaId: Long): List { return handler.awaitList { chaptersQueries.getMergedChaptersByMangaId(mangaId, chapterMapper) } } diff --git a/app/src/main/java/eu/kanade/data/history/HistoryRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/history/HistoryRepositoryImpl.kt index 808aeee65..6d27e8e55 100644 --- a/app/src/main/java/eu/kanade/data/history/HistoryRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/history/HistoryRepositoryImpl.kt @@ -5,6 +5,7 @@ import eu.kanade.data.DatabaseHandler import eu.kanade.data.chapter.chapterMapper import eu.kanade.data.manga.mangaMapper import eu.kanade.domain.chapter.model.Chapter +import eu.kanade.domain.history.model.History import eu.kanade.domain.history.model.HistoryUpdate import eu.kanade.domain.history.model.HistoryWithRelations import eu.kanade.domain.history.repository.HistoryRepository @@ -109,4 +110,10 @@ class HistoryRepositoryImpl( logcat(LogPriority.ERROR, throwable = e) } } + + // SY --> + override suspend fun getByMangaId(mangaId: Long): List { + return handler.awaitList { historyQueries.getHistoryByMangaId(mangaId, historyMapper) } + } + // SY <-- } diff --git a/app/src/main/java/eu/kanade/domain/SYDomainModule.kt b/app/src/main/java/eu/kanade/domain/SYDomainModule.kt index 0bf9b4f05..3c94925c8 100644 --- a/app/src/main/java/eu/kanade/domain/SYDomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/SYDomainModule.kt @@ -6,7 +6,9 @@ import eu.kanade.data.manga.MangaMetadataRepositoryImpl import eu.kanade.data.source.FeedSavedSearchRepositoryImpl import eu.kanade.data.source.SavedSearchRepositoryImpl import eu.kanade.domain.chapter.interactor.DeleteChapters +import eu.kanade.domain.chapter.interactor.GetChapterByUrl import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId +import eu.kanade.domain.history.interactor.GetHistoryByMangaId import eu.kanade.domain.manga.interactor.DeleteByMergeId import eu.kanade.domain.manga.interactor.DeleteFavoriteEntries import eu.kanade.domain.manga.interactor.DeleteMangaById @@ -73,6 +75,8 @@ class SYDomainModule : InjektModule { addFactory { DeleteChapters(get()) } addFactory { DeleteMangaById(get()) } addFactory { FilterSerializer() } + addFactory { GetHistoryByMangaId(get()) } + addFactory { GetChapterByUrl(get()) } addSingletonFactory { MangaMetadataRepositoryImpl(get()) } addFactory { GetFlatMetadataById(get()) } diff --git a/app/src/main/java/eu/kanade/domain/category/interactor/InsertCategory.kt b/app/src/main/java/eu/kanade/domain/category/interactor/InsertCategory.kt index 0a659d0e5..813a7fde0 100644 --- a/app/src/main/java/eu/kanade/domain/category/interactor/InsertCategory.kt +++ b/app/src/main/java/eu/kanade/domain/category/interactor/InsertCategory.kt @@ -8,15 +8,19 @@ class InsertCategory( suspend fun await(name: String, order: Long): Result { return try { - categoryRepository.insert(name, order) - Result.Success + // SY --> + Result.Success(categoryRepository.insert(name, order)) + // SY <-- } catch (e: Exception) { Result.Error(e) } } sealed class Result { - object Success : Result() + // SY --> + data class Success(val id: Long) : Result() + + // Sy <-- data class Error(val error: Exception) : Result() } } diff --git a/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt b/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt index 6499243b4..0f69b1a72 100644 --- a/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt +++ b/app/src/main/java/eu/kanade/domain/category/repository/CategoryRepository.kt @@ -14,8 +14,10 @@ interface CategoryRepository { fun getCategoriesByMangaIdAsFlow(mangaId: Long): Flow> + // SY --> @Throws(DuplicateNameException::class) - suspend fun insert(name: String, order: Long) + suspend fun insert(name: String, order: Long): Long + // SY <-- @Throws(DuplicateNameException::class) suspend fun update(payload: CategoryUpdate) diff --git a/app/src/main/java/eu/kanade/domain/chapter/interactor/GetChapterByUrl.kt b/app/src/main/java/eu/kanade/domain/chapter/interactor/GetChapterByUrl.kt new file mode 100644 index 000000000..ad61368ce --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/chapter/interactor/GetChapterByUrl.kt @@ -0,0 +1,20 @@ +package eu.kanade.domain.chapter.interactor + +import eu.kanade.domain.chapter.model.Chapter +import eu.kanade.domain.chapter.repository.ChapterRepository +import eu.kanade.tachiyomi.util.system.logcat +import logcat.LogPriority + +class GetChapterByUrl( + private val chapterRepository: ChapterRepository, +) { + + suspend fun await(url: String): List { + return try { + chapterRepository.getChapterByUrl(url) + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) + emptyList() + } + } +} diff --git a/app/src/main/java/eu/kanade/domain/chapter/repository/ChapterRepository.kt b/app/src/main/java/eu/kanade/domain/chapter/repository/ChapterRepository.kt index 3eff17858..353861a69 100644 --- a/app/src/main/java/eu/kanade/domain/chapter/repository/ChapterRepository.kt +++ b/app/src/main/java/eu/kanade/domain/chapter/repository/ChapterRepository.kt @@ -23,6 +23,8 @@ interface ChapterRepository { suspend fun getChapterByUrlAndMangaId(url: String, mangaId: Long): Chapter? // SY --> + suspend fun getChapterByUrl(url: String): List + suspend fun getMergedChapterByMangaId(mangaId: Long): List suspend fun getMergedChapterByMangaIdAsFlow(mangaId: Long): Flow> diff --git a/app/src/main/java/eu/kanade/domain/history/interactor/GetHistoryByMangaId.kt b/app/src/main/java/eu/kanade/domain/history/interactor/GetHistoryByMangaId.kt new file mode 100644 index 000000000..eecd14861 --- /dev/null +++ b/app/src/main/java/eu/kanade/domain/history/interactor/GetHistoryByMangaId.kt @@ -0,0 +1,13 @@ +package eu.kanade.domain.history.interactor + +import eu.kanade.domain.history.model.History +import eu.kanade.domain.history.repository.HistoryRepository + +class GetHistoryByMangaId( + private val repository: HistoryRepository, +) { + + suspend fun await(mangaId: Long): List { + return repository.getByMangaId(mangaId) + } +} diff --git a/app/src/main/java/eu/kanade/domain/history/repository/HistoryRepository.kt b/app/src/main/java/eu/kanade/domain/history/repository/HistoryRepository.kt index f2c57894a..1ec2bfc78 100644 --- a/app/src/main/java/eu/kanade/domain/history/repository/HistoryRepository.kt +++ b/app/src/main/java/eu/kanade/domain/history/repository/HistoryRepository.kt @@ -2,6 +2,7 @@ package eu.kanade.domain.history.repository import androidx.paging.PagingSource import eu.kanade.domain.chapter.model.Chapter +import eu.kanade.domain.history.model.History import eu.kanade.domain.history.model.HistoryUpdate import eu.kanade.domain.history.model.HistoryWithRelations @@ -20,4 +21,8 @@ interface HistoryRepository { suspend fun deleteAllHistory(): Boolean suspend fun upsertHistory(historyUpdate: HistoryUpdate) + + // SY --> + suspend fun getByMangaId(mangaId: Long): List + // SY <-- } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationProcessAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationProcessAdapter.kt index 5f1291803..d7d25cb3a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationProcessAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationProcessAdapter.kt @@ -2,14 +2,13 @@ package eu.kanade.tachiyomi.ui.browse.migration.advanced.process import android.view.MenuItem import eu.davidea.flexibleadapter.FlexibleAdapter -import eu.kanade.data.DatabaseHandler -import eu.kanade.data.history.historyMapper import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.SetMangaCategories import eu.kanade.domain.chapter.interactor.GetChapterByMangaId import eu.kanade.domain.chapter.interactor.UpdateChapter import eu.kanade.domain.chapter.model.Chapter import eu.kanade.domain.chapter.model.ChapterUpdate +import eu.kanade.domain.history.interactor.GetHistoryByMangaId import eu.kanade.domain.history.interactor.UpsertHistory import eu.kanade.domain.history.model.HistoryUpdate import eu.kanade.domain.manga.interactor.GetManga @@ -32,13 +31,13 @@ import uy.kohesive.injekt.injectLazy class MigrationProcessAdapter( val controller: MigrationListController, ) : FlexibleAdapter(null, controller, true) { - private val handler: DatabaseHandler by injectLazy() private val preferences: PreferencesHelper by injectLazy() private val coverCache: CoverCache by injectLazy() private val getManga: GetManga by injectLazy() private val updateManga: UpdateManga by injectLazy() private val updateChapter: UpdateChapter by injectLazy() private val getChapterByMangaId: GetChapterByMangaId by injectLazy() + private val getHistoryByMangaId: GetHistoryByMangaId by injectLazy() private val upsertHistory: UpsertHistory by injectLazy() private val getCategories: GetCategories by injectLazy() private val setMangaCategories: SetMangaCategories by injectLazy() @@ -139,7 +138,7 @@ class MigrationProcessAdapter( val maxChapterRead = prevMangaChapters.filter(Chapter::read).maxOfOrNull(Chapter::chapterNumber) val dbChapters = getChapterByMangaId.await(manga.id) - val prevHistoryList = handler.awaitList { historyQueries.getHistoryByMangaId(prevManga.id, historyMapper) } + val prevHistoryList = getHistoryByMangaId.await(prevManga.id) val chapterUpdates = mutableListOf() val historyUpdates = mutableListOf() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsEhController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsEhController.kt index aa86d2707..70f558c5d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsEhController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsEhController.kt @@ -14,9 +14,8 @@ import androidx.core.widget.doAfterTextChanged import androidx.preference.PreferenceScreen import com.fredporciuncula.flow.preferences.Preference import com.google.android.material.dialog.MaterialAlertDialogBuilder -import eu.kanade.data.DatabaseHandler -import eu.kanade.data.manga.mangaMapper import eu.kanade.domain.manga.interactor.DeleteFavoriteEntries +import eu.kanade.domain.manga.interactor.GetExhFavoriteMangaWithMetadata import eu.kanade.domain.manga.interactor.GetFlatMetadataById import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING @@ -46,8 +45,6 @@ import exh.eh.EHentaiUpdaterStats import exh.favorites.FavoritesIntroDialog import exh.log.xLogD import exh.metadata.metadata.EHentaiSearchMetadata -import exh.source.EH_SOURCE_ID -import exh.source.EXH_SOURCE_ID import exh.uconfig.WarnConfigureDialogController import exh.ui.login.EhLoginActivity import exh.util.nullIfBlank @@ -72,9 +69,9 @@ import kotlin.time.Duration.Companion.seconds */ class SettingsEhController : SettingsController() { - private val handler: DatabaseHandler by injectLazy() private val getFlatMetadataById: GetFlatMetadataById by injectLazy() private val deleteFavoriteEntries: DeleteFavoriteEntries by injectLazy() + private val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy() fun Preference<*>.reconfigure(): Boolean { // Listen for change commit @@ -475,8 +472,7 @@ class SettingsEhController : SettingsController() { context.getString(R.string.gallery_updater_stats_text, getRelativeTimeString(getRelativeTimeFromNow(stats.startTime.milliseconds), context), stats.updateCount, stats.possibleUpdates) } else context.getString(R.string.gallery_updater_not_ran_yet) - val allMeta = handler - .awaitList { mangasQueries.getEhMangaWithMetadata(EH_SOURCE_ID, EXH_SOURCE_ID, mangaMapper) } + val allMeta = getExhFavoriteMangaWithMetadata.await() .mapNotNull { getFlatMetadataById.await(it.id) ?.raise() diff --git a/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt b/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt index f581a8142..03258e808 100644 --- a/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt +++ b/app/src/main/java/exh/eh/EHentaiUpdateHelper.kt @@ -1,15 +1,14 @@ package exh.eh import android.content.Context -import eu.kanade.data.DatabaseHandler -import eu.kanade.data.chapter.chapterMapper -import eu.kanade.data.history.historyMapper import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.SetMangaCategories import eu.kanade.domain.chapter.interactor.GetChapterByMangaId +import eu.kanade.domain.chapter.interactor.GetChapterByUrl import eu.kanade.domain.chapter.model.Chapter import eu.kanade.domain.chapter.model.ChapterUpdate import eu.kanade.domain.chapter.repository.ChapterRepository +import eu.kanade.domain.history.interactor.GetHistoryByMangaId import eu.kanade.domain.history.interactor.RemoveHistoryById import eu.kanade.domain.history.interactor.UpsertHistory import eu.kanade.domain.history.model.History @@ -35,7 +34,7 @@ class EHentaiUpdateHelper(context: Context) { File(context.filesDir, "exh-plt.maftable"), GalleryEntry.Serializer(), ) - private val handler: DatabaseHandler by injectLazy() + private val getChapterByUrl: GetChapterByUrl by injectLazy() private val getChapterByMangaId: GetChapterByMangaId by injectLazy() private val getManga: GetManga by injectLazy() private val updateManga: UpdateManga by injectLazy() @@ -44,6 +43,7 @@ class EHentaiUpdateHelper(context: Context) { private val chapterRepository: ChapterRepository by injectLazy() private val upsertHistory: UpsertHistory by injectLazy() private val removeHistoryById: RemoveHistoryById by injectLazy() + private val getHistoryByMangaId: GetHistoryByMangaId by injectLazy() /** * @param chapters Cannot be an empty list! @@ -55,8 +55,7 @@ class EHentaiUpdateHelper(context: Context) { val chainsFlow = flowOf(chapters) .map { chapterList -> chapterList.flatMap { chapter -> - handler.awaitList { chaptersQueries.getChapterByUrl(chapter.url, chapterMapper) } - .map { it.mangaId } + getChapterByUrl.await(chapter.url).map { it.mangaId } }.distinct() } .map { mangaIds -> @@ -70,7 +69,7 @@ class EHentaiUpdateHelper(context: Context) { getChapterByMangaId.await(mangaId) } val history = async(Dispatchers.IO) { - handler.awaitList { historyQueries.getHistoryByMangaId(mangaId, historyMapper) } + getHistoryByMangaId.await(mangaId) } ChapterChain( manga.await() ?: return@coroutineScope null, @@ -139,8 +138,8 @@ class EHentaiUpdateHelper(context: Context) { // Copy categories from all chains to accepted manga - val newCategories = rootsToMutate.flatMap { - getCategories.await(it.manga.id).map { it.id } + val newCategories = rootsToMutate.flatMap { chapterChain -> + getCategories.await(chapterChain.manga.id).map { it.id } }.distinct() rootsToMutate.forEach { setMangaCategories.await(it.manga.id, newCategories) diff --git a/app/src/main/java/exh/favorites/FavoritesSyncHelper.kt b/app/src/main/java/exh/favorites/FavoritesSyncHelper.kt index b09c642a1..66605d42c 100644 --- a/app/src/main/java/exh/favorites/FavoritesSyncHelper.kt +++ b/app/src/main/java/exh/favorites/FavoritesSyncHelper.kt @@ -3,10 +3,12 @@ package exh.favorites import android.content.Context import android.net.wifi.WifiManager import android.os.PowerManager -import eu.kanade.data.DatabaseHandler import eu.kanade.domain.category.interactor.GetCategories +import eu.kanade.domain.category.interactor.InsertCategory import eu.kanade.domain.category.interactor.SetMangaCategories +import eu.kanade.domain.category.interactor.UpdateCategory import eu.kanade.domain.category.model.Category +import eu.kanade.domain.category.model.CategoryUpdate import eu.kanade.domain.manga.interactor.GetLibraryManga import eu.kanade.domain.manga.interactor.GetManga import eu.kanade.domain.manga.interactor.UpdateManga @@ -48,12 +50,13 @@ import kotlin.time.Duration.Companion.seconds // TODO only apply database changes after sync class FavoritesSyncHelper(val context: Context) { - private val handler: DatabaseHandler by injectLazy() private val getLibraryManga: GetLibraryManga by injectLazy() private val getCategories: GetCategories by injectLazy() private val getManga: GetManga by injectLazy() private val updateManga: UpdateManga by injectLazy() private val setMangaCategories: SetMangaCategories by injectLazy() + private val insertCategory: InsertCategory by injectLazy() + private val updateCategory: UpdateCategory by injectLazy() private val prefs: PreferencesHelper by injectLazy() @@ -203,28 +206,25 @@ class FavoritesSyncHelper(val context: Context) { private suspend fun applyRemoteCategories(categories: List) { val localCategories = getCategories.await() - val newLocalCategories = localCategories.toMutableList() - categories.forEachIndexed { index, remote -> val local = localCategories.getOrElse(index) { - val newCategoryId = handler.awaitOne(true) { - categoriesQueries.insert(remote, index.toLong(), 0L, emptyList()) - categoriesQueries.selectLastInsertedRowId() + when (val insertCategoryResult = insertCategory.await(remote, index.toLong())) { + is InsertCategory.Result.Error -> throw insertCategoryResult.error + is InsertCategory.Result.Success -> Category(insertCategoryResult.id, remote, index.toLong(), 0L, emptyList()) } - Category(newCategoryId, remote, index.toLong(), 0L, emptyList()) - .also { newLocalCategories += it } } // Ensure consistent ordering and naming if (local.name != remote || local.order != index.toLong()) { - handler.await { - categoriesQueries.update( - categoryId = local.id, + val result = updateCategory.await( + CategoryUpdate( + id = local.id, order = index.toLong().takeIf { it != local.order }, name = remote.takeIf { it != local.name }, - flags = null, - mangaOrder = null, - ) + ), + ) + if (result is UpdateCategory.Result.Error) { + throw result.error } } }