Estoy usando Room como ORM y aquí está mi interfaz Dao:

@Dao
interface UserDao {
    @Query(value = "SELECT * FROM User LIMIT 1")
    fun get(): Single<User?>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun add(profile: User)
}

Por otro lado, tengo un método en el repositorio que debe verificar si el usuario está conectado o no, aquí está el código de implementación:

override fun isUserLogin(): Single<Boolean> = userDao
            .get().async()
            .onErrorReturn { null }
            .map { it != null }

Room lanzará la siguiente excepción si ninguna fila coincide con la consulta:

La consulta devolvió el conjunto de resultados vacío: SELECCIONAR * DESDE EL LÍMITE 1

Quiero devolver null en este caso, pero cuando ejecuto el código arroja una excepción con el siguiente mensaje:

El valor suministrado era nulo

No puedo usar Optional porque Dao está devolviendo Single<User?>, así que onErrorReturn debería devolver el mismo tipo.

¿Cómo puedo verificar si el usuario existe o no sin cambiar Dao?

3
Mosius 8 sep. 2018 a las 14:44

3 respuestas

La mejor respuesta

Creo que la forma correcta de hacer esto, además de Android y Room, es utilizar COUNT en su consulta.

@Query("SELECT COUNT(*) from User")
fun usersCount() : Single<Int>

Devolverá el número de filas en la tabla, si es 0, sabe que no hay ningún usuario en la base de datos, entonces.

override fun isUserLogin(): Single<Int> = userDao
            .usersCount()
            .async()
            .map { it > 0 }

Sin embargo, si realmente quieres hacerlo de la manera fea:

@Query(value = "SELECT * FROM User LIMIT 1")
fun get(): Single<User>

No use un tipo anulable, no tiene sentido. Luego asigne a Boolean y maneje la excepción:

override fun isUserLogin(): Single<Boolean> = userDao
        .get()
        .async()
        .map { true }
        .onErrorReturn { false }
4
lelloman 8 sep. 2018 a las 14:53

Utilice Maybe, que modela con precisión la respuesta esperando 0 resultados, 1 resultado o una excepción.

1
Kiskae 8 sep. 2018 a las 11:46

Si cambia su DAO para devolver una lista fluida de usuarios, puede asignar esto a un valor booleano comprobando el tamaño de la lista.

@Query(value = "SELECT * FROM User LIMIT 1")
fun get(): Flowable<List<User>> 

E.g.

fun isUserLogin(): Single<Boolean> = userDao
    .get()
    .flatMapSingle { Single.just(it.size == 1) }
    .onErrorReturn { false }
    .first(false)
0
Chris 8 sep. 2018 a las 13:03