diff --git a/app/src/main/java/com/hippo/ehviewer/EhDB.kt b/app/src/main/java/com/hippo/ehviewer/EhDB.kt index 79254a824..18dee33ff 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhDB.kt +++ b/app/src/main/java/com/hippo/ehviewer/EhDB.kt @@ -23,7 +23,6 @@ import androidx.paging.PagingSource import arrow.fx.coroutines.release import arrow.fx.coroutines.resource import com.hippo.ehviewer.client.data.GalleryInfo -import com.hippo.ehviewer.dao.BasicDao import com.hippo.ehviewer.dao.DownloadDirname import com.hippo.ehviewer.dao.DownloadInfo import com.hippo.ehviewer.dao.DownloadLabel @@ -34,10 +33,11 @@ import com.hippo.ehviewer.dao.LocalFavoriteInfo import com.hippo.ehviewer.dao.QuickSearch import com.hippo.ehviewer.download.DownloadManager import com.hippo.ehviewer.util.sendTo +import kotlinx.coroutines.runBlocking import splitties.arch.room.roomDb object EhDB { - private val db = roomDb("eh.db") { allowMainThreadQueries() } + private val db = roomDb("eh.db") // Fix state @get:Synchronized @@ -151,13 +151,11 @@ object EhDB { dao.delete(raw!!) } - @Synchronized - fun removeLocalFavorites(gid: Long) { + suspend fun removeLocalFavorites(gid: Long) { db.localFavoritesDao().deleteByKey(gid) } - @Synchronized - fun removeLocalFavorites(gidArray: LongArray) { + suspend fun removeLocalFavorites(gidArray: LongArray) { val dao = db.localFavoritesDao() for (gid in gidArray) { dao.deleteByKey(gid) @@ -167,11 +165,11 @@ object EhDB { @Synchronized fun containLocalFavorites(gid: Long): Boolean { val dao = db.localFavoritesDao() - return dao.contains(gid) + // TODO: remove runBlocking + return runBlocking { dao.contains(gid) } } - @Synchronized - fun putLocalFavorites(galleryInfo: GalleryInfo) { + suspend fun putLocalFavorites(galleryInfo: GalleryInfo) { val dao = db.localFavoritesDao() if (null == dao.load(galleryInfo.gid)) { val info: LocalFavoriteInfo @@ -185,46 +183,36 @@ object EhDB { } } - @Synchronized - fun putLocalFavorites(galleryInfoList: List) { + suspend fun putLocalFavorites(galleryInfoList: List) { for (gi in galleryInfoList) { putLocalFavorites(gi) } } - @get:Synchronized - val allQuickSearch: List - get() { - val dao = db.quickSearchDao() - return dao.list() - } + suspend fun getAllQuickSearch() = db.quickSearchDao().list() - @Synchronized - fun insertQuickSearch(quickSearch: QuickSearch) { + suspend fun insertQuickSearch(quickSearch: QuickSearch) { val dao = db.quickSearchDao() quickSearch.id = null quickSearch.time = System.currentTimeMillis() quickSearch.id = dao.insert(quickSearch) } - @Synchronized - fun importQuickSearch(quickSearchList: List) { + private suspend fun importQuickSearch(quickSearchList: List) { val dao = db.quickSearchDao() for (quickSearch in quickSearchList) { dao.insert(quickSearch!!) } } - @Synchronized - fun deleteQuickSearch(quickSearch: QuickSearch?) { + suspend fun deleteQuickSearch(quickSearch: QuickSearch?) { val dao = db.quickSearchDao() if (quickSearch != null) { dao.delete(quickSearch) } } - @Synchronized - fun moveQuickSearch(fromPosition: Int, toPosition: Int) { + suspend fun moveQuickSearch(fromPosition: Int, toPosition: Int) { if (fromPosition == toPosition) { return } @@ -254,8 +242,7 @@ object EhDB { fun searchLocalFav(keyword: String) = db.localFavoritesDao().listLazy("%$keyword%") - @Synchronized - fun putHistoryInfo(galleryInfo: GalleryInfo?) { + suspend fun putHistoryInfo(galleryInfo: GalleryInfo?) { val dao = db.historyDao() val info: HistoryInfo = if (galleryInfo is HistoryInfo) { galleryInfo @@ -270,8 +257,7 @@ object EhDB { } } - @Synchronized - fun modifyHistoryInfoFavslotNonRefresh(gid: Long, slot: Int) { + suspend fun modifyHistoryInfoFavslotNonRefresh(gid: Long, slot: Int) { val dao = db.historyDao() dao.load(gid)?.let { it.favoriteSlot = slot @@ -279,8 +265,7 @@ object EhDB { } } - @Synchronized - fun putHistoryInfo(historyInfoList: List) { + private suspend fun putHistoryInfo(historyInfoList: List) { val dao = db.historyDao() for (info in historyInfoList) { if (null == dao.load(info.gid)) { @@ -289,29 +274,20 @@ object EhDB { } } - @Synchronized - fun deleteHistoryInfo(info: HistoryInfo?) { + suspend fun deleteHistoryInfo(info: HistoryInfo?) { val dao = db.historyDao() dao.delete(info!!) } - @Synchronized - fun clearHistoryInfo() { + suspend fun clearHistoryInfo() { val dao = db.historyDao() dao.deleteAll() } - @get:Synchronized - val allFilter: List - get() = db.filterDao().list() + suspend fun getAllFilter() = db.filterDao().list() - @Synchronized - fun addFilter(filter: Filter): Boolean { - val existFilter: Filter? = try { - db.filterDao().load(filter.text, filter.mode.field) - } catch (e: Exception) { - null - } + suspend fun addFilter(filter: Filter): Boolean { + val existFilter = runCatching { db.filterDao().load(filter.text, filter.mode.field) }.getOrNull() return if (existFilter == null) { filter.id = null filter.id = db.filterDao().insert(filter) @@ -321,22 +297,15 @@ object EhDB { } } - @Synchronized - fun deleteFilter(filter: Filter) { + suspend fun deleteFilter(filter: Filter) { db.filterDao().delete(filter) } - @Synchronized - fun triggerFilter(filter: Filter) { + suspend fun triggerFilter(filter: Filter) { filter.enable = !filter.enable db.filterDao().update(filter) } - private fun copyDao(from: BasicDao, to: BasicDao) { - val list = from.list() - for (item in list) to.insert(item) - } - suspend fun exportDB(context: Context, uri: Uri) { val ehExportName = "eh.export.db" resource { @@ -346,13 +315,13 @@ object EhDB { it.close() context.deleteDatabase(ehExportName) } use { newDb -> - copyDao(db.downloadsDao(), newDb.downloadsDao()) - copyDao(db.downloadLabelDao(), newDb.downloadLabelDao()) - copyDao(db.downloadDirnameDao(), newDb.downloadDirnameDao()) - copyDao(db.historyDao(), newDb.historyDao()) - copyDao(db.quickSearchDao(), newDb.quickSearchDao()) - copyDao(db.localFavoritesDao(), newDb.localFavoritesDao()) - copyDao(db.filterDao(), newDb.filterDao()) + db.downloadsDao().list().forEach { newDb.downloadsDao().insert(it) } + db.downloadLabelDao().list().forEach { newDb.downloadLabelDao().insert(it) } + db.downloadDirnameDao().list().forEach { newDb.downloadDirnameDao().insert(it) } + db.historyDao().list().forEach { newDb.historyDao().insert(it) } + db.quickSearchDao().list().forEach { newDb.quickSearchDao().insert(it) } + db.localFavoritesDao().list().forEach { newDb.localFavoritesDao().insert(it) } + db.filterDao().list().forEach { newDb.filterDao().insert(it) } newDb.close() val dbFile = context.getDatabasePath(ehExportName) context.contentResolver.openFileDescriptor(uri, "rw")!!.use { toFd -> diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhFilter.kt b/app/src/main/java/com/hippo/ehviewer/client/EhFilter.kt index 9c51e3d87..b9c95fe52 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhFilter.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhFilter.kt @@ -38,7 +38,7 @@ object EhFilter : CoroutineScope { override val coroutineContext = Dispatchers.IO.limitedParallelism(1) private fun Filter.launchOps( callback: ((R) -> Unit)? = null, - ops: Filter.() -> R, + ops: suspend Filter.() -> R, ) = launch { ops().let { callback?.invoke(it) } } fun Filter.remember(callback: ((Boolean) -> Unit)? = null) = launchOps(callback) { EhDB.addFilter(this).also { if (it) memorizeFilter(this) } @@ -56,9 +56,7 @@ object EhFilter : CoroutineScope { } } - init { - EhDB.allFilter.forEach(::memorizeFilter) - } + init { launch { EhDB.getAllFilter().forEach(::memorizeFilter) } } private fun memorizeFilter(filter: Filter) { when (filter.mode) { diff --git a/app/src/main/java/com/hippo/ehviewer/dao/BasicDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/BasicDao.kt deleted file mode 100644 index a37d678fa..000000000 --- a/app/src/main/java/com/hippo/ehviewer/dao/BasicDao.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.hippo.ehviewer.dao - -interface BasicDao { - fun list(): List - fun insert(t: T): Long -} diff --git a/app/src/main/java/com/hippo/ehviewer/dao/CookiesDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/CookiesDao.kt index 2b142faff..5919119b4 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/CookiesDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/CookiesDao.kt @@ -6,5 +6,5 @@ import androidx.room.Query @Dao interface CookiesDao { @Query("SELECT * FROM OK_HTTP_3_COOKIE") - fun list(): List + suspend fun list(): List } diff --git a/app/src/main/java/com/hippo/ehviewer/dao/DownloadDirnameDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/DownloadDirnameDao.kt index 426b08811..c308ceb6c 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/DownloadDirnameDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/DownloadDirnameDao.kt @@ -6,7 +6,7 @@ import androidx.room.Query import androidx.room.Update @Dao -interface DownloadDirnameDao : BasicDao { +interface DownloadDirnameDao { @Query("SELECT * FROM DOWNLOAD_DIRNAME WHERE GID = :gid") fun load(gid: Long): DownloadDirname? @@ -14,14 +14,11 @@ interface DownloadDirnameDao : BasicDao { fun update(downloadDirname: DownloadDirname) @Insert - override fun insert(t: DownloadDirname): Long + fun insert(t: DownloadDirname): Long @Query("DELETE FROM DOWNLOAD_DIRNAME WHERE GID = :gid") fun deleteByKey(gid: Long) - @Query("DELETE FROM DOWNLOAD_DIRNAME") - fun deleteAll() - @Query("SELECT * FROM DOWNLOAD_DIRNAME") - override fun list(): List + fun list(): List } diff --git a/app/src/main/java/com/hippo/ehviewer/dao/DownloadLabelDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/DownloadLabelDao.kt index 9f345100b..41f39e6b8 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/DownloadLabelDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/DownloadLabelDao.kt @@ -7,9 +7,9 @@ import androidx.room.Query import androidx.room.Update @Dao -interface DownloadLabelDao : BasicDao { +interface DownloadLabelDao { @Query("SELECT * FROM DOWNLOAD_LABELS ORDER BY TIME ASC") - override fun list(): List + fun list(): List @Query("SELECT * FROM DOWNLOAD_LABELS ORDER BY TIME ASC LIMIT :limit OFFSET :offset") fun list(offset: Int, limit: Int): List @@ -21,7 +21,7 @@ interface DownloadLabelDao : BasicDao { fun update(downloadLabel: DownloadLabel) @Insert - override fun insert(t: DownloadLabel): Long + fun insert(t: DownloadLabel): Long @Delete fun delete(downloadLabel: DownloadLabel) diff --git a/app/src/main/java/com/hippo/ehviewer/dao/DownloadsDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/DownloadsDao.kt index 31bcdda00..654aec35d 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/DownloadsDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/DownloadsDao.kt @@ -7,9 +7,9 @@ import androidx.room.Query import androidx.room.Update @Dao -interface DownloadsDao : BasicDao { +interface DownloadsDao { @Query("SELECT * FROM DOWNLOADS ORDER BY TIME DESC") - override fun list(): List + fun list(): List @Query("SELECT * FROM DOWNLOADS ORDER BY TIME DESC LIMIT :limit OFFSET :offset") fun list(offset: Int, limit: Int): List @@ -24,7 +24,7 @@ interface DownloadsDao : BasicDao { fun update(downloadInfo: DownloadInfo) @Insert - override fun insert(t: DownloadInfo): Long + fun insert(t: DownloadInfo): Long @Delete fun delete(downloadInfo: DownloadInfo) diff --git a/app/src/main/java/com/hippo/ehviewer/dao/FilterDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/FilterDao.kt index 2262d0350..eeffc7fcf 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/FilterDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/FilterDao.kt @@ -7,19 +7,19 @@ import androidx.room.Query import androidx.room.Update @Dao -interface FilterDao : BasicDao { +interface FilterDao { @Query("SELECT * FROM FILTER") - override fun list(): List + suspend fun list(): List @Update - fun update(filter: Filter) + suspend fun update(filter: Filter) @Insert - override fun insert(t: Filter): Long + suspend fun insert(t: Filter): Long @Delete - fun delete(filter: Filter) + suspend fun delete(filter: Filter) @Query("SELECT * FROM FILTER WHERE TEXT = :text AND MODE = :mode") - fun load(text: String, mode: Int): Filter? + suspend fun load(text: String, mode: Int): Filter? } diff --git a/app/src/main/java/com/hippo/ehviewer/dao/HistoryDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/HistoryDao.kt index 1f6b3b2eb..97d40a2c9 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/HistoryDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/HistoryDao.kt @@ -8,31 +8,31 @@ import androidx.room.Query import androidx.room.Update @Dao -interface HistoryDao : BasicDao { +interface HistoryDao { @Query("SELECT * FROM HISTORY WHERE GID = :gid") - fun load(gid: Long): HistoryInfo? + suspend fun load(gid: Long): HistoryInfo? @Query("SELECT * FROM HISTORY ORDER BY TIME DESC") - override fun list(): List + suspend fun list(): List @Query("SELECT * FROM HISTORY ORDER BY TIME DESC LIMIT :limit OFFSET :offset") - fun list(offset: Int, limit: Int): List + suspend fun list(offset: Int, limit: Int): List @Query("SELECT * FROM HISTORY ORDER BY TIME DESC") fun listLazy(): PagingSource @Update - fun update(historyInfo: HistoryInfo) + suspend fun update(historyInfo: HistoryInfo) @Insert - override fun insert(t: HistoryInfo): Long + suspend fun insert(t: HistoryInfo): Long @Delete - fun delete(historyInfo: HistoryInfo) + suspend fun delete(historyInfo: HistoryInfo) @Delete - fun delete(historyInfo: List) + suspend fun delete(historyInfo: List) @Query("DELETE FROM HISTORY") - fun deleteAll() + suspend fun deleteAll() } diff --git a/app/src/main/java/com/hippo/ehviewer/dao/LocalFavoritesDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/LocalFavoritesDao.kt index b7433feec..1a54ec49f 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/LocalFavoritesDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/LocalFavoritesDao.kt @@ -7,31 +7,28 @@ import androidx.room.Insert import androidx.room.Query @Dao -interface LocalFavoritesDao : BasicDao { +interface LocalFavoritesDao { @Query("SELECT * FROM LOCAL_FAVORITES ORDER BY TIME DESC") - override fun list(): List + suspend fun list(): List @Query("SELECT * FROM LOCAL_FAVORITES ORDER BY TIME DESC") fun listLazy(): PagingSource - @Query("SELECT * FROM LOCAL_FAVORITES WHERE TITLE LIKE :title ORDER BY TIME DESC") - fun list(title: String): List - @Query("SELECT * FROM LOCAL_FAVORITES WHERE TITLE LIKE :title ORDER BY TIME DESC") fun listLazy(title: String): PagingSource @Query("SELECT * FROM LOCAL_FAVORITES WHERE GID = :gid") - fun load(gid: Long): LocalFavoriteInfo? + suspend fun load(gid: Long): LocalFavoriteInfo? @Query("SELECT EXISTS(SELECT * FROM LOCAL_FAVORITES WHERE GID = :gid)") - fun contains(gid: Long): Boolean + suspend fun contains(gid: Long): Boolean @Insert - override fun insert(t: LocalFavoriteInfo): Long + suspend fun insert(t: LocalFavoriteInfo): Long @Delete - fun delete(localFavoriteInfo: LocalFavoriteInfo) + suspend fun delete(localFavoriteInfo: LocalFavoriteInfo) @Query("DELETE FROM LOCAL_FAVORITES WHERE GID = :gid") - fun deleteByKey(gid: Long) + suspend fun deleteByKey(gid: Long) } diff --git a/app/src/main/java/com/hippo/ehviewer/dao/QuickSearchDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/QuickSearchDao.kt index bfdd8bbf8..c553dd7f9 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/QuickSearchDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/QuickSearchDao.kt @@ -7,22 +7,22 @@ import androidx.room.Query import androidx.room.Update @Dao -interface QuickSearchDao : BasicDao { +interface QuickSearchDao { @Query("SELECT * FROM QUICK_SEARCH ORDER BY TIME ASC") - override fun list(): List + suspend fun list(): List @Query("SELECT * FROM QUICK_SEARCH ORDER BY TIME ASC LIMIT :limit OFFSET :offset") - fun list(offset: Int, limit: Int): List + suspend fun list(offset: Int, limit: Int): List @Update - fun update(downloadLabels: List) + suspend fun update(downloadLabels: List) @Update - fun update(quickSearch: QuickSearch) + suspend fun update(quickSearch: QuickSearch) @Insert - override fun insert(t: QuickSearch): Long + suspend fun insert(t: QuickSearch): Long @Delete - fun delete(quickSearch: QuickSearch) + suspend fun delete(quickSearch: QuickSearch) } diff --git a/app/src/main/java/com/hippo/ehviewer/dao/SearchDao.kt b/app/src/main/java/com/hippo/ehviewer/dao/SearchDao.kt index 90eb485d2..e5445d625 100644 --- a/app/src/main/java/com/hippo/ehviewer/dao/SearchDao.kt +++ b/app/src/main/java/com/hippo/ehviewer/dao/SearchDao.kt @@ -7,23 +7,23 @@ import androidx.room.Query @Dao interface SearchDao { @Query("DELETE FROM suggestions WHERE `query` = :query") - fun deleteQuery(query: String) + suspend fun deleteQuery(query: String) @Query("SELECT * FROM suggestions WHERE `query` LIKE :prefix || '%' ORDER BY date DESC LIMIT :limit") - fun rawSuggestions(prefix: String, limit: Int): Array + suspend fun rawSuggestions(prefix: String, limit: Int): Array @Query("SELECT * FROM suggestions ORDER BY date DESC LIMIT :limit") - fun list(limit: Int): Array + suspend fun list(limit: Int): Array @Insert - fun insert(search: Search) + suspend fun insert(search: Search) - fun addQuery(query: String) { + suspend fun addQuery(query: String) { deleteQuery(query) if (query.isBlank()) return val search = Search(System.currentTimeMillis(), query) insert(search) } - fun suggestions(prefix: String, limit: Int) = (if (prefix.isBlank()) list(limit) else rawSuggestions(prefix, limit)).map { it.query } + suspend fun suggestions(prefix: String, limit: Int) = (if (prefix.isBlank()) list(limit) else rawSuggestions(prefix, limit)).map { it.query } } diff --git a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt index e6113380a..d503dee10 100644 --- a/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt +++ b/app/src/main/java/com/hippo/ehviewer/download/DownloadManager.kt @@ -35,6 +35,7 @@ import com.hippo.ehviewer.util.ConcurrentPool import com.hippo.ehviewer.util.LongList import com.hippo.ehviewer.util.SimpleHandler import com.hippo.unifile.UniFile +import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.withUIContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -227,8 +228,10 @@ object DownloadManager : OnSpiderListener { // Make sure download is running ensureDownload() - // Add it to history - EhDB.putHistoryInfo(info) + launchIO { + // Add it to history + EhDB.putHistoryInfo(info) + } } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt index d0de2d478..6f0d66e23 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.kt @@ -619,7 +619,7 @@ class GalleryListScene : SearchBarScene() { drawerBinding.recyclerViewDrawer.visibility = View.GONE } lifecycleScope.launchIO { - mQuickSearchList = EhDB.allQuickSearch as MutableList + mQuickSearchList = EhDB.getAllQuickSearch() as MutableList if (mQuickSearchList.isNotEmpty()) { withUIContext { drawerBinding.tip.visibility = View.GONE