From d6cbff2837bdf0de679bdf1cc8b93dbf3eadb487 Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Mon, 17 Oct 2022 01:33:12 +0600 Subject: [PATCH] Tweak library query (#8214) * Tweak library query Co-Authored-By: Quang Kieu * Update app/src/main/sqldelight/migrations/21.sqm * Update app/src/main/java/eu/kanade/domain/library/model/LibraryManga.kt * Update app/src/main/sqldelight/view/libraryView.sq * Update app/src/main/java/eu/kanade/data/manga/MangaMapper.kt * Update app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt * Update app/src/main/java/eu/kanade/data/manga/MangaMapper.kt * Bump version Co-authored-by: Quang Kieu --- app/build.gradle.kts | 2 +- .../java/eu/kanade/data/manga/MangaMapper.kt | 13 +++-- .../kanade/data/manga/MangaRepositoryImpl.kt | 4 +- .../domain/library/model/LibraryManga.kt | 3 + .../tachiyomi/ui/library/LibraryPresenter.kt | 48 ++-------------- app/src/main/sqldelight/data/mangas.sq | 56 ------------------- app/src/main/sqldelight/migrations/21.sqm | 27 +++++++++ app/src/main/sqldelight/view/libraryView.sq | 31 ++++++++++ 8 files changed, 76 insertions(+), 108 deletions(-) create mode 100644 app/src/main/sqldelight/migrations/21.sqm create mode 100644 app/src/main/sqldelight/view/libraryView.sq diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b8240bb9b4..f543d02bdf 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,7 +27,7 @@ android { applicationId = "eu.kanade.tachiyomi" minSdk = AndroidConfig.minSdk targetSdk = AndroidConfig.targetSdk - versionCode = 86 + versionCode = 87 versionName = "0.13.6" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") diff --git a/app/src/main/java/eu/kanade/data/manga/MangaMapper.kt b/app/src/main/java/eu/kanade/data/manga/MangaMapper.kt index 2ea682d7e3..80edff3631 100644 --- a/app/src/main/java/eu/kanade/data/manga/MangaMapper.kt +++ b/app/src/main/java/eu/kanade/data/manga/MangaMapper.kt @@ -5,14 +5,14 @@ import eu.kanade.domain.manga.model.Manga import eu.kanade.tachiyomi.source.model.UpdateStrategy val mangaMapper: (Long, Long, String, String?, String?, String?, List?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy) -> Manga = - { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewer, chapterFlags, coverLastModified, dateAdded, updateStrategy -> + { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy -> Manga( id = id, source = source, favorite = favorite, lastUpdate = lastUpdate ?: 0, dateAdded = dateAdded, - viewerFlags = viewer, + viewerFlags = viewerFlags, chapterFlags = chapterFlags, coverLastModified = coverLastModified, url = url, @@ -28,11 +28,11 @@ val mangaMapper: (Long, Long, String, String?, String?, String?, List?, ) } -val libraryManga: (Long, Long, String, String?, String?, String?, List?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long) -> LibraryManga = - { _id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, unreadCount, readCount, category -> +val libraryManga: (Long, Long, String, String?, String?, String?, List?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, Long, Long, Long, Long, Long, Long) -> LibraryManga = + { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, unreadCount, readCount, latestUpload, chapterFetchedAt, lastRead, category -> LibraryManga( manga = mangaMapper( - _id, + id, source, url, artist, @@ -55,5 +55,8 @@ val libraryManga: (Long, Long, String, String?, String?, String?, List?, category = category, unreadCount = unreadCount, readCount = readCount, + latestUpload = latestUpload, + chapterFetchedAt = chapterFetchedAt, + lastRead = lastRead, ) } diff --git a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt index 0f3acdaee3..650331167a 100644 --- a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt @@ -37,11 +37,11 @@ class MangaRepositoryImpl( } override suspend fun getLibraryManga(): List { - return handler.awaitList { mangasQueries.getLibrary(libraryManga) } + return handler.awaitList { libraryViewQueries.library(libraryManga) } } override fun getLibraryMangaAsFlow(): Flow> { - return handler.subscribeToList { mangasQueries.getLibrary(libraryManga) } + return handler.subscribeToList { libraryViewQueries.library(libraryManga) } } override fun getFavoritesBySourceId(sourceId: Long): Flow> { diff --git a/app/src/main/java/eu/kanade/domain/library/model/LibraryManga.kt b/app/src/main/java/eu/kanade/domain/library/model/LibraryManga.kt index 9e99166971..74a41357b4 100644 --- a/app/src/main/java/eu/kanade/domain/library/model/LibraryManga.kt +++ b/app/src/main/java/eu/kanade/domain/library/model/LibraryManga.kt @@ -7,6 +7,9 @@ data class LibraryManga( val category: Long, val unreadCount: Long, val readCount: Long, + val latestUpload: Long, + val chapterFetchedAt: Long, + val lastRead: Long, ) { val totalChapters get() = readCount + unreadCount diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 6dd94c5b9f..015d797a88 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -15,7 +15,6 @@ import eu.kanade.core.prefs.CheckboxState import eu.kanade.core.prefs.PreferenceMutableState import eu.kanade.core.util.asFlow import eu.kanade.core.util.asObservable -import eu.kanade.data.DatabaseHandler import eu.kanade.domain.base.BasePreferences import eu.kanade.domain.category.interactor.GetCategories import eu.kanade.domain.category.interactor.SetMangaCategories @@ -82,7 +81,6 @@ typealias LibraryMap = Map> */ class LibraryPresenter( private val state: LibraryStateImpl = LibraryState() as LibraryStateImpl, - private val handler: DatabaseHandler = Injekt.get(), private val getLibraryManga: GetLibraryManga = Injekt.get(), private val getTracks: GetTracks = Injekt.get(), private val getCategories: GetCategories = Injekt.get(), @@ -286,37 +284,7 @@ class LibraryPresenter( * @param map the map to sort. */ private fun applySort(categories: List, map: LibraryMap): LibraryMap { - val lastReadManga by lazy { - var counter = 0 - // TODO: Make [applySort] a suspended function - runBlocking { - handler.awaitList { - mangasQueries.getLastRead() - }.associate { it._id to counter++ } - } - } - val latestChapterManga by lazy { - var counter = 0 - // TODO: Make [applySort] a suspended function - runBlocking { - handler.awaitList { - mangasQueries.getLatestByChapterUploadDate() - }.associate { it._id to counter++ } - } - } - val chapterFetchDateManga by lazy { - var counter = 0 - // TODO: Make [applySort] a suspended function - runBlocking { - handler.awaitList { - mangasQueries.getLatestByChapterFetchDate() - }.associate { it._id to counter++ } - } - } - - val sortModes = categories.associate { category -> - category.id to category.sort - } + val sortModes = categories.associate { it.id to it.sort } val locale = Locale.getDefault() val collator = Collator.getInstance(locale).apply { @@ -329,9 +297,7 @@ class LibraryPresenter( collator.compare(i1.libraryManga.manga.title.lowercase(locale), i2.libraryManga.manga.title.lowercase(locale)) } LibrarySort.Type.LastRead -> { - val manga1LastRead = lastReadManga[i1.libraryManga.manga.id] ?: 0 - val manga2LastRead = lastReadManga[i2.libraryManga.manga.id] ?: 0 - manga1LastRead.compareTo(manga2LastRead) + i1.libraryManga.lastRead.compareTo(i2.libraryManga.lastRead) } LibrarySort.Type.LastUpdate -> { i1.libraryManga.manga.lastUpdate.compareTo(i2.libraryManga.manga.lastUpdate) @@ -347,16 +313,10 @@ class LibraryPresenter( i1.libraryManga.totalChapters.compareTo(i2.libraryManga.totalChapters) } LibrarySort.Type.LatestChapter -> { - val manga1latestChapter = latestChapterManga[i1.libraryManga.manga.id] - ?: latestChapterManga.size - val manga2latestChapter = latestChapterManga[i2.libraryManga.manga.id] - ?: latestChapterManga.size - manga1latestChapter.compareTo(manga2latestChapter) + i1.libraryManga.latestUpload.compareTo(i2.libraryManga.latestUpload) } LibrarySort.Type.ChapterFetchDate -> { - val manga1chapterFetchDate = chapterFetchDateManga[i1.libraryManga.manga.id] ?: 0 - val manga2chapterFetchDate = chapterFetchDateManga[i2.libraryManga.manga.id] ?: 0 - manga1chapterFetchDate.compareTo(manga2chapterFetchDate) + i1.libraryManga.chapterFetchedAt.compareTo(i2.libraryManga.chapterFetchedAt) } LibrarySort.Type.DateAdded -> { i1.libraryManga.manga.dateAdded.compareTo(i2.libraryManga.manga.dateAdded) diff --git a/app/src/main/sqldelight/data/mangas.sq b/app/src/main/sqldelight/data/mangas.sq index 4a5b7bf56b..11bac32e3c 100644 --- a/app/src/main/sqldelight/data/mangas.sq +++ b/app/src/main/sqldelight/data/mangas.sq @@ -74,62 +74,6 @@ FROM mangas WHERE favorite = 0 GROUP BY source; -getLibrary: -SELECT M.*, COALESCE(MC.category_id, 0) AS category -FROM ( - SELECT mangas.*, COALESCE(UR.unreadCount, 0) AS unread_count, COALESCE(R.readCount, 0) AS read_count - FROM mangas - LEFT JOIN ( - SELECT chapters.manga_id, COUNT(*) AS unreadCount - FROM chapters - WHERE chapters.read = 0 - GROUP BY chapters.manga_id - ) AS UR - ON mangas._id = UR.manga_id - LEFT JOIN ( - SELECT chapters.manga_id, COUNT(*) AS readCount - FROM chapters - WHERE chapters.read = 1 - GROUP BY chapters.manga_id - ) AS R - ON mangas._id = R.manga_id - WHERE mangas.favorite = 1 - GROUP BY mangas._id - ORDER BY mangas.title -) AS M -LEFT JOIN ( - SELECT * - FROM mangas_categories -) AS MC -ON M._id = MC.manga_id; - -getLastRead: -SELECT M.*, MAX(H.last_read) AS max -FROM mangas M -JOIN chapters C -ON M._id = C.manga_id -JOIN history H -ON C._id = H.chapter_id -WHERE M.favorite = 1 -GROUP BY M._id -ORDER BY max ASC; - -getLatestByChapterUploadDate: -SELECT M.*, MAX(C.date_upload) AS max -FROM mangas M -JOIN chapters C -ON M._id = C.manga_id -GROUP BY M._id -ORDER BY max ASC; - -getLatestByChapterFetchDate: -SELECT M.*, MAX(C.date_fetch) AS max -FROM mangas M -JOIN chapters C -ON M._id = C.manga_id -GROUP BY M._id -ORDER BY max ASC; - deleteMangasNotInLibraryBySourceIds: DELETE FROM mangas WHERE favorite = 0 AND source IN :sourceIds; diff --git a/app/src/main/sqldelight/migrations/21.sqm b/app/src/main/sqldelight/migrations/21.sqm new file mode 100644 index 0000000000..00538aef80 --- /dev/null +++ b/app/src/main/sqldelight/migrations/21.sqm @@ -0,0 +1,27 @@ +CREATE VIEW libraryView AS +SELECT + M.*, + coalesce(C.total - C.readCount, 0) AS unreadCount, + coalesce(C.readCount, 0) AS readCount, + coalesce(C.latestUpload, 0) AS latestUpload, + coalesce(C.fetchedAt, 0) AS chapterFetchedAt, + coalesce(C.lastRead, 0) AS lastRead, + COALESCE(MC.category_id, 0) AS category +FROM mangas M +LEFT JOIN mangas_categories AS MC +ON MC.manga_id = M._id +LEFT JOIN( + SELECT + chapters.manga_id, + count(*) AS total, + sum(read) AS readCount, + max(chapters.date_upload) AS latestUpload, + max(history.last_read) AS lastRead, + max(chapters.date_fetch) AS fetchedAt + FROM chapters + LEFT JOIN history + ON chapters._id = history.chapter_id + GROUP BY chapters.manga_id +) AS C +ON M._id = C.manga_id +WHERE M.favorite = 1; diff --git a/app/src/main/sqldelight/view/libraryView.sq b/app/src/main/sqldelight/view/libraryView.sq new file mode 100644 index 0000000000..93373abf17 --- /dev/null +++ b/app/src/main/sqldelight/view/libraryView.sq @@ -0,0 +1,31 @@ +CREATE VIEW libraryView AS +SELECT + M.*, + coalesce(C.total - C.readCount, 0) AS unreadCount, + coalesce(C.readCount, 0) AS readCount, + coalesce(C.latestUpload, 0) AS latestUpload, + coalesce(C.fetchedAt, 0) AS chapterFetchedAt, + coalesce(C.lastRead, 0) AS lastRead, + COALESCE(MC.category_id, 0) AS category +FROM mangas M +LEFT JOIN mangas_categories AS MC +ON MC.manga_id = M._id +LEFT JOIN( + SELECT + chapters.manga_id, + count(*) AS total, + sum(read) AS readCount, + coalesce(max(chapters.date_upload), 0) AS latestUpload, + coalesce(max(history.last_read), 0) AS lastRead, + coalesce(max(chapters.date_fetch), 0) AS fetchedAt + FROM chapters + LEFT JOIN history + ON chapters._id = history.chapter_id + GROUP BY chapters.manga_id +) AS C +ON M._id = C.manga_id +WHERE M.favorite = 1; + +library: +SELECT * +FROM libraryView;