- Uses the new `asObservable` function to change the database calls to use SQLDelight, which should make the impact minimal when it comes to bugs. - Use interactors where they already exist - The todos are for the Compose rewrite - Removed unused StorIO methods/queries - Tested loading library, move manga to new category, unfavorite multiple manga, move multiple manga from one category to another, change filter, sort and display settings (with and without per category settings), (un)mark chapters, start/delete downloads Thank Syer for asObservable Co-authored-by: jobobby04 <17078382+jobobby04@users.noreply.github.com> Co-authored-by: jobobby04 <17078382+jobobby04@users.noreply.github.com> (cherry picked from commit 05085fe57fe4c3ada497f93b8cd282a5009cdbbb) # Conflicts: # app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt # app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt # app/src/main/java/eu/kanade/tachiyomi/data/database/queries/CategoryQueries.kt # app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt # app/src/main/java/eu/kanade/tachiyomi/data/database/queries/TrackQueries.kt # app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt # app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt # app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt # app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt # app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
96 lines
3.3 KiB
Kotlin
96 lines
3.3 KiB
Kotlin
package eu.kanade.data
|
|
|
|
import androidx.paging.PagingSource
|
|
import com.squareup.sqldelight.Query
|
|
import com.squareup.sqldelight.db.SqlDriver
|
|
import com.squareup.sqldelight.runtime.coroutines.asFlow
|
|
import com.squareup.sqldelight.runtime.coroutines.mapToList
|
|
import com.squareup.sqldelight.runtime.coroutines.mapToOne
|
|
import com.squareup.sqldelight.runtime.coroutines.mapToOneOrNull
|
|
import eu.kanade.data.manga.LibraryQuery
|
|
import eu.kanade.tachiyomi.Database
|
|
import kotlinx.coroutines.CoroutineDispatcher
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.flow.Flow
|
|
import kotlinx.coroutines.withContext
|
|
|
|
class AndroidDatabaseHandler(
|
|
val db: Database,
|
|
private val driver: SqlDriver,
|
|
val queryDispatcher: CoroutineDispatcher = Dispatchers.IO,
|
|
val transactionDispatcher: CoroutineDispatcher = queryDispatcher,
|
|
) : DatabaseHandler {
|
|
|
|
val suspendingTransactionId = ThreadLocal<Int>()
|
|
|
|
override suspend fun <T> await(inTransaction: Boolean, block: suspend Database.() -> T): T {
|
|
return dispatch(inTransaction, block)
|
|
}
|
|
|
|
override suspend fun <T : Any> awaitList(
|
|
inTransaction: Boolean,
|
|
block: suspend Database.() -> Query<T>,
|
|
): List<T> {
|
|
return dispatch(inTransaction) { block(db).executeAsList() }
|
|
}
|
|
|
|
override suspend fun <T : Any> awaitOne(
|
|
inTransaction: Boolean,
|
|
block: suspend Database.() -> Query<T>,
|
|
): T {
|
|
return dispatch(inTransaction) { block(db).executeAsOne() }
|
|
}
|
|
|
|
override suspend fun <T : Any> awaitOneOrNull(
|
|
inTransaction: Boolean,
|
|
block: suspend Database.() -> Query<T>,
|
|
): T? {
|
|
return dispatch(inTransaction) { block(db).executeAsOneOrNull() }
|
|
}
|
|
|
|
override fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>> {
|
|
return block(db).asFlow().mapToList(queryDispatcher)
|
|
}
|
|
|
|
override fun <T : Any> subscribeToOne(block: Database.() -> Query<T>): Flow<T> {
|
|
return block(db).asFlow().mapToOne(queryDispatcher)
|
|
}
|
|
|
|
override fun <T : Any> subscribeToOneOrNull(block: Database.() -> Query<T>): Flow<T?> {
|
|
return block(db).asFlow().mapToOneOrNull(queryDispatcher)
|
|
}
|
|
|
|
override fun <T : Any> subscribeToPagingSource(
|
|
countQuery: Database.() -> Query<Long>,
|
|
queryProvider: Database.(Long, Long) -> Query<T>,
|
|
): PagingSource<Long, T> {
|
|
return QueryPagingSource(
|
|
handler = this,
|
|
countQuery = countQuery,
|
|
queryProvider = { limit, offset ->
|
|
queryProvider.invoke(db, limit, offset)
|
|
},
|
|
)
|
|
}
|
|
|
|
private suspend fun <T> dispatch(inTransaction: Boolean, block: suspend Database.() -> T): T {
|
|
// Create a transaction if needed and run the calling block inside it.
|
|
if (inTransaction) {
|
|
return withTransaction { block(db) }
|
|
}
|
|
|
|
// If we're currently in the transaction thread, there's no need to dispatch our query.
|
|
if (driver.currentTransaction() != null) {
|
|
return block(db)
|
|
}
|
|
|
|
// Get the current database context and run the calling block.
|
|
val context = getCurrentDatabaseContext()
|
|
return withContext(context) { block(db) }
|
|
}
|
|
|
|
// SY -->
|
|
fun getLibraryQuery() = LibraryQuery(driver)
|
|
// SY <--
|
|
}
|