mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
chore: Flow version of firstOrNull
This commit is contained in:
parent
19ea7cbebd
commit
106737371f
6 changed files with 47 additions and 0 deletions
|
@ -30,6 +30,9 @@ class MangaRepositoryImpl(private val handler: DatabaseHandler) : MangaRepositor
|
|||
override fun getMangaListAsFlow(): Flow<List<Manga>> =
|
||||
handler.subscribeToList { mangasQueries.findAll(Manga::mapper) }
|
||||
|
||||
override fun getMangaByUrlAndSourceAsFlow(url: String, source: Long): Flow<Manga?> =
|
||||
handler.subscribeToFirstOrNull { mangasQueries.findByUrlAndSource(url, source, Manga::mapper) }
|
||||
|
||||
override suspend fun getLibraryManga(): List<LibraryManga> =
|
||||
handler.awaitList { library_viewQueries.findAll(LibraryManga::mapper) }
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import yokai.domain.manga.models.MangaUpdate
|
|||
interface MangaRepository {
|
||||
suspend fun getMangaList(): List<Manga>
|
||||
suspend fun getMangaByUrlAndSource(url: String, source: Long): Manga?
|
||||
fun getMangaByUrlAndSourceAsFlow(url: String, source: Long): Flow<Manga?>
|
||||
suspend fun getMangaById(id: Long): Manga?
|
||||
suspend fun getFavorites(): List<Manga>
|
||||
suspend fun getReadNotFavorites(): List<Manga>
|
||||
|
|
|
@ -7,6 +7,7 @@ class GetManga (
|
|||
) {
|
||||
suspend fun awaitAll() = mangaRepository.getMangaList()
|
||||
fun subscribeAll() = mangaRepository.getMangaListAsFlow()
|
||||
fun subscribeByUrlAndSource(url: String, source: Long) = mangaRepository.getMangaByUrlAndSourceAsFlow(url, source)
|
||||
|
||||
suspend fun awaitByUrlAndSource(url: String, source: Long) = mangaRepository.getMangaByUrlAndSource(url, source)
|
||||
suspend fun awaitById(id: Long) = mangaRepository.getMangaById(id)
|
||||
|
|
|
@ -12,6 +12,7 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
import yokai.data.util.executeAsFirstOrNull
|
||||
import yokai.data.util.mapToFirstOrNull
|
||||
|
||||
class AndroidDatabaseHandler(
|
||||
val db: Database,
|
||||
|
@ -80,6 +81,10 @@ class AndroidDatabaseHandler(
|
|||
return block(db).asFlow().mapToOneOrNull(queryDispatcher)
|
||||
}
|
||||
|
||||
override fun <T : Any> subscribeToFirstOrNull(block: Database.() -> Query<T>): Flow<T?> {
|
||||
return block(db).asFlow().mapToFirstOrNull(queryDispatcher)
|
||||
}
|
||||
|
||||
/*
|
||||
override fun <T : Any> subscribeToPagingSource(
|
||||
countQuery: Database.() -> Query<Long>,
|
||||
|
|
|
@ -43,6 +43,8 @@ interface DatabaseHandler {
|
|||
|
||||
fun <T : Any> subscribeToOneOrNull(block: Database.() -> Query<T>): Flow<T?>
|
||||
|
||||
fun <T : Any> subscribeToFirstOrNull(block: Database.() -> Query<T>): Flow<T?>
|
||||
|
||||
/*
|
||||
fun <T : Any> subscribeToPagingSource(
|
||||
countQuery: Database.() -> Query<Long>,
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package yokai.data.util
|
||||
|
||||
import app.cash.sqldelight.ExecutableQuery
|
||||
import app.cash.sqldelight.Query
|
||||
import app.cash.sqldelight.db.QueryResult
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
fun <T : Any> ExecutableQuery<T>.executeAsFirst(): T {
|
||||
return executeAsFirstOrNull() ?: throw NullPointerException("ResultSet returned null for $this")
|
||||
|
@ -11,3 +16,33 @@ fun <T : Any> ExecutableQuery<T>.executeAsFirstOrNull(): T? = execute { cursor -
|
|||
if (!cursor.next().value) return@execute QueryResult.Value(null)
|
||||
QueryResult.Value(mapper(cursor))
|
||||
}.value
|
||||
|
||||
suspend fun <T : Any> ExecutableQuery<T>.awaitAsFirst(): T {
|
||||
return awaitAsFirstOrNull()
|
||||
?: throw NullPointerException("ResultSet returned null for $this")
|
||||
}
|
||||
|
||||
suspend fun <T : Any> ExecutableQuery<T>.awaitAsFirstOrNull(): T? = execute { cursor ->
|
||||
// If the cursor isn't async, we want to preserve the blocking semantics and execute it synchronously
|
||||
when (val next = cursor.next()) {
|
||||
is QueryResult.AsyncValue -> {
|
||||
QueryResult.AsyncValue {
|
||||
if (!next.await()) return@AsyncValue null
|
||||
mapper(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
is QueryResult.Value -> {
|
||||
if (!next.value) return@execute QueryResult.Value(null)
|
||||
QueryResult.Value(mapper(cursor))
|
||||
}
|
||||
}
|
||||
}.await()
|
||||
|
||||
fun <T : Any> Flow<Query<T>>.mapToFirstOrNull(
|
||||
context: CoroutineContext,
|
||||
): Flow<T?> = map {
|
||||
withContext(context) {
|
||||
it.awaitAsFirstOrNull()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue