mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
refactor(db): Migrate clear database queries to SQLDelight
This commit is contained in:
parent
cf06ebdb8b
commit
da1f60c5c5
7 changed files with 24 additions and 125 deletions
|
@ -1,3 +1,3 @@
|
||||||
package eu.kanade.tachiyomi.data.database.models
|
package eu.kanade.tachiyomi.data.database.models
|
||||||
|
|
||||||
data class SourceIdMangaCount(val source: Long, val count: Int)
|
data class SourceIdMangaCount(val source: Long, val count: Long)
|
||||||
|
|
|
@ -1,36 +1,15 @@
|
||||||
package eu.kanade.tachiyomi.data.database.queries
|
package eu.kanade.tachiyomi.data.database.queries
|
||||||
|
|
||||||
import com.pushtorefresh.storio.Queries
|
|
||||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
|
||||||
import com.pushtorefresh.storio.sqlite.queries.Query
|
import com.pushtorefresh.storio.sqlite.queries.Query
|
||||||
import com.pushtorefresh.storio.sqlite.queries.RawQuery
|
|
||||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||||
import eu.kanade.tachiyomi.data.database.models.SourceIdMangaCount
|
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaDateAddedPutResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaDateAddedPutResolver
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaTitlePutResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaTitlePutResolver
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.SourceIdMangaCountGetResolver
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||||
|
|
||||||
interface MangaQueries : DbProvider {
|
interface MangaQueries : DbProvider {
|
||||||
|
|
||||||
fun getDuplicateLibraryManga(manga: Manga) = db.get()
|
|
||||||
.`object`(Manga::class.java)
|
|
||||||
.withQuery(
|
|
||||||
Query.builder()
|
|
||||||
.table(MangaTable.TABLE)
|
|
||||||
.where("${MangaTable.COL_FAVORITE} = 1 AND LOWER(${MangaTable.COL_TITLE}) = ? AND ${MangaTable.COL_SOURCE} != ?")
|
|
||||||
.whereArgs(
|
|
||||||
manga.title.lowercase(),
|
|
||||||
manga.source,
|
|
||||||
)
|
|
||||||
.limit(1)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.prepare()
|
|
||||||
|
|
||||||
fun getFavoriteMangas() = db.get()
|
fun getFavoriteMangas() = db.get()
|
||||||
.listOfObjects(Manga::class.java)
|
.listOfObjects(Manga::class.java)
|
||||||
.withQuery(
|
.withQuery(
|
||||||
|
@ -65,17 +44,6 @@ interface MangaQueries : DbProvider {
|
||||||
)
|
)
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
fun getSourceIdsWithNonLibraryManga() = db.get()
|
|
||||||
.listOfObjects(SourceIdMangaCount::class.java)
|
|
||||||
.withQuery(
|
|
||||||
RawQuery.builder()
|
|
||||||
.query(getSourceIdsWithNonLibraryMangaQuery())
|
|
||||||
.observesTables(MangaTable.TABLE)
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.withGetResolver(SourceIdMangaCountGetResolver.INSTANCE)
|
|
||||||
.prepare()
|
|
||||||
|
|
||||||
fun insertManga(manga: Manga) = db.put().`object`(manga).prepare()
|
fun insertManga(manga: Manga) = db.put().`object`(manga).prepare()
|
||||||
|
|
||||||
// FIXME: Migrate to SQLDelight, on halt: used by StorIO's inTransaction
|
// FIXME: Migrate to SQLDelight, on halt: used by StorIO's inTransaction
|
||||||
|
@ -96,38 +64,4 @@ interface MangaQueries : DbProvider {
|
||||||
.withPutResolver(MangaTitlePutResolver())
|
.withPutResolver(MangaTitlePutResolver())
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
fun deleteMangasNotInLibraryBySourceIds(sourceIds: List<Long>) = db.delete()
|
|
||||||
.byQuery(
|
|
||||||
DeleteQuery.builder()
|
|
||||||
.table(MangaTable.TABLE)
|
|
||||||
.where("${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_SOURCE} IN (${Queries.placeholders(sourceIds.size)})")
|
|
||||||
.whereArgs(0, *sourceIds.toTypedArray())
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.prepare()
|
|
||||||
|
|
||||||
fun deleteMangasNotInLibraryAndNotReadBySourceIds(sourceIds: List<Long>) = db.delete()
|
|
||||||
.byQuery(
|
|
||||||
DeleteQuery.builder()
|
|
||||||
.table(MangaTable.TABLE)
|
|
||||||
.where(
|
|
||||||
"""
|
|
||||||
${MangaTable.COL_FAVORITE} = ? AND ${MangaTable.COL_SOURCE} IN (${Queries.placeholders(sourceIds.size)}) AND ${MangaTable.COL_ID} NOT IN (
|
|
||||||
SELECT ${ChapterTable.COL_MANGA_ID} FROM ${ChapterTable.TABLE} WHERE ${ChapterTable.COL_READ} = 1 OR ${ChapterTable.COL_LAST_PAGE_READ} != 0
|
|
||||||
)
|
|
||||||
""".trimIndent(),
|
|
||||||
)
|
|
||||||
.whereArgs(0, *sourceIds.toTypedArray())
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.prepare()
|
|
||||||
|
|
||||||
fun getReadNotInLibraryMangas() = db.get()
|
|
||||||
.listOfObjects(Manga::class.java)
|
|
||||||
.withQuery(
|
|
||||||
RawQuery.builder()
|
|
||||||
.query(getReadMangaNotInLibraryQuery())
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
.prepare()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.kanade.tachiyomi.data.database.queries
|
package eu.kanade.tachiyomi.data.database.queries
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.SourceIdMangaCountGetResolver
|
|
||||||
import eu.kanade.tachiyomi.ui.recents.RecentsPresenter
|
import eu.kanade.tachiyomi.ui.recents.RecentsPresenter
|
||||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable as Category
|
import eu.kanade.tachiyomi.data.database.tables.CategoryTable as Category
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable as Chapter
|
||||||
|
@ -293,25 +292,3 @@ fun getCategoriesForMangaQuery() =
|
||||||
WHERE ${MangaCategory.COL_MANGA_ID} = ?
|
WHERE ${MangaCategory.COL_MANGA_ID} = ?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
/** Query to get the list of sources in the database that have
|
|
||||||
* non-library manga, and how many
|
|
||||||
*/
|
|
||||||
fun getSourceIdsWithNonLibraryMangaQuery() =
|
|
||||||
"""
|
|
||||||
SELECT ${Manga.COL_SOURCE}, COUNT(*) as ${SourceIdMangaCountGetResolver.COL_COUNT}
|
|
||||||
FROM ${Manga.TABLE}
|
|
||||||
WHERE ${Manga.COL_FAVORITE} = 0
|
|
||||||
GROUP BY ${Manga.COL_SOURCE}
|
|
||||||
"""
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query to get manga that are not in library, but have read chapters
|
|
||||||
*/
|
|
||||||
fun getReadMangaNotInLibraryQuery() =
|
|
||||||
"""
|
|
||||||
SELECT ${Manga.TABLE}.*
|
|
||||||
FROM ${Manga.TABLE}
|
|
||||||
WHERE ${Manga.COL_FAVORITE} = 0 AND ${Manga.COL_ID} IN(
|
|
||||||
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} FROM ${Chapter.TABLE} WHERE ${Chapter.COL_READ} = 1 OR ${Chapter.COL_LAST_PAGE_READ} != 0
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.data.database.resolvers
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.database.Cursor
|
|
||||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.SourceIdMangaCount
|
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
|
||||||
|
|
||||||
class SourceIdMangaCountGetResolver : DefaultGetResolver<SourceIdMangaCount>() {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val INSTANCE = SourceIdMangaCountGetResolver()
|
|
||||||
const val COL_COUNT = "manga_count"
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("Range")
|
|
||||||
override fun mapFromCursor(cursor: Cursor): SourceIdMangaCount {
|
|
||||||
val sourceID = cursor.getLong(cursor.getColumnIndex(MangaTable.COL_SOURCE))
|
|
||||||
val count = cursor.getInt(cursor.getColumnIndex(COL_COUNT))
|
|
||||||
|
|
||||||
return SourceIdMangaCount(sourceID, count)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.setting.controllers.database
|
package eu.kanade.tachiyomi.ui.setting.controllers.database
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.models.SourceIdMangaCount
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
|
||||||
import eu.kanade.tachiyomi.util.system.launchIO
|
import eu.kanade.tachiyomi.util.system.launchIO
|
||||||
|
@ -12,8 +12,6 @@ import yokai.data.DatabaseHandler
|
||||||
|
|
||||||
class ClearDatabasePresenter : BaseCoroutinePresenter<ClearDatabaseController>() {
|
class ClearDatabasePresenter : BaseCoroutinePresenter<ClearDatabaseController>() {
|
||||||
|
|
||||||
private val db = Injekt.get<DatabaseHelper>()
|
|
||||||
|
|
||||||
private val handler = Injekt.get<DatabaseHandler>()
|
private val handler = Injekt.get<DatabaseHandler>()
|
||||||
|
|
||||||
private val sourceManager = Injekt.get<SourceManager>()
|
private val sourceManager = Injekt.get<SourceManager>()
|
||||||
|
@ -37,12 +35,14 @@ class ClearDatabasePresenter : BaseCoroutinePresenter<ClearDatabaseController>()
|
||||||
|
|
||||||
fun clearDatabaseForSourceIds(sources: List<Long>, keepReadManga: Boolean) {
|
fun clearDatabaseForSourceIds(sources: List<Long>, keepReadManga: Boolean) {
|
||||||
presenterScope.launchIO {
|
presenterScope.launchIO {
|
||||||
if (keepReadManga) {
|
handler.await(true) {
|
||||||
db.deleteMangasNotInLibraryAndNotReadBySourceIds(sources).executeAsBlocking()
|
if (keepReadManga) {
|
||||||
} else {
|
mangasQueries.deleteNotInLibraryAndNotReadBySourceIds(sources)
|
||||||
db.deleteMangasNotInLibraryBySourceIds(sources).executeAsBlocking()
|
} else {
|
||||||
|
mangasQueries.deleteNotInLibraryBySourceIds(sources)
|
||||||
|
}
|
||||||
|
historyQueries.deleteAllUnread()
|
||||||
}
|
}
|
||||||
handler.await { historyQueries.deleteAllUnread() }
|
|
||||||
getDatabaseSources()
|
getDatabaseSources()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,9 @@ class ClearDatabasePresenter : BaseCoroutinePresenter<ClearDatabaseController>()
|
||||||
|
|
||||||
private suspend fun getDatabaseSources() = withUIContext {
|
private suspend fun getDatabaseSources() = withUIContext {
|
||||||
hasStubSources = false
|
hasStubSources = false
|
||||||
val sources = db.getSourceIdsWithNonLibraryManga().executeAsBlocking()
|
val sources = handler.awaitList {
|
||||||
|
mangasQueries.getSourceIdsOfNotInLibrary { source, count -> SourceIdMangaCount(source, count) }
|
||||||
|
}
|
||||||
.map {
|
.map {
|
||||||
val sourceObj = sourceManager.getOrStub(it.source)
|
val sourceObj = sourceManager.getOrStub(it.source)
|
||||||
hasStubSources = sourceObj is SourceManager.StubSource || hasStubSources
|
hasStubSources = sourceObj is SourceManager.StubSource || hasStubSources
|
||||||
|
|
|
@ -15,7 +15,7 @@ import eu.kanade.tachiyomi.source.icon
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.util.lang.getString
|
import yokai.util.lang.getString
|
||||||
|
|
||||||
data class ClearDatabaseSourceItem(val source: Source, val mangaCount: Int) : AbstractFlexibleItem<ClearDatabaseSourceItem.Holder>() {
|
data class ClearDatabaseSourceItem(val source: Source, val mangaCount: Long) : AbstractFlexibleItem<ClearDatabaseSourceItem.Holder>() {
|
||||||
|
|
||||||
val isStub: Boolean = source is SourceManager.StubSource
|
val isStub: Boolean = source is SourceManager.StubSource
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ data class ClearDatabaseSourceItem(val source: Source, val mangaCount: Int) : Ab
|
||||||
|
|
||||||
private val binding = ClearDatabaseSourceItemBinding.bind(view)
|
private val binding = ClearDatabaseSourceItemBinding.bind(view)
|
||||||
|
|
||||||
fun bind(source: Source, count: Int) {
|
fun bind(source: Source, count: Long) {
|
||||||
binding.title.text = source.toString()
|
binding.title.text = source.toString()
|
||||||
binding.description.text = itemView.context.getString(MR.strings.clear_database_source_item_count, count)
|
binding.description.text = itemView.context.getString(MR.strings.clear_database_source_item_count, count)
|
||||||
|
|
||||||
|
|
|
@ -87,8 +87,17 @@ WHERE _id = :mangaId;
|
||||||
selectLastInsertedRowId:
|
selectLastInsertedRowId:
|
||||||
SELECT last_insert_rowid();
|
SELECT last_insert_rowid();
|
||||||
|
|
||||||
|
deleteNotInLibraryBySourceIds:
|
||||||
|
DELETE FROM mangas
|
||||||
|
WHERE favorite = 0 AND source IN :sourceIds;
|
||||||
|
|
||||||
deleteNotInLibraryAndNotReadBySourceIds:
|
deleteNotInLibraryAndNotReadBySourceIds:
|
||||||
DELETE FROM mangas
|
DELETE FROM mangas
|
||||||
WHERE favorite = :favorite AND source IN :sourceIds AND _id NOT IN (
|
WHERE favorite = 0 AND source IN :sourceIds AND _id NOT IN (
|
||||||
SELECT chapters.manga_id FROM chapters WHERE read = 1 OR last_page_read != 0
|
SELECT chapters.manga_id FROM chapters WHERE read = 1 OR last_page_read != 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
getSourceIdsOfNotInLibrary:
|
||||||
|
SELECT source, count(*) AS count
|
||||||
|
FROM mangas WHERE favorite = 0
|
||||||
|
GROUP BY source;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue