diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e5e3d46e7..d434b275c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -28,7 +28,7 @@ android { applicationId = "eu.kanade.tachiyomi.sy" minSdk = AndroidConfig.minSdk targetSdk = AndroidConfig.targetSdk - versionCode = 42 + versionCode = 43 versionName = "1.8.5" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") diff --git a/app/src/main/java/eu/kanade/data/manga/LibraryQuery.kt b/app/src/main/java/eu/kanade/data/manga/LibraryQuery.kt index 7f42c1036..46e0d670a 100644 --- a/app/src/main/java/eu/kanade/data/manga/LibraryQuery.kt +++ b/app/src/main/java/eu/kanade/data/manga/LibraryQuery.kt @@ -36,7 +36,10 @@ private val mapper = { cursor: SqlCursor -> ), unreadCount = cursor.getLong(20)!!, readCount = cursor.getLong(21)!!, - category = cursor.getLong(22)!!, + latestUpload = cursor.getLong(22)!!, + chapterFetchedAt = cursor.getLong(23)!!, + lastRead = cursor.getLong(24)!!, + category = cursor.getLong(25)!!, ) } @@ -45,56 +48,67 @@ class LibraryQuery(val driver: SqlDriver) : Query(copyOnWriteList( return driver.executeQuery( null, """ - 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 AND mangas.source <> $MERGED_SOURCE_ID - GROUP BY mangas._id - UNION - SELECT mangas.*, COALESCE(UR.unreadCount, 0) AS unread_count, COALESCE(R.readCount, 0) AS read_count - FROM mangas - LEFT JOIN ( - SELECT merged.merge_id, COUNT(*) as unreadCount - FROM merged - JOIN chapters - ON chapters.manga_id = merged.manga_id - WHERE chapters.read = 0 - GROUP BY merged.merge_id - ) AS UR - ON mangas._id = UR.merge_id - LEFT JOIN ( - SELECT merged.merge_id, COUNT(*) as readCount - FROM merged - JOIN chapters - ON chapters.manga_id = merged.manga_id - WHERE chapters.read = 1 - GROUP BY merged.merge_id - ) AS R - ON mangas._id = R.merge_id - WHERE mangas.favorite = 1 AND mangas.source = $MERGED_SOURCE_ID - GROUP BY mangas._id - ORDER BY mangas.title - ) AS M + 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 AND M.source <> $MERGED_SOURCE_ID + UNION + 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 ( - SELECT * - FROM mangas_categories - ) AS MC - ON M._id = MC.manga_id; + SELECT merged.manga_id,merged.merge_id + FROM merged + GROUP BY merged.merge_id + ) as ME + ON ME.merge_id = M._id + LEFT JOIN mangas_categories AS MC + ON MC.manga_id = M._id + LEFT JOIN( + SELECT + ME.merge_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 + LEFT JOIN merged as ME + ON ME.manga_id = chapters.manga_id + GROUP BY ME.merge_id + ) AS C + ON ME.merge_id = C.merge_id + WHERE M.favorite = 1 AND M.source = $MERGED_SOURCE_ID; """.trimIndent(), 1, ) 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 e115bffce..a0a128eb6 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, List?, UpdateStrategy) -> Manga = - { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewer, chapterFlags, coverLastModified, dateAdded, filteredScanlators, updateStrategy -> + { id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, filteredScanlators, updateStrategy -> Manga( id = id, source = source, favorite = favorite, lastUpdate = lastUpdate ?: 0, dateAdded = dateAdded, - viewerFlags = viewer, + viewerFlags = viewerFlags, chapterFlags = chapterFlags, coverLastModified = coverLastModified, url = url, @@ -33,11 +33,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, List?, UpdateStrategy, Long, Long, Long) -> LibraryManga = - { _id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, nextUpdate, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, filteredScanlators, updateStrategy, unreadCount, readCount, category -> +val libraryManga: (Long, Long, String, String?, String?, String?, List?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List?, 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, filteredScanlators, updateStrategy, unreadCount, readCount, latestUpload, chapterFetchedAt, lastRead, category -> LibraryManga( manga = mangaMapper( - _id, + id, source, url, artist, @@ -61,5 +61,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 1443b6861..d64532c13 100644 --- a/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt +++ b/app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt @@ -40,12 +40,12 @@ class MangaRepositoryImpl( override suspend fun getLibraryManga(): List { return handler.awaitList { (handler as AndroidDatabaseHandler).getLibraryQuery() } - // return handler.awaitList { mangasQueries.getLibrary(libraryManga) } + // return handler.awaitList { libraryViewQueries.library(libraryManga) } } override fun getLibraryMangaAsFlow(): Flow> { return handler.subscribeToList { (handler as AndroidDatabaseHandler).getLibraryQuery() } - // 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 9e9916697..74a41357b 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 aed12c3fb..91d3c13f4 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -17,7 +17,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.UnsortedPreferences import eu.kanade.domain.base.BasePreferences import eu.kanade.domain.category.interactor.GetCategories @@ -124,7 +123,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(), @@ -399,34 +397,6 @@ 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++ } - } - } - // SY --> val listOfTags by lazy { libraryPreferences.sortTagsForLibrary().get() @@ -467,9 +437,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) @@ -485,16 +453,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 55fbc571e..170e2857b 100644 --- a/app/src/main/sqldelight/data/mangas.sq +++ b/app/src/main/sqldelight/data/mangas.sq @@ -82,62 +82,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 :sourceIdsAND AND _id NOT IN (