diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/dataLoaders/ChapterDataLoader.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/dataLoaders/ChapterDataLoader.kt index 89a2af0a..4013a508 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/dataLoaders/ChapterDataLoader.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/dataLoaders/ChapterDataLoader.kt @@ -11,7 +11,10 @@ import com.expediagroup.graphql.dataloader.KotlinDataLoader import org.dataloader.DataLoader import org.dataloader.DataLoaderFactory import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger +import org.jetbrains.exposed.sql.SortOrder import org.jetbrains.exposed.sql.addLogger +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.count import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.transactions.transaction import suwayomi.tachidesk.graphql.types.ChapterNodeList @@ -49,3 +52,55 @@ class ChaptersForMangaDataLoader : KotlinDataLoader { } } } + +class DownloadedChapterCountForMangaDataLoader : KotlinDataLoader { + override val dataLoaderName = "DownloadedChapterCountForMangaDataLoader" + override fun getDataLoader(): DataLoader = DataLoaderFactory.newDataLoader { ids -> + future { + transaction { + addLogger(Slf4jSqlDebugLogger) + val downloadedChapterCountByMangaId = + ChapterTable + .slice(ChapterTable.manga, ChapterTable.isDownloaded.count()) + .select { (ChapterTable.manga inList ids) and (ChapterTable.isDownloaded eq true) } + .groupBy(ChapterTable.manga) + .associate { it[ChapterTable.manga].value to it[ChapterTable.isDownloaded.count()] } + ids.map { downloadedChapterCountByMangaId[it]?.toInt() ?: 0 } + } + } + } +} + +class UnreadChapterCountForMangaDataLoader : KotlinDataLoader { + override val dataLoaderName = "UnreadChapterCountForMangaDataLoader" + override fun getDataLoader(): DataLoader = DataLoaderFactory.newDataLoader { ids -> + future { + transaction { + addLogger(Slf4jSqlDebugLogger) + val unreadChapterCountByMangaId = + ChapterTable + .slice(ChapterTable.manga, ChapterTable.isRead.count()) + .select { (ChapterTable.manga inList ids) and (ChapterTable.isRead eq false) } + .groupBy(ChapterTable.manga) + .associate { it[ChapterTable.manga].value to it[ChapterTable.isRead.count()] } + ids.map { unreadChapterCountByMangaId[it]?.toInt() ?: 0 } + } + } + } +} + +class LastReadChapterForMangaDataLoader : KotlinDataLoader { + override val dataLoaderName = "LastReadChapterForMangaDataLoader" + override fun getDataLoader(): DataLoader = DataLoaderFactory.newDataLoader { ids -> + future { + transaction { + addLogger(Slf4jSqlDebugLogger) + val lastReadChaptersByMangaId = ChapterTable + .select { (ChapterTable.manga inList ids) and (ChapterTable.isRead eq true) } + .orderBy(ChapterTable.sourceOrder to SortOrder.DESC) + .groupBy { it[ChapterTable.manga].value } + ids.map { id -> lastReadChaptersByMangaId[id]?.let { chapters -> ChapterType(chapters.first()) } } + } + } + } +} diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt index b4b8ede4..5d3e4413 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/server/TachideskDataLoaderRegistryFactory.kt @@ -15,9 +15,11 @@ import suwayomi.tachidesk.graphql.dataLoaders.CategoryMetaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ChapterDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ChapterMetaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ChaptersForMangaDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.DownloadedChapterCountForMangaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ExtensionDataLoader import suwayomi.tachidesk.graphql.dataLoaders.ExtensionForSourceDataLoader import suwayomi.tachidesk.graphql.dataLoaders.GlobalMetaDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.LastReadChapterForMangaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.MangaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.MangaForCategoryDataLoader import suwayomi.tachidesk.graphql.dataLoaders.MangaForIdsDataLoader @@ -25,6 +27,7 @@ import suwayomi.tachidesk.graphql.dataLoaders.MangaForSourceDataLoader import suwayomi.tachidesk.graphql.dataLoaders.MangaMetaDataLoader import suwayomi.tachidesk.graphql.dataLoaders.SourceDataLoader import suwayomi.tachidesk.graphql.dataLoaders.SourcesForExtensionDataLoader +import suwayomi.tachidesk.graphql.dataLoaders.UnreadChapterCountForMangaDataLoader class TachideskDataLoaderRegistryFactory { companion object { @@ -33,6 +36,9 @@ class TachideskDataLoaderRegistryFactory { MangaDataLoader(), ChapterDataLoader(), ChaptersForMangaDataLoader(), + DownloadedChapterCountForMangaDataLoader(), + UnreadChapterCountForMangaDataLoader(), + LastReadChapterForMangaDataLoader(), GlobalMetaDataLoader(), ChapterMetaDataLoader(), MangaMetaDataLoader(), diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt index c20f2324..ceb80b40 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt @@ -79,6 +79,18 @@ class MangaType( dataClass.chaptersLastFetchedAt ) + fun downloadCount(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { + return dataFetchingEnvironment.getValueFromDataLoader("DownloadedChapterCountForMangaDataLoader", id) + } + + fun unreadCount(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { + return dataFetchingEnvironment.getValueFromDataLoader("UnreadChapterCountForMangaDataLoader", id) + } + + fun lastReadChapter(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { + return dataFetchingEnvironment.getValueFromDataLoader("LastReadChapterForMangaDataLoader", id) + } + fun chapters(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { return dataFetchingEnvironment.getValueFromDataLoader("ChaptersForMangaDataLoader", id) }