diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt index 8e1a2f769..a1cc808d1 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/CategoryManga.kt @@ -10,14 +10,16 @@ package suwayomi.tachidesk.manga.impl import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.SortOrder import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.alias import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.count import org.jetbrains.exposed.sql.deleteWhere import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.leftJoin +import org.jetbrains.exposed.sql.max import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.update -import org.jetbrains.exposed.sql.wrapAsExpression import suwayomi.tachidesk.manga.impl.Category.DEFAULT_CATEGORY_ID import suwayomi.tachidesk.manga.impl.util.lang.isEmpty import suwayomi.tachidesk.manga.model.dataclass.CategoryDataClass @@ -61,46 +63,40 @@ object CategoryManga { * list of mangas that belong to a category */ fun getCategoryMangaList(categoryId: Int): List { - val unreadExpression = wrapAsExpression( - ChapterTable - .slice(ChapterTable.id.count()) - .select { (MangaTable.id eq ChapterTable.manga) and (ChapterTable.isRead eq false) } - ) - val downloadExpression = wrapAsExpression( - ChapterTable - .slice(ChapterTable.id.count()) - .select { (MangaTable.id eq ChapterTable.manga) and (ChapterTable.isDownloaded eq true) } - ) - val chapterCountExpression = wrapAsExpression( - ChapterTable - .slice(ChapterTable.id.count()) - .select { (MangaTable.id eq ChapterTable.manga) } - ) - - val selectedColumns = MangaTable.columns + unreadExpression + downloadExpression + chapterCountExpression + // Select the required columns from the MangaTable and add the aggregate functions to compute unread, download, and chapter counts + val unreadCountEx = ChapterTable.isRead.count().alias("unread_count") + val downloadedCount = ChapterTable.isDownloaded.count().alias("download_count") + val chapterCount = ChapterTable.id.count().alias("chapter_count") + val lastReadAt = ChapterTable.lastReadAt.max().alias("last_read_at") + val selectedColumns = MangaTable.columns + unreadCountEx + downloadedCount + chapterCount + lastReadAt val transform: (ResultRow) -> MangaDataClass = { + // Map the data from the result row to the MangaDataClass val dataClass = MangaTable.toDataClass(it) - dataClass.unreadCount = it[unreadExpression] - dataClass.downloadCount = it[downloadExpression] - dataClass.chapterCount = it[chapterCountExpression] + dataClass.lastReadAt = it[lastReadAt] + dataClass.unreadCount = it[unreadCountEx] + dataClass.downloadCount = it[downloadedCount] + dataClass.chapterCount = it[chapterCount] dataClass } - if (categoryId == DEFAULT_CATEGORY_ID) { - return transaction { + return transaction { + // Fetch data from the MangaTable and join with the CategoryMangaTable, if a category is specified + val query = if (categoryId == DEFAULT_CATEGORY_ID) { MangaTable - .slice(selectedColumns) + .leftJoin(ChapterTable, { MangaTable.id }, { ChapterTable.manga }) + .slice(columns = selectedColumns) .select { (MangaTable.inLibrary eq true) and (MangaTable.defaultCategory eq true) } - .map(transform) + } else { + MangaTable + .innerJoin(CategoryMangaTable) + .leftJoin(ChapterTable, { MangaTable.id }, { ChapterTable.manga }) + .slice(columns = selectedColumns) + .select { (MangaTable.inLibrary eq true) and (CategoryMangaTable.category eq categoryId) } } - } - return transaction { - CategoryMangaTable.innerJoin(MangaTable) - .slice(selectedColumns) - .select { (MangaTable.inLibrary eq true) and (CategoryMangaTable.category eq categoryId) } - .map(transform) + // Join with the ChapterTable to fetch the last read chapter for each manga + query.groupBy(*MangaTable.columns.toTypedArray()).map(transform) } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt index 84a893397..05ea72dd4 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/model/dataclass/MangaDataClass.kt @@ -45,6 +45,7 @@ data class MangaDataClass( var unreadCount: Long? = null, var downloadCount: Long? = null, var chapterCount: Long? = null, + var lastReadAt: Long? = null, var lastChapterRead: ChapterDataClass? = null, val age: Long? = if (lastFetchedAt == null) 0 else Instant.now().epochSecond.minus(lastFetchedAt),