mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 02:34:39 +00:00
refactor(db): Fully migrated from StorIO to SQLDelight
This commit is contained in:
parent
a832e4d6dc
commit
07c1e7e67f
67 changed files with 156 additions and 1755 deletions
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.backup.restore.restorers
|
|||
import eu.kanade.tachiyomi.data.backup.models.BackupCategory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupHistory
|
||||
import eu.kanade.tachiyomi.data.backup.models.BackupManga
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
|
@ -31,9 +30,9 @@ import yokai.domain.manga.interactor.GetManga
|
|||
import yokai.domain.manga.interactor.InsertManga
|
||||
import yokai.domain.manga.interactor.UpdateManga
|
||||
import yokai.domain.track.interactor.GetTrack
|
||||
import yokai.domain.track.interactor.InsertTrack
|
||||
|
||||
class MangaBackupRestorer(
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val customMangaManager: CustomMangaManager = Injekt.get(),
|
||||
private val handler: DatabaseHandler = Injekt.get(),
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
|
@ -47,6 +46,7 @@ class MangaBackupRestorer(
|
|||
private val getHistory: GetHistory = Injekt.get(),
|
||||
private val upsertHistory: UpsertHistory = Injekt.get(),
|
||||
private val getTrack: GetTrack = Injekt.get(),
|
||||
private val insertTrack: InsertTrack = Injekt.get(),
|
||||
) {
|
||||
suspend fun restoreManga(
|
||||
backupManga: BackupManga,
|
||||
|
@ -272,7 +272,7 @@ class MangaBackupRestorer(
|
|||
}
|
||||
// Update database
|
||||
if (trackToUpdate.isNotEmpty()) {
|
||||
db.insertTracks(trackToUpdate).executeAsBlocking()
|
||||
insertTrack.awaitBulk(trackToUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database
|
||||
|
||||
import android.content.Context
|
||||
import androidx.sqlite.db.SupportSQLiteOpenHelper
|
||||
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite
|
||||
import eu.kanade.tachiyomi.data.database.mappers.CategoryTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.mappers.ChapterTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.mappers.HistoryTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.mappers.MangaCategoryTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.mappers.MangaTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.mappers.SearchMetadataTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.mappers.TrackTypeMapping
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.models.SearchMetadata
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.queries.CategoryQueries
|
||||
import eu.kanade.tachiyomi.data.database.queries.ChapterQueries
|
||||
import eu.kanade.tachiyomi.data.database.queries.HistoryQueries
|
||||
import eu.kanade.tachiyomi.data.database.queries.MangaCategoryQueries
|
||||
import eu.kanade.tachiyomi.data.database.queries.MangaQueries
|
||||
import eu.kanade.tachiyomi.data.database.queries.TrackQueries
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
/**
|
||||
* This class provides operations to manage the database through its interfaces.
|
||||
*/
|
||||
open class DatabaseHelper(
|
||||
context: Context,
|
||||
openHelper: SupportSQLiteOpenHelper,
|
||||
) :
|
||||
MangaQueries,
|
||||
ChapterQueries,
|
||||
TrackQueries,
|
||||
CategoryQueries,
|
||||
MangaCategoryQueries,
|
||||
HistoryQueries {
|
||||
|
||||
override val db = DefaultStorIOSQLite.builder()
|
||||
.sqliteOpenHelper(openHelper)
|
||||
.addTypeMapping(Manga::class.java, MangaTypeMapping())
|
||||
.addTypeMapping(Chapter::class.java, ChapterTypeMapping())
|
||||
.addTypeMapping(Track::class.java, TrackTypeMapping())
|
||||
.addTypeMapping(Category::class.java, CategoryTypeMapping())
|
||||
.addTypeMapping(MangaCategory::class.java, MangaCategoryTypeMapping())
|
||||
.addTypeMapping(SearchMetadata::class.java, SearchMetadataTypeMapping())
|
||||
.addTypeMapping(History::class.java, HistoryTypeMapping())
|
||||
.build()
|
||||
|
||||
inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
|
||||
|
||||
inline fun <T> inTransactionReturn(block: () -> T): T = db.inTransactionReturn(block)
|
||||
|
||||
fun lowLevel() = db.lowLevel()
|
||||
}
|
|
@ -1,27 +1,5 @@
|
|||
package eu.kanade.tachiyomi.data.database
|
||||
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
|
||||
inline fun StorIOSQLite.inTransaction(block: () -> Unit) {
|
||||
lowLevel().beginTransaction()
|
||||
try {
|
||||
block()
|
||||
lowLevel().setTransactionSuccessful()
|
||||
} finally {
|
||||
lowLevel().endTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T> StorIOSQLite.inTransactionReturn(block: () -> T): T {
|
||||
lowLevel().beginTransaction()
|
||||
try {
|
||||
val result = block()
|
||||
lowLevel().setTransactionSuccessful()
|
||||
return result
|
||||
} finally {
|
||||
lowLevel().endTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
fun Cursor.getBoolean(index: Int) = getLong(index) > 0
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_FLAGS
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_MANGA_ORDER
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_NAME
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.COL_ORDER
|
||||
import eu.kanade.tachiyomi.data.database.tables.CategoryTable.TABLE
|
||||
|
||||
class CategoryTypeMapping : SQLiteTypeMapping<Category>(
|
||||
CategoryPutResolver(),
|
||||
CategoryGetResolver(),
|
||||
CategoryDeleteResolver(),
|
||||
)
|
||||
|
||||
class CategoryPutResolver : DefaultPutResolver<Category>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: Category) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: Category) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: Category) = ContentValues(4).apply {
|
||||
put(COL_ID, obj.id)
|
||||
put(COL_NAME, obj.name)
|
||||
put(COL_ORDER, obj.order)
|
||||
put(COL_FLAGS, obj.flags)
|
||||
if (obj.mangaSort != null) {
|
||||
put(COL_MANGA_ORDER, obj.mangaSort.toString())
|
||||
} else {
|
||||
val orderString = obj.mangaOrder.joinToString("/")
|
||||
put(COL_MANGA_ORDER, orderString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryGetResolver : DefaultGetResolver<Category>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): Category = CategoryImpl().also {
|
||||
it.id = cursor.getInt(cursor.getColumnIndex(COL_ID))
|
||||
it.name = cursor.getString(cursor.getColumnIndex(COL_NAME))
|
||||
it.order = cursor.getInt(cursor.getColumnIndex(COL_ORDER))
|
||||
it.flags = cursor.getInt(cursor.getColumnIndex(COL_FLAGS))
|
||||
|
||||
val orderString = cursor.getString(cursor.getColumnIndex(COL_MANGA_ORDER))
|
||||
val (sort, order) = Category.mangaOrderFromString(orderString)
|
||||
if (sort != null) it.mangaSort = sort
|
||||
it.mangaOrder = order
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryDeleteResolver : DefaultDeleteResolver<Category>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: Category) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_BOOKMARK
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_CHAPTER_NUMBER
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_DATE_FETCH
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_DATE_UPLOAD
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_LAST_PAGE_READ
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_MANGA_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_NAME
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_PAGES_LEFT
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_READ
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_SCANLATOR
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_SOURCE_ORDER
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.COL_URL
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable.TABLE
|
||||
|
||||
class ChapterTypeMapping : SQLiteTypeMapping<Chapter>(
|
||||
ChapterPutResolver(),
|
||||
ChapterGetResolver(),
|
||||
ChapterDeleteResolver(),
|
||||
)
|
||||
|
||||
class ChapterPutResolver : DefaultPutResolver<Chapter>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: Chapter) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: Chapter) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: Chapter) = ContentValues(11).apply {
|
||||
put(COL_ID, obj.id)
|
||||
put(COL_MANGA_ID, obj.manga_id)
|
||||
put(COL_URL, obj.url)
|
||||
put(COL_NAME, obj.name)
|
||||
put(COL_READ, obj.read)
|
||||
put(COL_SCANLATOR, obj.scanlator)
|
||||
put(COL_BOOKMARK, obj.bookmark)
|
||||
put(COL_DATE_FETCH, obj.date_fetch)
|
||||
put(COL_DATE_UPLOAD, obj.date_upload)
|
||||
put(COL_LAST_PAGE_READ, obj.last_page_read)
|
||||
put(COL_PAGES_LEFT, obj.pages_left)
|
||||
put(COL_CHAPTER_NUMBER, obj.chapter_number)
|
||||
put(COL_SOURCE_ORDER, obj.source_order)
|
||||
}
|
||||
}
|
||||
|
||||
class ChapterGetResolver : DefaultGetResolver<Chapter>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): Chapter = ChapterImpl().apply {
|
||||
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
|
||||
manga_id = cursor.getLong(cursor.getColumnIndex(COL_MANGA_ID))
|
||||
url = cursor.getString(cursor.getColumnIndex(COL_URL))
|
||||
name = cursor.getString(cursor.getColumnIndex(COL_NAME))
|
||||
scanlator = cursor.getString(cursor.getColumnIndex(COL_SCANLATOR))
|
||||
read = cursor.getInt(cursor.getColumnIndex(COL_READ)) == 1
|
||||
bookmark = cursor.getInt(cursor.getColumnIndex(COL_BOOKMARK)) == 1
|
||||
date_fetch = cursor.getLong(cursor.getColumnIndex(COL_DATE_FETCH))
|
||||
date_upload = cursor.getLong(cursor.getColumnIndex(COL_DATE_UPLOAD))
|
||||
last_page_read = cursor.getInt(cursor.getColumnIndex(COL_LAST_PAGE_READ))
|
||||
pages_left = cursor.getInt(cursor.getColumnIndex(COL_PAGES_LEFT))
|
||||
chapter_number = cursor.getFloat(cursor.getColumnIndex(COL_CHAPTER_NUMBER))
|
||||
source_order = cursor.getInt(cursor.getColumnIndex(COL_SOURCE_ORDER))
|
||||
}
|
||||
}
|
||||
|
||||
class ChapterDeleteResolver : DefaultDeleteResolver<Chapter>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: Chapter) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_CHAPTER_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_LAST_READ
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable.COL_TIME_READ
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable.TABLE
|
||||
|
||||
class HistoryTypeMapping : SQLiteTypeMapping<History>(
|
||||
HistoryPutResolver(),
|
||||
HistoryGetResolver(),
|
||||
HistoryDeleteResolver(),
|
||||
)
|
||||
|
||||
open class HistoryPutResolver : DefaultPutResolver<History>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: History) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: History) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: History) = ContentValues(4).apply {
|
||||
put(COL_ID, obj.id)
|
||||
put(COL_CHAPTER_ID, obj.chapter_id)
|
||||
put(COL_LAST_READ, obj.last_read)
|
||||
put(COL_TIME_READ, obj.time_read)
|
||||
}
|
||||
}
|
||||
|
||||
class HistoryGetResolver : DefaultGetResolver<History>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): History = History.mapper(
|
||||
id = cursor.getLong(cursor.getColumnIndex(COL_ID)),
|
||||
chapterId = cursor.getLong(cursor.getColumnIndex(COL_CHAPTER_ID)),
|
||||
lastRead = cursor.getLong(cursor.getColumnIndex(COL_LAST_READ)),
|
||||
timeRead = cursor.getLong(cursor.getColumnIndex(COL_TIME_READ)),
|
||||
)
|
||||
}
|
||||
|
||||
class HistoryDeleteResolver : DefaultDeleteResolver<History>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: History) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable.COL_CATEGORY_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable.COL_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable.COL_MANGA_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable.TABLE
|
||||
|
||||
class MangaCategoryTypeMapping : SQLiteTypeMapping<MangaCategory>(
|
||||
MangaCategoryPutResolver(),
|
||||
MangaCategoryGetResolver(),
|
||||
MangaCategoryDeleteResolver(),
|
||||
)
|
||||
|
||||
class MangaCategoryPutResolver : DefaultPutResolver<MangaCategory>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: MangaCategory) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: MangaCategory) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: MangaCategory) = ContentValues(3).apply {
|
||||
put(COL_ID, obj.id)
|
||||
put(COL_MANGA_ID, obj.manga_id)
|
||||
put(COL_CATEGORY_ID, obj.category_id)
|
||||
}
|
||||
}
|
||||
|
||||
class MangaCategoryGetResolver : DefaultGetResolver<MangaCategory>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): MangaCategory = MangaCategory().apply {
|
||||
id = cursor.getLong(cursor.getColumnIndex(COL_ID))
|
||||
manga_id = cursor.getLong(cursor.getColumnIndex(COL_MANGA_ID))
|
||||
category_id = cursor.getInt(cursor.getColumnIndex(COL_CATEGORY_ID))
|
||||
}
|
||||
}
|
||||
|
||||
class MangaCategoryDeleteResolver : DefaultDeleteResolver<MangaCategory>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: MangaCategory) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.getBoolean
|
||||
import eu.kanade.tachiyomi.data.database.models.mapper
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_ARTIST
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_AUTHOR
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_CHAPTER_FLAGS
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_COVER_LAST_MODIFIED
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_DATE_ADDED
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_DESCRIPTION
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_FAVORITE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_FILTERED_SCANLATORS
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_GENRE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_HIDE_TITLE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_INITIALIZED
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_LAST_UPDATE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_SOURCE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_STATUS
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_THUMBNAIL_URL
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_TITLE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_UPDATE_STRATEGY
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_URL
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_VIEWER
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.TABLE
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import yokai.data.updateStrategyAdapter
|
||||
|
||||
class MangaTypeMapping : SQLiteTypeMapping<Manga>(
|
||||
MangaPutResolver(),
|
||||
MangaGetResolver(),
|
||||
MangaDeleteResolver(),
|
||||
)
|
||||
|
||||
class MangaPutResolver : DefaultPutResolver<Manga>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: Manga) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: Manga) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: Manga) = ContentValues(15).apply {
|
||||
put(COL_ID, obj.id)
|
||||
put(COL_SOURCE, obj.source)
|
||||
put(COL_URL, obj.url)
|
||||
put(COL_ARTIST, obj.originalArtist)
|
||||
put(COL_AUTHOR, obj.originalAuthor)
|
||||
put(COL_DESCRIPTION, obj.originalDescription)
|
||||
put(COL_GENRE, obj.originalGenre)
|
||||
put(COL_TITLE, obj.ogTitle)
|
||||
put(COL_STATUS, obj.ogStatus)
|
||||
put(COL_THUMBNAIL_URL, obj.thumbnail_url)
|
||||
put(COL_FAVORITE, obj.favorite)
|
||||
put(COL_LAST_UPDATE, obj.last_update)
|
||||
put(COL_INITIALIZED, obj.initialized)
|
||||
put(COL_VIEWER, obj.viewer_flags)
|
||||
put(COL_HIDE_TITLE, obj.hide_title)
|
||||
put(COL_CHAPTER_FLAGS, obj.chapter_flags)
|
||||
put(COL_DATE_ADDED, obj.date_added)
|
||||
put(COL_FILTERED_SCANLATORS, obj.filtered_scanlators)
|
||||
put(COL_UPDATE_STRATEGY, obj.update_strategy.let(updateStrategyAdapter::encode))
|
||||
put(COL_COVER_LAST_MODIFIED, obj.cover_last_modified)
|
||||
}
|
||||
}
|
||||
|
||||
interface BaseMangaGetResolver {
|
||||
@SuppressLint("Range")
|
||||
fun mapBaseFromCursor(cursor: Cursor) = Manga.mapper(
|
||||
id = cursor.getLong(cursor.getColumnIndex(COL_ID)),
|
||||
source = cursor.getLong(cursor.getColumnIndex(COL_SOURCE)),
|
||||
url = cursor.getString(cursor.getColumnIndex(COL_URL)),
|
||||
artist = cursor.getString(cursor.getColumnIndex(COL_ARTIST)),
|
||||
author = cursor.getString(cursor.getColumnIndex(COL_AUTHOR)),
|
||||
description = cursor.getString(cursor.getColumnIndex(COL_DESCRIPTION)),
|
||||
genre = cursor.getString(cursor.getColumnIndex(COL_GENRE)),
|
||||
title = cursor.getString(cursor.getColumnIndex(COL_TITLE)),
|
||||
status = cursor.getLong(cursor.getColumnIndex(COL_STATUS)),
|
||||
thumbnailUrl = cursor.getString(cursor.getColumnIndex(COL_THUMBNAIL_URL)),
|
||||
favorite = cursor.getBoolean(cursor.getColumnIndex(COL_FAVORITE)),
|
||||
lastUpdate = cursor.getLong(cursor.getColumnIndex(COL_LAST_UPDATE)),
|
||||
initialized = cursor.getBoolean(cursor.getColumnIndex(COL_INITIALIZED)),
|
||||
viewerFlags = cursor.getLong(cursor.getColumnIndex(COL_VIEWER)),
|
||||
chapterFlags = cursor.getLong(cursor.getColumnIndex(COL_CHAPTER_FLAGS)),
|
||||
hideTitle = cursor.getBoolean(cursor.getColumnIndex(COL_HIDE_TITLE)),
|
||||
dateAdded = cursor.getLong(cursor.getColumnIndex(COL_DATE_ADDED)),
|
||||
filteredScanlators = cursor.getString(cursor.getColumnIndex(COL_FILTERED_SCANLATORS)),
|
||||
updateStrategy = cursor.getLong(cursor.getColumnIndex(COL_UPDATE_STRATEGY)),
|
||||
coverLastModified = cursor.getLong(cursor.getColumnIndex(COL_COVER_LAST_MODIFIED)),
|
||||
)
|
||||
}
|
||||
|
||||
open class MangaGetResolver : DefaultGetResolver<Manga>(), BaseMangaGetResolver {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): Manga {
|
||||
return mapBaseFromCursor(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
class MangaDeleteResolver : DefaultDeleteResolver<Manga>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: Manga) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.models.SearchMetadata
|
||||
import eu.kanade.tachiyomi.data.database.tables.SearchMetadataTable.COL_EXTRA
|
||||
import eu.kanade.tachiyomi.data.database.tables.SearchMetadataTable.COL_EXTRA_VERSION
|
||||
import eu.kanade.tachiyomi.data.database.tables.SearchMetadataTable.COL_INDEXED_EXTRA
|
||||
import eu.kanade.tachiyomi.data.database.tables.SearchMetadataTable.COL_MANGA_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.SearchMetadataTable.COL_UPLOADER
|
||||
import eu.kanade.tachiyomi.data.database.tables.SearchMetadataTable.TABLE
|
||||
|
||||
class SearchMetadataTypeMapping : SQLiteTypeMapping<SearchMetadata>(
|
||||
SearchMetadataPutResolver(),
|
||||
SearchMetadataGetResolver(),
|
||||
SearchMetadataDeleteResolver(),
|
||||
)
|
||||
|
||||
class SearchMetadataPutResolver : DefaultPutResolver<SearchMetadata>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: SearchMetadata) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: SearchMetadata) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_MANGA_ID = ?")
|
||||
.whereArgs(obj.mangaId)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: SearchMetadata) = ContentValues(5).apply {
|
||||
put(COL_MANGA_ID, obj.mangaId)
|
||||
put(COL_UPLOADER, obj.uploader)
|
||||
put(COL_EXTRA, obj.extra)
|
||||
put(COL_INDEXED_EXTRA, obj.indexedExtra)
|
||||
put(COL_EXTRA_VERSION, obj.extraVersion)
|
||||
}
|
||||
}
|
||||
|
||||
class SearchMetadataGetResolver : DefaultGetResolver<SearchMetadata>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): SearchMetadata = SearchMetadata(
|
||||
mangaId = cursor.getLong(cursor.getColumnIndex(COL_MANGA_ID)),
|
||||
uploader = cursor.getString(cursor.getColumnIndex(COL_UPLOADER)),
|
||||
extra = cursor.getString(cursor.getColumnIndex(COL_EXTRA)),
|
||||
indexedExtra = cursor.getString(cursor.getColumnIndex(COL_INDEXED_EXTRA)),
|
||||
extraVersion = cursor.getInt(cursor.getColumnIndex(COL_EXTRA_VERSION)),
|
||||
)
|
||||
}
|
||||
|
||||
class SearchMetadataDeleteResolver : DefaultDeleteResolver<SearchMetadata>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: SearchMetadata) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_MANGA_ID = ?")
|
||||
.whereArgs(obj.mangaId)
|
||||
.build()
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.mappers
|
||||
|
||||
import android.database.Cursor
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||
import com.pushtorefresh.storio.sqlite.operations.delete.DefaultDeleteResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.DefaultPutResolver
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.InsertQuery
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_FINISH_DATE
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_LAST_CHAPTER_READ
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_LIBRARY_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_MANGA_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_MEDIA_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_SCORE
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_START_DATE
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_STATUS
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_SYNC_ID
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_TITLE
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_TOTAL_CHAPTERS
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.COL_TRACKING_URL
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable.TABLE
|
||||
|
||||
class TrackTypeMapping : SQLiteTypeMapping<Track>(
|
||||
TrackPutResolver(),
|
||||
TrackGetResolver(),
|
||||
TrackDeleteResolver(),
|
||||
)
|
||||
|
||||
class TrackPutResolver : DefaultPutResolver<Track>() {
|
||||
|
||||
override fun mapToInsertQuery(obj: Track) = InsertQuery.builder()
|
||||
.table(TABLE)
|
||||
.build()
|
||||
|
||||
override fun mapToUpdateQuery(obj: Track) = UpdateQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
|
||||
override fun mapToContentValues(obj: Track) = contentValuesOf(
|
||||
COL_ID to obj.id,
|
||||
COL_MANGA_ID to obj.manga_id,
|
||||
COL_SYNC_ID to obj.sync_id,
|
||||
COL_MEDIA_ID to obj.media_id,
|
||||
COL_LIBRARY_ID to obj.library_id,
|
||||
COL_TITLE to obj.title,
|
||||
COL_LAST_CHAPTER_READ to obj.last_chapter_read,
|
||||
COL_TOTAL_CHAPTERS to obj.total_chapters,
|
||||
COL_STATUS to obj.status,
|
||||
COL_TRACKING_URL to obj.tracking_url,
|
||||
COL_SCORE to obj.score,
|
||||
COL_START_DATE to obj.started_reading_date,
|
||||
COL_FINISH_DATE to obj.finished_reading_date,
|
||||
)
|
||||
}
|
||||
|
||||
class TrackGetResolver : DefaultGetResolver<Track>() {
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): Track = TrackImpl().apply {
|
||||
id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_ID))
|
||||
manga_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_MANGA_ID))
|
||||
sync_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_SYNC_ID))
|
||||
media_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_MEDIA_ID))
|
||||
library_id = cursor.getLong(cursor.getColumnIndexOrThrow(COL_LIBRARY_ID))
|
||||
title = cursor.getString(cursor.getColumnIndexOrThrow(COL_TITLE))
|
||||
last_chapter_read = cursor.getFloat(cursor.getColumnIndexOrThrow(COL_LAST_CHAPTER_READ))
|
||||
total_chapters = cursor.getLong(cursor.getColumnIndexOrThrow(COL_TOTAL_CHAPTERS))
|
||||
status = cursor.getInt(cursor.getColumnIndexOrThrow(COL_STATUS))
|
||||
score = cursor.getFloat(cursor.getColumnIndexOrThrow(COL_SCORE))
|
||||
tracking_url = cursor.getString(cursor.getColumnIndexOrThrow(COL_TRACKING_URL))
|
||||
started_reading_date = cursor.getLong(cursor.getColumnIndexOrThrow(COL_START_DATE))
|
||||
finished_reading_date = cursor.getLong(cursor.getColumnIndexOrThrow(COL_FINISH_DATE))
|
||||
}
|
||||
}
|
||||
|
||||
class TrackDeleteResolver : DefaultDeleteResolver<Track>() {
|
||||
|
||||
override fun mapToDeleteQuery(obj: Track) = DeleteQuery.builder()
|
||||
.table(TABLE)
|
||||
.where("$COL_ID = ?")
|
||||
.whereArgs(obj.id)
|
||||
.build()
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.queries.RawQuery
|
||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
interface CategoryQueries : DbProvider {
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun getCategoriesForManga(manga: Manga) = db.get()
|
||||
.listOfObjects(Category::class.java)
|
||||
.withQuery(
|
||||
RawQuery.builder()
|
||||
.query(getCategoriesForMangaQuery())
|
||||
.args(manga.id)
|
||||
.build(),
|
||||
)
|
||||
.prepare()
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.queries.Query
|
||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
interface ChapterQueries : DbProvider {
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun getChapters(manga: Manga) = db.get()
|
||||
.listOfObjects(Chapter::class.java)
|
||||
.withQuery(
|
||||
Query.builder()
|
||||
.table(ChapterTable.TABLE)
|
||||
.where("${ChapterTable.COL_MANGA_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build(),
|
||||
)
|
||||
.prepare()
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun insertChapters(chapters: List<Chapter>) = db.put().objects(chapters).prepare()
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.queries.RawQuery
|
||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.HistoryUpsertResolver
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
||||
|
||||
interface HistoryQueries : DbProvider {
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun getHistoryByMangaId(mangaId: Long) = db.get()
|
||||
.listOfObjects(History::class.java)
|
||||
.withQuery(
|
||||
RawQuery.builder()
|
||||
.query(getHistoryByMangaId())
|
||||
.args(mangaId)
|
||||
.observesTables(HistoryTable.TABLE)
|
||||
.build(),
|
||||
)
|
||||
.prepare()
|
||||
|
||||
/**
|
||||
* Updates the history last read.
|
||||
* Inserts history object if not yet in database
|
||||
* @param historyList history object list
|
||||
*/
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun upsertHistoryLastRead(historyList: List<History>) = db.inTransactionReturn {
|
||||
db.put()
|
||||
.objects(historyList)
|
||||
.withPutResolver(HistoryUpsertResolver())
|
||||
.prepare()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import com.pushtorefresh.storio.Queries
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.inTransaction
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
interface MangaCategoryQueries : DbProvider {
|
||||
|
||||
private fun insertMangasCategories(mangasCategories: List<MangaCategory>) = db.put().objects(mangasCategories).prepare()
|
||||
|
||||
private fun deleteOldMangasCategories(mangas: List<Manga>) = db.delete()
|
||||
.byQuery(
|
||||
DeleteQuery.builder()
|
||||
.table(MangaCategoryTable.TABLE)
|
||||
.where("${MangaCategoryTable.COL_MANGA_ID} IN (${Queries.placeholders(mangas.size)})")
|
||||
.whereArgs(*mangas.map { it.id }.toTypedArray())
|
||||
.build(),
|
||||
)
|
||||
.prepare()
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun setMangaCategories(mangasCategories: List<MangaCategory>, mangas: List<Manga>) {
|
||||
db.inTransaction {
|
||||
deleteOldMangasCategories(mangas).executeAsBlocking()
|
||||
insertMangasCategories(mangasCategories).executeAsBlocking()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.queries.Query
|
||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaDateAddedPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver
|
||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaTitlePutResolver
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
interface MangaQueries : DbProvider {
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun getManga(id: Long) = db.get()
|
||||
.`object`(Manga::class.java)
|
||||
.withQuery(
|
||||
Query.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(id)
|
||||
.build(),
|
||||
)
|
||||
.prepare()
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: used by StorIO's inTransaction
|
||||
fun updateMangaFavorite(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaFavoritePutResolver())
|
||||
.prepare()
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: used by StorIO's inTransaction
|
||||
fun updateMangaAdded(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaDateAddedPutResolver())
|
||||
.prepare()
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: used by StorIO's inTransaction
|
||||
fun updateMangaTitle(manga: Manga) = db.put()
|
||||
.`object`(manga)
|
||||
.withPutResolver(MangaTitlePutResolver())
|
||||
.prepare()
|
||||
|
||||
}
|
|
@ -1,294 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import eu.kanade.tachiyomi.ui.recents.RecentsPresenter
|
||||
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.HistoryTable as History
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable as MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable as Manga
|
||||
|
||||
// TODO: Migrate to SQLDelight
|
||||
/**
|
||||
* Query to get the recent chapters of manga from the library up to a date.
|
||||
*/
|
||||
fun getRecentsQuery(search: String, offset: Int, isResuming: Boolean) =
|
||||
"""
|
||||
SELECT
|
||||
M.url AS mangaUrl,
|
||||
M.*,
|
||||
C.*
|
||||
FROM mangas AS M
|
||||
JOIN chapters AS C
|
||||
ON M._id = C.manga_id
|
||||
LEFT JOIN scanlators_view AS S
|
||||
ON C.manga_id = S.manga_id
|
||||
AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '/<INVALID>/')
|
||||
WHERE M.favorite = 1
|
||||
AND C.date_fetch > M.date_added
|
||||
AND lower(M.title) LIKE '%$search%'
|
||||
AND S.name IS NULL
|
||||
ORDER BY C.date_fetch DESC
|
||||
${limitAndOffset(true, isResuming, offset)}
|
||||
"""
|
||||
|
||||
fun limitAndOffset(endless: Boolean, isResuming: Boolean, offset: Int): String {
|
||||
return when {
|
||||
isResuming && endless && offset > 0 -> "LIMIT $offset"
|
||||
endless -> "LIMIT ${RecentsPresenter.ENDLESS_LIMIT}\nOFFSET $offset"
|
||||
else -> "LIMIT ${RecentsPresenter.SHORT_LIMIT}"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Migrate to SQLDelight
|
||||
/**
|
||||
* Query to get the recently read chapters of manga from the library up to a date.
|
||||
* The max_last_read table contains the most recent chapters grouped by manga
|
||||
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
||||
* and are read after the given time period
|
||||
*/
|
||||
fun getRecentHistoryUngrouped(
|
||||
search: String = "",
|
||||
offset: Int = 0,
|
||||
isResuming: Boolean,
|
||||
) =
|
||||
"""
|
||||
SELECT
|
||||
M.url AS mangaUrl,
|
||||
M.*,
|
||||
C.*,
|
||||
H.*
|
||||
FROM mangas AS M
|
||||
JOIN chapters AS C
|
||||
ON M._id = C.manga_id
|
||||
JOIN history AS H
|
||||
ON C._id = H.history_chapter_id
|
||||
AND H.history_last_read > 0
|
||||
LEFT JOIN scanlators_view AS S
|
||||
ON C.manga_id = S.manga_id
|
||||
AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '/<INVALID>/')
|
||||
WHERE lower(M.title) LIKE '%$search%'
|
||||
AND S.name IS NULL
|
||||
ORDER BY H.history_last_read DESC
|
||||
${limitAndOffset(true, isResuming, offset)}
|
||||
"""
|
||||
|
||||
// TODO: Migrate to SQLDelight
|
||||
/**
|
||||
* Query to get the recently read chapters of manga from the library up to a date.
|
||||
* The max_last_read table contains the most recent chapters grouped by manga
|
||||
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
||||
* and are read after the given time period
|
||||
*/
|
||||
fun getRecentMangasLimitQuery(
|
||||
search: String = "",
|
||||
offset: Int = 0,
|
||||
isResuming: Boolean,
|
||||
) =
|
||||
"""
|
||||
SELECT
|
||||
M.url AS mangaUrl,
|
||||
M.*,
|
||||
C.*,
|
||||
H.*
|
||||
FROM mangas AS M
|
||||
JOIN chapters AS C
|
||||
ON M._id = C.manga_id
|
||||
JOIN history AS H
|
||||
ON C._id = H.history_chapter_id
|
||||
JOIN (
|
||||
SELECT
|
||||
C2.manga_id AS manga_id,
|
||||
C2._id AS history_chapter_id,
|
||||
MAX(H2.history_last_read) AS history_last_read
|
||||
FROM chapters AS C2 JOIN history AS H2
|
||||
ON C2._id = H2.history_chapter_id
|
||||
GROUP BY C2.manga_id
|
||||
) AS max_last_read
|
||||
ON C.manga_id = max_last_read.manga_id
|
||||
AND max_last_read.history_chapter_id = H.history_chapter_id
|
||||
AND max_last_read.history_last_read > 0
|
||||
LEFT JOIN scanlators_view AS S
|
||||
ON C.manga_id = S.manga_id
|
||||
AND ifnull(C.scanlator, 'N/A') = ifnull(S.name, '/<INVALID>/')
|
||||
WHERE lower(M.title) LIKE '%$search%'
|
||||
AND S.name IS NULL
|
||||
ORDER BY max_last_read.history_last_read DESC
|
||||
${limitAndOffset(true, isResuming, offset)}
|
||||
"""
|
||||
|
||||
/**
|
||||
* Query to get the read chapters of manga from the library during the period.
|
||||
* The max_last_read table contains the most recent chapters grouped by manga
|
||||
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
||||
* and are read after the given time period
|
||||
*/
|
||||
fun getHistoryPerPeriodQuery(startDate: Long, endDate: Long) =
|
||||
"""
|
||||
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
|
||||
FROM ${Manga.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||
JOIN ${History.TABLE}
|
||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||
AND ${History.TABLE}.${History.COL_LAST_READ} >= $startDate
|
||||
AND ${History.TABLE}.${History.COL_LAST_READ} <= $endDate
|
||||
ORDER BY ${History.TABLE}.${History.COL_LAST_READ} DESC
|
||||
"""
|
||||
|
||||
/**
|
||||
* Query to get the recently read manga that has more chapters to read
|
||||
* The first from checks that there's an unread chapter
|
||||
* The max_last_read table contains the most recent chapters grouped by manga
|
||||
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
|
||||
* and are read after the given time period
|
||||
* The Second Union/Select gets recents chapters
|
||||
* Final Union gets newly added manga
|
||||
*/
|
||||
fun getAllRecentsType(
|
||||
search: String = "",
|
||||
includeRead: Boolean,
|
||||
endless: Boolean,
|
||||
offset: Int = 0,
|
||||
isResuming: Boolean,
|
||||
) = """
|
||||
SELECT * FROM
|
||||
(SELECT mangas.url as mangaUrl, mangas.*, chapters.*, history.*
|
||||
FROM (
|
||||
SELECT mangas.*
|
||||
FROM mangas
|
||||
LEFT JOIN (
|
||||
SELECT manga_id, COUNT(*) AS unread
|
||||
FROM chapters
|
||||
WHERE read = 0
|
||||
GROUP BY manga_id
|
||||
) AS C
|
||||
ON _id = C.manga_id
|
||||
${if (includeRead) "" else "WHERE C.unread > 0"}
|
||||
GROUP BY _id
|
||||
ORDER BY title
|
||||
) AS mangas
|
||||
JOIN chapters
|
||||
ON mangas._id = chapters.manga_id
|
||||
JOIN history
|
||||
ON chapters._id = history.history_chapter_id
|
||||
JOIN (
|
||||
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID}, MAX(${History.TABLE}.${History.COL_LAST_READ}) as ${History.COL_LAST_READ}
|
||||
FROM ${Chapter.TABLE} JOIN ${History.TABLE}
|
||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
|
||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
||||
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||
AND max_last_read.${History.COL_LAST_READ} > 0
|
||||
AND lower(${Manga.COL_TITLE}) LIKE '%$search%')
|
||||
UNION
|
||||
SELECT * FROM
|
||||
(SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*,
|
||||
Null as history_id,
|
||||
Null as history_chapter_id,
|
||||
chapters.date_fetch as history_last_read,
|
||||
Null as history_time_read
|
||||
FROM ${Manga.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||
JOIN (
|
||||
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID},MAX(${Chapter.TABLE}.${Chapter.COL_DATE_UPLOAD})
|
||||
FROM ${Chapter.TABLE} JOIN ${Manga.TABLE}
|
||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||
WHERE ${Chapter.COL_READ} = 0
|
||||
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS newest_chapter
|
||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = newest_chapter.${Chapter.COL_MANGA_ID}
|
||||
WHERE ${Manga.COL_FAVORITE} = 1
|
||||
AND newest_chapter.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
||||
AND ${Chapter.COL_DATE_FETCH} > ${Manga.COL_DATE_ADDED}
|
||||
AND lower(${Manga.COL_TITLE}) LIKE '%$search%')
|
||||
UNION
|
||||
SELECT * FROM
|
||||
(SELECT mangas.url as mangaUrl,
|
||||
mangas.*,
|
||||
Null as _id,
|
||||
Null as manga_id,
|
||||
Null as url,
|
||||
Null as name,
|
||||
Null as read,
|
||||
Null as scanlator,
|
||||
Null as bookmark,
|
||||
Null as date_fetch,
|
||||
Null as date_upload,
|
||||
Null as last_page_read,
|
||||
Null as pages_left,
|
||||
Null as chapter_number,
|
||||
Null as source_order,
|
||||
Null as history_id,
|
||||
Null as history_chapter_id,
|
||||
${Manga.TABLE}.${Manga.COL_DATE_ADDED} as history_last_read,
|
||||
Null as history_time_read
|
||||
FROM mangas
|
||||
WHERE ${Manga.COL_FAVORITE} = 1
|
||||
AND lower(${Manga.COL_TITLE}) LIKE '%$search%')
|
||||
ORDER BY history_last_read DESC
|
||||
${limitAndOffset(endless, isResuming, offset)}
|
||||
"""
|
||||
|
||||
fun getHistoryByMangaId() =
|
||||
"""
|
||||
SELECT ${History.TABLE}.*
|
||||
FROM ${History.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
||||
WHERE ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ? AND ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
||||
"""
|
||||
|
||||
fun getHistoryByChapterUrl() =
|
||||
"""
|
||||
SELECT ${History.TABLE}.*
|
||||
FROM ${History.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
||||
WHERE ${Chapter.TABLE}.${Chapter.COL_URL} = ? AND ${History.TABLE}.${History.COL_CHAPTER_ID} = ${Chapter.TABLE}.${Chapter.COL_ID}
|
||||
"""
|
||||
|
||||
fun getLastReadMangaQuery() =
|
||||
"""
|
||||
SELECT ${Manga.TABLE}.*, MAX(${History.TABLE}.${History.COL_LAST_READ}) AS max
|
||||
FROM ${Manga.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||
JOIN ${History.TABLE}
|
||||
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||
WHERE ${Manga.TABLE}.${Manga.COL_FAVORITE} = 1
|
||||
GROUP BY ${Manga.TABLE}.${Manga.COL_ID}
|
||||
ORDER BY max DESC
|
||||
"""
|
||||
|
||||
fun getLastFetchedMangaQuery() =
|
||||
"""
|
||||
SELECT ${Manga.TABLE}.*, MAX(${Chapter.TABLE}.${Chapter.COL_DATE_FETCH}) AS max
|
||||
FROM ${Manga.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||
WHERE ${Manga.TABLE}.${Manga.COL_FAVORITE} = 1
|
||||
GROUP BY ${Manga.TABLE}.${Manga.COL_ID}
|
||||
ORDER BY max DESC
|
||||
"""
|
||||
|
||||
fun getTotalChapterMangaQuery() =
|
||||
"""
|
||||
SELECT ${Manga.TABLE}.*
|
||||
FROM ${Manga.TABLE}
|
||||
JOIN ${Chapter.TABLE}
|
||||
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
|
||||
GROUP BY ${Manga.TABLE}.${Manga.COL_ID}
|
||||
ORDER by COUNT(*)
|
||||
"""
|
||||
|
||||
/**
|
||||
* Query to get the categories for a manga.
|
||||
*/
|
||||
fun getCategoriesForMangaQuery() =
|
||||
"""
|
||||
SELECT ${Category.TABLE}.* FROM ${Category.TABLE}
|
||||
JOIN ${MangaCategory.TABLE} ON ${Category.TABLE}.${Category.COL_ID} =
|
||||
${MangaCategory.TABLE}.${MangaCategory.COL_CATEGORY_ID}
|
||||
WHERE ${MangaCategory.COL_MANGA_ID} = ?
|
||||
"""
|
||||
|
|
@ -1,26 +1,7 @@
|
|||
package eu.kanade.tachiyomi.data.database.queries
|
||||
|
||||
import com.pushtorefresh.storio.sqlite.queries.Query
|
||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.tables.TrackTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
interface TrackQueries : DbProvider {
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun getTracks(manga: Manga) = db.get()
|
||||
.listOfObjects(Track::class.java)
|
||||
.withQuery(
|
||||
Query.builder()
|
||||
.table(TrackTable.TABLE)
|
||||
.where("${TrackTable.COL_MANGA_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build(),
|
||||
)
|
||||
.prepare()
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun insertTracks(tracks: List<Track>) = db.put().objects(tracks).prepare()
|
||||
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||
|
||||
class ChapterBackupPutResolver : PutResolver<Chapter>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, chapter: Chapter) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(chapter)
|
||||
val contentValues = mapToContentValues(chapter)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(chapter: Chapter) = UpdateQuery.builder()
|
||||
.table(ChapterTable.TABLE)
|
||||
.where("${ChapterTable.COL_URL} = ?")
|
||||
.whereArgs(chapter.url)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(chapter: Chapter) = ContentValues(3).apply {
|
||||
put(ChapterTable.COL_READ, chapter.read)
|
||||
put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
|
||||
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||
|
||||
class ChapterKnownBackupPutResolver : PutResolver<Chapter>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, chapter: Chapter) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(chapter)
|
||||
val contentValues = mapToContentValues(chapter)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(chapter: Chapter) = UpdateQuery.builder()
|
||||
.table(ChapterTable.TABLE)
|
||||
.where("${ChapterTable.COL_ID} = ?")
|
||||
.whereArgs(chapter.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(chapter: Chapter) =
|
||||
contentValuesOf(
|
||||
ChapterTable.COL_READ to chapter.read,
|
||||
ChapterTable.COL_BOOKMARK to chapter.bookmark,
|
||||
ChapterTable.COL_LAST_PAGE_READ to chapter.last_page_read,
|
||||
)
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||
|
||||
class ChapterSourceOrderPutResolver : PutResolver<Chapter>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, chapter: Chapter) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(chapter)
|
||||
val contentValues = mapToContentValues(chapter)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(chapter: Chapter) = UpdateQuery.builder()
|
||||
.table(ChapterTable.TABLE)
|
||||
.where("${ChapterTable.COL_URL} = ? AND ${ChapterTable.COL_MANGA_ID} = ?")
|
||||
.whereArgs(chapter.url, chapter.manga_id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(chapter: Chapter) = ContentValues(1).apply {
|
||||
put(ChapterTable.COL_SOURCE_ORDER, chapter.source_order)
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.Query
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.mappers.HistoryPutResolver
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
||||
|
||||
class HistoryUpsertResolver : HistoryPutResolver() {
|
||||
|
||||
/**
|
||||
* Updates last_read time of chapter
|
||||
*/
|
||||
override fun performPut(db: StorIOSQLite, history: History): PutResult {
|
||||
val updateQuery = mapToUpdateQuery(history)
|
||||
|
||||
val cursor = db.lowLevel().query(
|
||||
Query.builder()
|
||||
.table(updateQuery.table())
|
||||
.where(updateQuery.where())
|
||||
.whereArgs(updateQuery.whereArgs())
|
||||
.build(),
|
||||
)
|
||||
|
||||
return cursor.use { putCursor ->
|
||||
if (putCursor.count == 0) {
|
||||
val insertQuery = mapToInsertQuery(history)
|
||||
val insertedId = db.lowLevel().insert(insertQuery, mapToContentValues(history))
|
||||
PutResult.newInsertResult(insertedId, insertQuery.table())
|
||||
} else {
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, mapToUpdateContentValues(history))
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun mapToUpdateQuery(obj: History) = UpdateQuery.builder()
|
||||
.table(HistoryTable.TABLE)
|
||||
.where("${HistoryTable.COL_CHAPTER_ID} = ?")
|
||||
.whereArgs(obj.chapter_id)
|
||||
.build()
|
||||
|
||||
private fun mapToUpdateContentValues(history: History) =
|
||||
contentValuesOf(
|
||||
HistoryTable.COL_LAST_READ to history.last_read,
|
||||
HistoryTable.COL_TIME_READ to history.time_read,
|
||||
)
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.mappers.ChapterGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.mappers.MangaGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaChapter
|
||||
|
||||
class MangaChapterGetResolver : DefaultGetResolver<MangaChapter>() {
|
||||
|
||||
companion object {
|
||||
val INSTANCE = MangaChapterGetResolver()
|
||||
}
|
||||
|
||||
private val mangaGetResolver = MangaGetResolver()
|
||||
|
||||
private val chapterGetResolver = ChapterGetResolver()
|
||||
|
||||
override fun mapFromCursor(cursor: Cursor): MangaChapter {
|
||||
val manga = mangaGetResolver.mapFromCursor(cursor)
|
||||
val chapter = chapterGetResolver.mapFromCursor(cursor)
|
||||
manga.id = chapter.manga_id
|
||||
manga.url = cursor.getString(cursor.getColumnIndex("mangaUrl"))
|
||||
|
||||
return MangaChapter(manga, chapter)
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.database.Cursor
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.DefaultGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.mappers.ChapterGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.mappers.HistoryGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.mappers.MangaGetResolver
|
||||
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
|
||||
import eu.kanade.tachiyomi.data.database.models.HistoryImpl
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
||||
|
||||
class MangaChapterHistoryGetResolver : DefaultGetResolver<MangaChapterHistory>() {
|
||||
companion object {
|
||||
val INSTANCE = MangaChapterHistoryGetResolver()
|
||||
}
|
||||
|
||||
/**
|
||||
* Manga get resolver
|
||||
*/
|
||||
private val mangaGetResolver = MangaGetResolver()
|
||||
|
||||
/**
|
||||
* Chapter get resolver
|
||||
*/
|
||||
private val chapterResolver = ChapterGetResolver()
|
||||
|
||||
/**
|
||||
* History get resolver
|
||||
*/
|
||||
private val historyGetResolver = HistoryGetResolver()
|
||||
|
||||
/**
|
||||
* Map correct objects from cursor result
|
||||
*/
|
||||
override fun mapFromCursor(cursor: Cursor): MangaChapterHistory {
|
||||
// Get manga object
|
||||
val manga = mangaGetResolver.mapFromCursor(cursor)
|
||||
|
||||
// Get chapter object
|
||||
val chapter =
|
||||
if (!cursor.isNull(cursor.getColumnIndex(ChapterTable.COL_MANGA_ID))) {
|
||||
chapterResolver.mapFromCursor(cursor)
|
||||
} else {
|
||||
ChapterImpl()
|
||||
}
|
||||
|
||||
// Get history object
|
||||
val history =
|
||||
if (!cursor.isNull(cursor.getColumnIndex(HistoryTable.COL_ID))) {
|
||||
historyGetResolver.mapFromCursor(cursor)
|
||||
} else {
|
||||
HistoryImpl().apply {
|
||||
last_read = try {
|
||||
cursor.getLong(cursor.getColumnIndex(HistoryTable.COL_LAST_READ))
|
||||
} catch (e: Exception) {
|
||||
0L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make certain column conflicts are dealt with
|
||||
if (chapter.id != null) {
|
||||
manga.id = chapter.manga_id
|
||||
manga.url = cursor.getString(cursor.getColumnIndex("mangaUrl"))
|
||||
}
|
||||
if (history.id != null) chapter.id = history.chapter_id
|
||||
|
||||
// Return result
|
||||
return MangaChapterHistory(manga, chapter, history)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
class MangaDateAddedPutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||
put(MangaTable.COL_DATE_ADDED, manga.date_added)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
class MangaFavoritePutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||
put(MangaTable.COL_FAVORITE, manga.favorite)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
class MangaFilteredScanlatorsPutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = contentValuesOf(
|
||||
MangaTable.COL_FILTERED_SCANLATORS to manga.filtered_scanlators,
|
||||
)
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import androidx.core.content.contentValuesOf
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
class MangaFlagsPutResolver(private val colName: String, private val fieldGetter: KProperty1<Manga, Int>, private val updateAll: Boolean = false) : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga): UpdateQuery {
|
||||
val builder = UpdateQuery.builder()
|
||||
|
||||
return if (updateAll) {
|
||||
builder
|
||||
.table(MangaTable.TABLE)
|
||||
.build()
|
||||
} else {
|
||||
builder
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
fun mapToContentValues(manga: Manga) =
|
||||
contentValuesOf(
|
||||
colName to fieldGetter.get(manga),
|
||||
)
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
class MangaInfoPutResolver() : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||
put(MangaTable.COL_TITLE, manga.originalTitle)
|
||||
put(MangaTable.COL_GENRE, manga.originalGenre)
|
||||
put(MangaTable.COL_AUTHOR, manga.originalAuthor)
|
||||
put(MangaTable.COL_ARTIST, manga.originalArtist)
|
||||
put(MangaTable.COL_DESCRIPTION, manga.originalDescription)
|
||||
put(MangaTable.COL_STATUS, manga.originalStatus)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
class MangaLastUpdatedPutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||
put(MangaTable.COL_LAST_UPDATE, manga.last_update)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package eu.kanade.tachiyomi.data.database.resolvers
|
||||
|
||||
import android.content.ContentValues
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
||||
class MangaTitlePutResolver : PutResolver<Manga>() {
|
||||
|
||||
override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
|
||||
val updateQuery = mapToUpdateQuery(manga)
|
||||
val contentValues = mapToContentValues(manga)
|
||||
|
||||
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
|
||||
PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
|
||||
}
|
||||
|
||||
fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
|
||||
.table(MangaTable.TABLE)
|
||||
.where("${MangaTable.COL_ID} = ?")
|
||||
.whereArgs(manga.id)
|
||||
.build()
|
||||
|
||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||
put(MangaTable.COL_TITLE, manga.title)
|
||||
}
|
||||
}
|
|
@ -119,7 +119,6 @@ class DownloadProvider(private val context: Context) {
|
|||
*/
|
||||
/*
|
||||
fun renameChapters() {
|
||||
val db by injectLazy<DatabaseHelper>()
|
||||
val sourceManager by injectLazy<SourceManager>()
|
||||
val mangas = db.getFavoriteMangas().executeAsBlocking()
|
||||
mangas.forEach sfor@{ manga ->
|
||||
|
|
|
@ -7,7 +7,6 @@ import co.touchlab.kermit.Logger
|
|||
import com.hippo.unifile.UniFile
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
||||
|
@ -83,7 +82,6 @@ class Downloader(
|
|||
private val downloadPreferences: DownloadPreferences by injectLazy()
|
||||
private val chapterCache: ChapterCache by injectLazy()
|
||||
private val xml: XML by injectLazy()
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val getCategories: GetCategories by injectLazy()
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,7 +21,6 @@ import coil3.imageLoader
|
|||
import coil3.request.CachePolicy
|
||||
import coil3.request.ImageRequest
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
|
@ -95,8 +94,6 @@ import yokai.util.lang.getString
|
|||
class LibraryUpdateJob(private val context: Context, workerParams: WorkerParameters) :
|
||||
CoroutineWorker(context, workerParams) {
|
||||
|
||||
private val db: DatabaseHelper = Injekt.get()
|
||||
|
||||
private val getCategories: GetCategories = Injekt.get()
|
||||
private val getChapter: GetChapter = Injekt.get()
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||
}
|
||||
val newLastChapter = chapters.maxByOrNull { it.chapter_number.toInt() }
|
||||
LibraryUpdateJob.updateMutableFlow.tryEmit(manga.id)
|
||||
updateTrackChapterMarkedAsRead(Injekt.get(), preferences, newLastChapter, mangaId, 0)
|
||||
updateTrackChapterMarkedAsRead(preferences, newLastChapter, mangaId, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.work.OneTimeWorkRequestBuilder
|
|||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
import co.touchlab.kermit.Logger
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -31,7 +30,6 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
|
|||
|
||||
override suspend fun doWork(): Result {
|
||||
val preferences = Injekt.get<PreferencesHelper>()
|
||||
val db = Injekt.get<DatabaseHelper>()
|
||||
val trackManager = Injekt.get<TrackManager>()
|
||||
val trackings = preferences.trackingsToAddOnline().get().toMutableSet().mapNotNull {
|
||||
val items = it.split(":")
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.track
|
|||
import androidx.annotation.CallSuper
|
||||
import androidx.annotation.DrawableRes
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.models.isOneShotOrCompleted
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
|
@ -19,7 +18,6 @@ abstract class TrackService(val id: Long) {
|
|||
|
||||
val trackPreferences: TrackPreferences by injectLazy()
|
||||
val networkService: NetworkHelper by injectLazy()
|
||||
val db: DatabaseHelper by injectLazy()
|
||||
val getChapter: GetChapter by injectLazy()
|
||||
val getManga: GetManga by injectLazy()
|
||||
val getHistory: GetHistory by injectLazy()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package eu.kanade.tachiyomi.source.online
|
||||
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||
import eu.kanade.tachiyomi.data.database.models.create
|
||||
|
@ -17,7 +16,6 @@ abstract class DelegatedHttpSource {
|
|||
var delegate: HttpSource? = null
|
||||
abstract val domainName: String
|
||||
|
||||
protected val db: DatabaseHelper by injectLazy()
|
||||
protected val getChapter: GetChapter by injectLazy()
|
||||
protected val getManga: GetManga by injectLazy()
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.mikepenz.fastadapter.FastAdapter
|
||||
import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.models.seriesType
|
||||
|
@ -74,7 +73,6 @@ class SetCategoriesSheet(
|
|||
private val fastAdapter: FastAdapter<AddCategoryItem>
|
||||
private val itemAdapter = ItemAdapter<AddCategoryItem>()
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val getCategories: GetCategories by injectLazy()
|
||||
private val setMangaCategories: SetMangaCategories by injectLazy()
|
||||
private val updateManga: UpdateManga by injectLazy()
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.view.HapticFeedbackConstants
|
|||
import android.view.View
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.library
|
|||
import eu.kanade.tachiyomi.core.preference.minusAssign
|
||||
import eu.kanade.tachiyomi.core.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter.Companion.copy
|
||||
|
@ -84,7 +83,6 @@ import yokai.util.lang.getString
|
|||
* Presenter of [LibraryController].
|
||||
*/
|
||||
class LibraryPresenter(
|
||||
val db: DatabaseHelper = Injekt.get(),
|
||||
private val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
val sourceManager: SourceManager = Injekt.get(),
|
||||
|
|
|
@ -67,7 +67,6 @@ import com.google.android.material.snackbar.Snackbar
|
|||
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
|
||||
import eu.kanade.tachiyomi.BuildConfig
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.download.DownloadJob
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||
|
@ -171,7 +170,6 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
|||
private val mangaShortcutManager: MangaShortcutManager by injectLazy()
|
||||
private val extensionManager: ExtensionManager by injectLazy()
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val getRecents: GetRecents by injectLazy()
|
||||
|
||||
private val hideBottomNav
|
||||
|
|
|
@ -1002,7 +1002,6 @@ class MangaDetailsController :
|
|||
|
||||
fun toggleReadChapter(position: Int) {
|
||||
val preferences = presenter.preferences
|
||||
val db = presenter.db
|
||||
val item = adapter?.getItem(position) as? ChapterItem ?: return
|
||||
val chapter = item.chapter
|
||||
val lastRead = chapter.last_page_read
|
||||
|
@ -1031,7 +1030,7 @@ class MangaDetailsController :
|
|||
if (preferences.removeAfterMarkedAsRead().get()) {
|
||||
presenter.deleteChapters(listOf(item))
|
||||
}
|
||||
updateTrackChapterMarkedAsRead(db, preferences, chapter, manga?.id) {
|
||||
updateTrackChapterMarkedAsRead(preferences, chapter, manga?.id) {
|
||||
presenter.fetchTracks()
|
||||
}
|
||||
}
|
||||
|
@ -1647,7 +1646,6 @@ class MangaDetailsController :
|
|||
val activity = activity ?: return
|
||||
snack?.dismiss()
|
||||
snack = presenter.manga.addOrRemoveToFavorites(
|
||||
presenter.db,
|
||||
presenter.preferences,
|
||||
view,
|
||||
activity,
|
||||
|
|
|
@ -12,7 +12,6 @@ import coil3.request.SuccessResult
|
|||
import com.hippo.unifile.UniFile
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
|
@ -106,7 +105,6 @@ class MangaDetailsPresenter(
|
|||
val sourceManager: SourceManager = Injekt.get(),
|
||||
val preferences: PreferencesHelper = Injekt.get(),
|
||||
val coverCache: CoverCache = Injekt.get(),
|
||||
val db: DatabaseHelper = Injekt.get(),
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val chapterFilter: ChapterFilter = Injekt.get(),
|
||||
private val storageManager: StorageManager = Injekt.get(),
|
||||
|
@ -614,7 +612,7 @@ class MangaDetailsPresenter(
|
|||
withContext(Dispatchers.Main) { view?.updateChapters(chapters) }
|
||||
if (read && deleteNow) {
|
||||
val latestReadChapter = selectedChapters.maxByOrNull { it.chapter_number.toInt() }?.chapter
|
||||
updateTrackChapterMarkedAsRead(db, preferences, latestReadChapter, manga.id) {
|
||||
updateTrackChapterMarkedAsRead(preferences, latestReadChapter, manga.id) {
|
||||
fetchTracks()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.ui.migration
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
@ -21,7 +20,6 @@ import yokai.domain.ui.UiPreferences
|
|||
|
||||
abstract class BaseMigrationPresenter<T : BaseMigrationInterface>(
|
||||
protected val sourceManager: SourceManager = Injekt.get(),
|
||||
protected val db: DatabaseHelper = Injekt.get(),
|
||||
val uiPreferences: UiPreferences = Injekt.get(),
|
||||
val preferences: PreferencesHelper = Injekt.get(),
|
||||
) : BaseCoroutinePresenter<T>() {
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.migration
|
|||
import android.content.Context
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.library.CustomMangaManager
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import eu.kanade.tachiyomi.util.system.toInt
|
||||
|
@ -21,7 +20,6 @@ object MigrationFlags {
|
|||
private const val CUSTOM_MANGA_INFO = 0b1000
|
||||
|
||||
private val coverCache: CoverCache by injectLazy()
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val customMangaManager: CustomMangaManager by injectLazy()
|
||||
private val getTrack: GetTrack by injectLazy()
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.ui.migration.manga.process
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
|
@ -13,7 +12,6 @@ import uy.kohesive.injekt.injectLazy
|
|||
import yokai.domain.manga.interactor.GetManga
|
||||
|
||||
class MigratingManga(
|
||||
private val db: DatabaseHelper,
|
||||
private val sourceManager: SourceManager,
|
||||
val mangaId: Long,
|
||||
parentContext: CoroutineContext,
|
||||
|
|
|
@ -19,7 +19,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import co.touchlab.kermit.Logger
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MigrationListControllerBinding
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
@ -87,7 +86,6 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||
|
||||
val config = args.getParcelableCompat(CONFIG_EXTRA, MigrationProcedureConfig::class.java)
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val getManga: GetManga by injectLazy()
|
||||
private val updateManga: UpdateManga by injectLazy()
|
||||
|
||||
|
@ -117,7 +115,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||
|
||||
val newMigratingManga = migratingManga ?: run {
|
||||
val new = config.mangaIds.map {
|
||||
MigratingManga(db, sourceManager, it, coroutineContext)
|
||||
MigratingManga(sourceManager, it, coroutineContext)
|
||||
}
|
||||
migratingManga = new.toMutableList()
|
||||
new
|
||||
|
|
|
@ -3,9 +3,7 @@ package eu.kanade.tachiyomi.ui.migration.manga.process
|
|||
import android.view.MenuItem
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.database.models.updateCoverLastModified
|
||||
import eu.kanade.tachiyomi.data.library.CustomMangaManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
|
@ -15,7 +13,6 @@ import eu.kanade.tachiyomi.domain.manga.models.Manga
|
|||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.migration.MigrationFlags
|
||||
import eu.kanade.tachiyomi.util.system.launchNow
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -24,14 +21,28 @@ import kotlinx.coroutines.withContext
|
|||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import yokai.domain.category.interactor.GetCategories
|
||||
import yokai.domain.category.interactor.SetMangaCategories
|
||||
import yokai.domain.chapter.interactor.GetChapter
|
||||
import yokai.domain.chapter.interactor.UpdateChapter
|
||||
import yokai.domain.chapter.models.ChapterUpdate
|
||||
import yokai.domain.history.interactor.GetHistory
|
||||
import yokai.domain.history.interactor.UpsertHistory
|
||||
import yokai.domain.library.custom.model.CustomMangaInfo.Companion.getMangaInfo
|
||||
import yokai.domain.manga.interactor.GetManga
|
||||
import yokai.domain.manga.interactor.UpdateManga
|
||||
import yokai.domain.manga.models.MangaUpdate
|
||||
import yokai.domain.track.interactor.GetTrack
|
||||
import yokai.domain.track.interactor.InsertTrack
|
||||
import yokai.domain.ui.UiPreferences
|
||||
|
||||
class MigrationProcessAdapter(
|
||||
val controller: MigrationListController,
|
||||
) : FlexibleAdapter<MigrationProcessItem>(null, controller, true) {
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val getCategories: GetCategories by injectLazy()
|
||||
private val getManga: GetManga by injectLazy()
|
||||
|
||||
var items: List<MigrationProcessItem> = emptyList()
|
||||
val preferences: PreferencesHelper by injectLazy()
|
||||
val uiPreferences: UiPreferences by injectLazy()
|
||||
|
@ -75,25 +86,21 @@ class MigrationProcessAdapter(
|
|||
|
||||
suspend fun performMigrations(copy: Boolean) {
|
||||
withContext(Dispatchers.IO) {
|
||||
db.inTransaction {
|
||||
currentItems.forEach { migratingManga ->
|
||||
val manga = migratingManga.manga
|
||||
if (manga.searchResult.initialized) {
|
||||
val toMangaObj =
|
||||
db.getManga(manga.searchResult.get() ?: return@forEach)
|
||||
.executeAsBlocking()
|
||||
?: return@forEach
|
||||
val prevManga = manga.manga() ?: return@forEach
|
||||
val source = sourceManager.get(toMangaObj.source) ?: return@forEach
|
||||
val prevSource = sourceManager.get(prevManga.source)
|
||||
migrateMangaInternal(
|
||||
prevSource,
|
||||
source,
|
||||
prevManga,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
}
|
||||
currentItems.forEach { migratingManga ->
|
||||
val manga = migratingManga.manga
|
||||
if (manga.searchResult.initialized) {
|
||||
val toMangaObj =
|
||||
getManga.awaitById(manga.searchResult.get() ?: return@forEach) ?: return@forEach
|
||||
val prevManga = manga.manga() ?: return@forEach
|
||||
val source = sourceManager.get(toMangaObj.source) ?: return@forEach
|
||||
val prevSource = sourceManager.get(prevManga.source)
|
||||
migrateMangaInternal(
|
||||
prevSource,
|
||||
source,
|
||||
prevManga,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,21 +109,17 @@ class MigrationProcessAdapter(
|
|||
fun migrateManga(position: Int, copy: Boolean) {
|
||||
launchUI {
|
||||
val manga = getItem(position)?.manga ?: return@launchUI
|
||||
db.inTransaction {
|
||||
val toMangaObj =
|
||||
db.getManga(manga.searchResult.get() ?: return@launchUI).executeAsBlocking()
|
||||
?: return@launchUI
|
||||
val prevManga = manga.manga() ?: return@launchUI
|
||||
val source = sourceManager.get(toMangaObj.source) ?: return@launchUI
|
||||
val prevSource = sourceManager.get(prevManga.source)
|
||||
migrateMangaInternal(
|
||||
prevSource,
|
||||
source,
|
||||
prevManga,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
}
|
||||
val toMangaObj = getManga.awaitById(manga.searchResult.get() ?: return@launchUI) ?: return@launchUI
|
||||
val prevManga = manga.manga() ?: return@launchUI
|
||||
val source = sourceManager.get(toMangaObj.source) ?: return@launchUI
|
||||
val prevSource = sourceManager.get(prevManga.source)
|
||||
migrateMangaInternal(
|
||||
prevSource,
|
||||
source,
|
||||
prevManga,
|
||||
toMangaObj,
|
||||
!copy,
|
||||
)
|
||||
removeManga(position)
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +134,7 @@ class MigrationProcessAdapter(
|
|||
}
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
private fun migrateMangaInternal(
|
||||
private suspend fun migrateMangaInternal(
|
||||
prevSource: Source?,
|
||||
source: Source,
|
||||
prevManga: Manga,
|
||||
|
@ -140,15 +143,24 @@ class MigrationProcessAdapter(
|
|||
) {
|
||||
if (controller.config == null) return
|
||||
val flags = preferences.migrateFlags().get()
|
||||
migrateMangaInternal(flags, db, enhancedServices, coverCache, customMangaManager, prevSource, source, prevManga, manga, replace)
|
||||
migrateMangaInternal(
|
||||
flags,
|
||||
enhancedServices,
|
||||
coverCache,
|
||||
customMangaManager,
|
||||
prevSource,
|
||||
source,
|
||||
prevManga,
|
||||
manga,
|
||||
replace,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
// FIXME: Migrate to SQLDelight, on halt: in StorIO transaction
|
||||
fun migrateMangaInternal(
|
||||
suspend fun migrateMangaInternal(
|
||||
flags: Int,
|
||||
db: DatabaseHelper,
|
||||
enhancedServices: List<EnhancedTrackService>,
|
||||
coverCache: CoverCache,
|
||||
customMangaManager: CustomMangaManager,
|
||||
|
@ -160,20 +172,30 @@ class MigrationProcessAdapter(
|
|||
) {
|
||||
// Update chapters read
|
||||
if (MigrationFlags.hasChapters(flags)) {
|
||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
||||
val maxChapterRead =
|
||||
prevMangaChapters.filter { it.read }.maxOfOrNull { it.chapter_number } ?: 0f
|
||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||
val prevHistoryList = db.getHistoryByMangaId(prevManga.id!!).executeAsBlocking()
|
||||
val getChapter: GetChapter = Injekt.get()
|
||||
val updateChapter: UpdateChapter = Injekt.get()
|
||||
val getHistory: GetHistory = Injekt.get()
|
||||
val upsertHistory: UpsertHistory = Injekt.get()
|
||||
|
||||
val prevMangaChapters = getChapter.awaitAll(prevManga, false)
|
||||
val maxChapterRead = prevMangaChapters.filter { it.read }.maxOfOrNull { it.chapter_number } ?: 0f
|
||||
val dbChapters = getChapter.awaitAll(manga, false)
|
||||
val prevHistoryList = getHistory.awaitAllByMangaId(prevManga.id!!)
|
||||
val historyList = mutableListOf<History>()
|
||||
val chapterUpdates = mutableListOf<ChapterUpdate>()
|
||||
for (chapter in dbChapters) {
|
||||
if (chapter.isRecognizedNumber) {
|
||||
var update: ChapterUpdate? = null
|
||||
val prevChapter =
|
||||
prevMangaChapters.find { it.isRecognizedNumber && it.chapter_number == chapter.chapter_number }
|
||||
if (prevChapter != null) {
|
||||
chapter.bookmark = prevChapter.bookmark
|
||||
chapter.read = prevChapter.read
|
||||
chapter.date_fetch = prevChapter.date_fetch
|
||||
// copy data from prevChapter -> chapter
|
||||
update = ChapterUpdate(
|
||||
id = chapter.id!!,
|
||||
bookmark = prevChapter.bookmark,
|
||||
read = prevChapter.read,
|
||||
dateFetch = prevChapter.date_fetch,
|
||||
)
|
||||
prevHistoryList.find { it.chapter_id == prevChapter.id }
|
||||
?.let { prevHistory ->
|
||||
val history = History.create(chapter)
|
||||
|
@ -184,23 +206,26 @@ class MigrationProcessAdapter(
|
|||
historyList.add(history)
|
||||
}
|
||||
} else if (chapter.chapter_number <= maxChapterRead) {
|
||||
chapter.read = true
|
||||
update = ChapterUpdate(
|
||||
id = chapter.id!!,
|
||||
read = true
|
||||
)
|
||||
}
|
||||
update?.let { chapterUpdates.add(it) }
|
||||
}
|
||||
}
|
||||
db.insertChapters(dbChapters).executeAsBlocking()
|
||||
db.upsertHistoryLastRead(historyList).executeAsBlocking()
|
||||
updateChapter.awaitAll(chapterUpdates)
|
||||
upsertHistory.awaitBulk(historyList)
|
||||
}
|
||||
// Update categories
|
||||
if (MigrationFlags.hasCategories(flags)) {
|
||||
val categories = db.getCategoriesForManga(prevManga).executeAsBlocking()
|
||||
val mangaCategories = categories.map { MangaCategory.create(manga, it) }
|
||||
db.setMangaCategories(mangaCategories, listOf(manga))
|
||||
val categories = Injekt.get<GetCategories>().awaitByMangaId(prevManga.id)
|
||||
Injekt.get<SetMangaCategories>().await(prevManga.id, categories.mapNotNull { it.id?.toLong() })
|
||||
}
|
||||
// Update track
|
||||
if (MigrationFlags.hasTracks(flags)) {
|
||||
val tracksToUpdate =
|
||||
db.getTracks(prevManga).executeAsBlocking().mapNotNull { track ->
|
||||
Injekt.get<GetTrack>().awaitAllByMangaId(prevManga.id).mapNotNull { track ->
|
||||
track.id = null
|
||||
track.manga_id = manga.id!!
|
||||
|
||||
|
@ -212,13 +237,20 @@ class MigrationProcessAdapter(
|
|||
track
|
||||
}
|
||||
}
|
||||
db.insertTracks(tracksToUpdate).executeAsBlocking()
|
||||
Injekt.get<InsertTrack>().awaitBulk(tracksToUpdate)
|
||||
}
|
||||
val updateManga: UpdateManga = Injekt.get()
|
||||
// Update favorite status
|
||||
if (replace) {
|
||||
prevManga.favorite = false
|
||||
db.updateMangaFavorite(prevManga).executeAsBlocking()
|
||||
updateManga.await(
|
||||
MangaUpdate(
|
||||
id = prevManga.id!!,
|
||||
favorite = false,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
manga.favorite = true
|
||||
if (replace) {
|
||||
manga.date_added = prevManga.date_added
|
||||
|
@ -230,18 +262,21 @@ class MigrationProcessAdapter(
|
|||
if (MigrationFlags.hasCustomMangaInfo(flags)) {
|
||||
if (coverCache.getCustomCoverFile(prevManga).exists()) {
|
||||
coverCache.setCustomCoverToCache(manga, coverCache.getCustomCoverFile(prevManga).inputStream())
|
||||
launchNow { manga.updateCoverLastModified() }
|
||||
manga.updateCoverLastModified()
|
||||
}
|
||||
customMangaManager.getManga(prevManga)?.let { customManga ->
|
||||
launchNow {
|
||||
customMangaManager.updateMangaInfo(prevManga.id, manga.id, customManga.getMangaInfo())
|
||||
}
|
||||
customMangaManager.updateMangaInfo(prevManga.id, manga.id, customManga.getMangaInfo())
|
||||
}
|
||||
}
|
||||
|
||||
db.updateMangaFavorite(manga).executeAsBlocking()
|
||||
db.updateMangaAdded(manga).executeAsBlocking()
|
||||
db.updateMangaTitle(manga).executeAsBlocking()
|
||||
updateManga.await(
|
||||
MangaUpdate(
|
||||
id = manga.id!!,
|
||||
title = manga.title,
|
||||
favorite = manga.favorite,
|
||||
dateAdded = manga.date_added,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import androidx.core.view.isInvisible
|
|||
import androidx.core.view.isVisible
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.coil.useCustomCover
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.databinding.MangaGridItemBinding
|
||||
import eu.kanade.tachiyomi.databinding.MigrationProcessItemBinding
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
|
@ -25,6 +24,7 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import yokai.domain.chapter.interactor.GetChapter
|
||||
import yokai.domain.manga.interactor.GetManga
|
||||
import yokai.domain.manga.models.cover
|
||||
import yokai.i18n.MR
|
||||
import yokai.presentation.core.util.coil.loadManga
|
||||
|
@ -35,8 +35,8 @@ class MigrationProcessHolder(
|
|||
private val adapter: MigrationProcessAdapter,
|
||||
) : BaseFlexibleViewHolder(view, adapter) {
|
||||
|
||||
private val db: DatabaseHelper by injectLazy()
|
||||
private val getChapter: GetChapter by injectLazy()
|
||||
private val getManga: GetManga by injectLazy()
|
||||
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
private var item: MigrationProcessItem? = null
|
||||
|
@ -99,12 +99,8 @@ class MigrationProcessHolder(
|
|||
}
|
||||
}*/
|
||||
|
||||
val searchResult = item.manga.searchResult.get()?.let {
|
||||
db.getManga(it).executeAsBlocking()
|
||||
}
|
||||
val resultSource = searchResult?.source?.let {
|
||||
sourceManager.get(it)
|
||||
}
|
||||
val searchResult = item.manga.searchResult.get()?.let { getManga.awaitById(it) }
|
||||
val resultSource = searchResult?.source?.let { sourceManager.get(it) }
|
||||
withContext(Dispatchers.Main) {
|
||||
if (item.manga.mangaId != this@MigrationProcessHolder.item?.manga?.mangaId || item.manga.migrationStatus == MigrationStatus.RUNNUNG) {
|
||||
return@withContext
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.ui.more.stats
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
|
@ -30,7 +29,6 @@ import yokai.util.lang.getString
|
|||
* Presenter of [StatsController].
|
||||
*/
|
||||
class StatsPresenter(
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val prefs: PreferencesHelper = Injekt.get(),
|
||||
private val trackManager: TrackManager = Injekt.get(),
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.graphics.drawable.Drawable
|
|||
import android.text.format.DateUtils
|
||||
import androidx.annotation.DrawableRes
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
||||
|
@ -48,7 +47,6 @@ import yokai.i18n.MR
|
|||
import yokai.util.lang.getString
|
||||
|
||||
class StatsDetailsPresenter(
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val prefs: PreferencesHelper = Injekt.get(),
|
||||
val trackManager: TrackManager = Injekt.get(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.lifecycle.viewModelScope
|
|||
import co.touchlab.kermit.Logger
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.defaultReaderType
|
||||
|
@ -98,7 +97,6 @@ import yokai.util.lang.getString
|
|||
*/
|
||||
class ReaderViewModel(
|
||||
private val savedState: SavedStateHandle = SavedStateHandle(),
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
|
|
|
@ -90,12 +90,12 @@ import eu.kanade.tachiyomi.util.view.snack
|
|||
import eu.kanade.tachiyomi.util.view.updateGradiantBGRadius
|
||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.widget.LinearLayoutManagerAccurateOffset
|
||||
import java.util.Locale
|
||||
import kotlin.math.max
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import yokai.i18n.MR
|
||||
import yokai.util.lang.getString
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
import android.R as AR
|
||||
|
||||
/**
|
||||
|
@ -839,7 +839,6 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
|
||||
override fun markAsRead(position: Int) {
|
||||
val preferences = presenter.preferences
|
||||
val db = presenter.db
|
||||
val item = adapter.getItem(position) as? RecentMangaItem ?: return
|
||||
val holder = binding.recycler.findViewHolderForAdapterPosition(position)
|
||||
val holderId = (holder as? RecentMangaHolder)?.chapterId
|
||||
|
@ -880,7 +879,7 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
lastChapterId = chapter.id
|
||||
presenter.deleteChapter(chapter, manga)
|
||||
}
|
||||
updateTrackChapterMarkedAsRead(db, preferences, chapter, manga.id) {
|
||||
updateTrackChapterMarkedAsRead(preferences, chapter, manga.id) {
|
||||
(router.backstack.lastOrNull()?.controller as? MangaDetailsController)?.presenter?.fetchTracks()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.ui.recents
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.ChapterHistory
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
|
@ -55,7 +54,6 @@ class RecentsPresenter(
|
|||
val recentsPreferences: RecentsPreferences = Injekt.get(),
|
||||
val preferences: PreferencesHelper = Injekt.get(),
|
||||
val downloadManager: DownloadManager = Injekt.get(),
|
||||
val db: DatabaseHelper = Injekt.get(),
|
||||
private val chapterFilter: ChapterFilter = Injekt.get(),
|
||||
) : BaseCoroutinePresenter<RecentsController>(), DownloadQueue.DownloadListener {
|
||||
private val handler: DatabaseHandler by injectLazy()
|
||||
|
|
|
@ -58,10 +58,10 @@ import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
|||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
import eu.kanade.tachiyomi.widget.EmptyView
|
||||
import eu.kanade.tachiyomi.widget.LinearLayoutManagerAccurateOffset
|
||||
import kotlin.math.roundToInt
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import yokai.i18n.MR
|
||||
import yokai.util.lang.getString
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* Controller to manage the catalogues available in the app.
|
||||
|
@ -769,7 +769,6 @@ open class BrowseSourceController(bundle: Bundle) :
|
|||
val activity = activity ?: return
|
||||
snack?.dismiss()
|
||||
snack = manga.addOrRemoveToFavorites(
|
||||
presenter.db,
|
||||
preferences,
|
||||
view,
|
||||
activity,
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.source.browse
|
|||
import co.touchlab.kermit.Logger
|
||||
import eu.davidea.flexibleadapter.items.IFlexible
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.create
|
||||
import eu.kanade.tachiyomi.data.database.models.removeCover
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
|
@ -54,7 +53,6 @@ open class BrowseSourcePresenter(
|
|||
searchQuery: String? = null,
|
||||
var useLatest: Boolean = false,
|
||||
val sourceManager: SourceManager = Injekt.get(),
|
||||
val db: DatabaseHelper = Injekt.get(),
|
||||
val uiPreferences: UiPreferences = Injekt.get(),
|
||||
val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
|
|
|
@ -116,7 +116,6 @@ open class GlobalSearchController(
|
|||
val activity = activity ?: return
|
||||
snack?.dismiss()
|
||||
snack = manga.addOrRemoveToFavorites(
|
||||
presenter.db,
|
||||
preferences,
|
||||
view,
|
||||
activity,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.source.globalsearch
|
||||
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.create
|
||||
import eu.kanade.tachiyomi.data.database.models.removeCover
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
|
@ -38,7 +37,6 @@ import yokai.domain.manga.interactor.UpdateManga
|
|||
* Function calls should be done from here. UI calls should be done from the controller.
|
||||
*
|
||||
* @param sourceManager manages the different sources.
|
||||
* @param db manages the database calls.
|
||||
* @param preferences manages the preference calls.
|
||||
*/
|
||||
open class GlobalSearchPresenter(
|
||||
|
@ -46,7 +44,6 @@ open class GlobalSearchPresenter(
|
|||
private val initialExtensionFilter: String? = null,
|
||||
private val sourcesToUse: List<CatalogueSource>? = null,
|
||||
val sourceManager: SourceManager = Injekt.get(),
|
||||
val db: DatabaseHelper = Injekt.get(),
|
||||
private val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
) : BaseCoroutinePresenter<GlobalSearchController>() {
|
||||
|
|
|
@ -10,7 +10,6 @@ import co.touchlab.kermit.Logger
|
|||
import com.bluelinelabs.conductor.Controller
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.seriesType
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
|
@ -29,6 +28,7 @@ import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcessAdapter
|
|||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithTrackServiceTwoWay
|
||||
import eu.kanade.tachiyomi.util.lang.asButton
|
||||
import eu.kanade.tachiyomi.util.system.launchIO
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.materialAlertDialog
|
||||
import eu.kanade.tachiyomi.util.system.setCustomTitleAndMessage
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
|
@ -147,7 +147,6 @@ fun List<Manga>.moveCategories(
|
|||
}
|
||||
|
||||
fun Manga.addOrRemoveToFavorites(
|
||||
db: DatabaseHelper,
|
||||
preferences: PreferencesHelper,
|
||||
view: View,
|
||||
activity: Activity,
|
||||
|
@ -175,12 +174,10 @@ fun Manga.addOrRemoveToFavorites(
|
|||
this,
|
||||
duplicateManga,
|
||||
activity,
|
||||
db,
|
||||
sourceManager,
|
||||
controller,
|
||||
addManga = {
|
||||
addOrRemoveToFavorites(
|
||||
db,
|
||||
preferences,
|
||||
view,
|
||||
activity,
|
||||
|
@ -375,7 +372,6 @@ private fun showAddDuplicateDialog(
|
|||
newManga: Manga,
|
||||
libraryManga: Manga,
|
||||
activity: Activity,
|
||||
db: DatabaseHelper,
|
||||
sourceManager: SourceManager,
|
||||
controller: Controller,
|
||||
addManga: () -> Unit,
|
||||
|
@ -389,18 +385,19 @@ private fun showAddDuplicateDialog(
|
|||
val enabled = titles.indices.map { listView.isItemChecked(it) }.toTypedArray()
|
||||
val flags = MigrationFlags.getFlagsFromPositions(enabled, libraryManga)
|
||||
val enhancedServices by lazy { Injekt.get<TrackManager>().services.filterIsInstance<EnhancedTrackService>() }
|
||||
MigrationProcessAdapter.migrateMangaInternal(
|
||||
flags,
|
||||
db,
|
||||
enhancedServices,
|
||||
Injekt.get(),
|
||||
Injekt.get(),
|
||||
source,
|
||||
sourceManager.getOrStub(newManga.source),
|
||||
libraryManga,
|
||||
newManga,
|
||||
replace,
|
||||
)
|
||||
launchUI {
|
||||
MigrationProcessAdapter.migrateMangaInternal(
|
||||
flags,
|
||||
enhancedServices,
|
||||
Injekt.get(),
|
||||
Injekt.get(),
|
||||
source,
|
||||
sourceManager.getOrStub(newManga.source),
|
||||
libraryManga,
|
||||
newManga,
|
||||
replace,
|
||||
)
|
||||
}
|
||||
migrateManga(libraryManga.source, !replace)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package eu.kanade.tachiyomi.util.chapter
|
||||
|
||||
import co.touchlab.kermit.Logger
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
|
@ -67,7 +66,6 @@ private var trackingJobs = HashMap<Long, Pair<Job?, Float?>>()
|
|||
* will run in a background thread and errors are ignored.
|
||||
*/
|
||||
fun updateTrackChapterMarkedAsRead(
|
||||
db: DatabaseHelper,
|
||||
preferences: PreferencesHelper,
|
||||
newLastChapter: Chapter?,
|
||||
mangaId: Long?,
|
||||
|
|
|
@ -15,7 +15,6 @@ import coil3.size.SizeResolver
|
|||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.appwidget.TachiyomiWidgetManager
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.domain.manga.models.Manga
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
|
@ -35,7 +34,6 @@ import kotlin.math.min
|
|||
|
||||
class MangaShortcutManager(
|
||||
val preferences: PreferencesHelper = Injekt.get(),
|
||||
val db: DatabaseHelper = Injekt.get(),
|
||||
val coverCache: CoverCache = Injekt.get(),
|
||||
val sourceManager: SourceManager = Injekt.get(),
|
||||
) {
|
||||
|
|
|
@ -10,7 +10,6 @@ import eu.kanade.tachiyomi.BuildConfig
|
|||
import eu.kanade.tachiyomi.core.storage.AndroidStorageFolderProvider
|
||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.DbOpenCallback
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.library.CustomMangaManager
|
||||
|
@ -84,10 +83,6 @@ fun appModule(app: Application) = module {
|
|||
|
||||
single<DatabaseHandler> { AndroidDatabaseHandler(get(), get()) }
|
||||
|
||||
single { DatabaseHelper(app, get()) } withOptions {
|
||||
createdAtStart()
|
||||
}
|
||||
|
||||
single { ChapterCache(app) }
|
||||
|
||||
single { CoverCache(app) }
|
||||
|
|
|
@ -28,4 +28,24 @@ class TrackRepositoryImpl(private val handler: DatabaseHandler) : TrackRepositor
|
|||
finishDate = track.finished_reading_date,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun insertBulk(tracks: List<Track>) =
|
||||
handler.await(inTransaction = true) {
|
||||
tracks.forEach { track ->
|
||||
manga_syncQueries.insert(
|
||||
mangaId = track.manga_id,
|
||||
syncId = track.sync_id,
|
||||
remoteId = track.media_id,
|
||||
libraryId = track.library_id,
|
||||
title = track.title,
|
||||
lastChapterRead = track.last_chapter_read.toDouble(),
|
||||
totalChapters = track.total_chapters,
|
||||
status = track.status.toLong(),
|
||||
score = track.score.toDouble(),
|
||||
remoteUrl = track.tracking_url,
|
||||
startDate = track.started_reading_date,
|
||||
finishDate = track.finished_reading_date,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@ class GetCategories(
|
|||
private val categoryRepository: CategoryRepository,
|
||||
) {
|
||||
suspend fun await() = categoryRepository.getAll()
|
||||
suspend fun awaitByMangaId(mangaId: Long) = categoryRepository.getAllByMangaId(mangaId)
|
||||
suspend fun awaitByMangaId(mangaId: Long?) = mangaId?.let { categoryRepository.getAllByMangaId(it) }.orEmpty()
|
||||
fun subscribe() = categoryRepository.getAllAsFlow()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ import yokai.domain.manga.MangaRepository
|
|||
class SetMangaCategories(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
suspend fun await(mangaId: Long, categories: List<Long>) = mangaRepository.setCategories(mangaId, categories)
|
||||
suspend fun await(mangaId: Long?, categories: List<Long>) {
|
||||
mangaRepository.setCategories(mangaId ?: return, categories)
|
||||
}
|
||||
suspend fun awaitAll(mangaIds: List<Long>, mangaCategories: List<MangaCategory>) =
|
||||
mangaRepository.setMultipleMangaCategories(mangaIds, mangaCategories)
|
||||
}
|
||||
|
|
|
@ -6,4 +6,5 @@ interface TrackRepository {
|
|||
suspend fun getAllByMangaId(mangaId: Long): List<Track>
|
||||
suspend fun deleteForManga(mangaId: Long, syncId: Long)
|
||||
suspend fun insert(track: Track)
|
||||
suspend fun insertBulk(tracks: List<Track>)
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@ class InsertTrack(
|
|||
private val trackRepository: TrackRepository,
|
||||
) {
|
||||
suspend fun await(track: Track) = trackRepository.insert(track)
|
||||
suspend fun awaitBulk(tracks: List<Track>) = trackRepository.insertBulk(tracks)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue