Skip to content

Commit

Permalink
Send last read chapter in Mangas in Category API (#507)
Browse files Browse the repository at this point in the history
* Send last read chapter with manga

* optimize query

* introduce new field for better performance
  • Loading branch information
akabhirav authored Feb 20, 2023
1 parent ac99dd5 commit 783787e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -61,46 +63,40 @@ object CategoryManga {
* list of mangas that belong to a category
*/
fun getCategoryMangaList(categoryId: Int): List<MangaDataClass> {
val unreadExpression = wrapAsExpression<Long>(
ChapterTable
.slice(ChapterTable.id.count())
.select { (MangaTable.id eq ChapterTable.manga) and (ChapterTable.isRead eq false) }
)
val downloadExpression = wrapAsExpression<Long>(
ChapterTable
.slice(ChapterTable.id.count())
.select { (MangaTable.id eq ChapterTable.manga) and (ChapterTable.isDownloaded eq true) }
)
val chapterCountExpression = wrapAsExpression<Long>(
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)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down

0 comments on commit 783787e

Please sign in to comment.