Patrón de repositorio con SqlBrite / SqlDelight (base de datos sin conexión) y Retrofit (solicitud Http)

Estoy implementando el patrón del repositorio en RxJava usando SqlBrite / SqlDelight para el almacenamiento de datos fuera de línea y retrofit para las solicitudes Http

Aquí hay una muestra de eso:

protected Observable<List<Item>> getItemsFromDb() { return database.createQuery(tableName(), selectAllStatement()) .mapToList(cursor -> selectAllMapper().map(cursor)); } public Observable<List<Item>>getItems(){ Observable<List<Item>> server = getRequest() .doOnNext(items -> { BriteDatabase.Transaction transaction = database.newTransaction(); for (Item item : items){ database.insert(tableName(), contentValues(item)); } transaction.markSuccessful(); transaction.end(); }) .flatMap(items -> getItemsFromDbById()) .delaySubscription(200, TimeUnit.MILLISECONDS); Observable<List<Item>> db = getItemsFromDbById(id) .filter(items -> items != null && items.size() > 0); return Observable.amb(db, server).doOnSubscribe(() -> server.subscribe(items -> {}, throwable -> {})); } 

La implementación actual utiliza Observable.amb para obtener la última de 2 flujos y devuelve la secuencia de db en caso de que db tenga datos o servidor de lo contrario. Para evitar un fallo temprano en caso de que no haya internet, el server tiene un delaySubscription en él con 200ms .

Intenté usar Observable.concat pero el flujo de SqlBrite nunca llama el onComplete así que el server observable nunca se onComplete .

También intenté Observable.combineLatest que no funcionó porque mantiene esperando el server observable para volver datos antes de emitir cualquier cosa y Observable.switchOnNext no trabajó tampoco.

Lo que estoy buscando es un repositorio que:

  • Mantiene abierta la suscripción a SqlBrite (DB), en caso de actualizaciones de DB
  • Siempre busca datos del servidor y los escribe en la base de datos
  • No debe emitir un resultado vacío en caso de que no haya nada en la base de datos y la solicitud de red sigue en curso. Esto, porque el usuario debe ver una barra de progreso en el caso de la primera carga.

Usted código contradice directamente lo que quiere hacer. Esta línea:

  Observable<List<Item>> db = getItemsFromDbById(id) .filter(items -> items != null && items.size() > 0); 

Es una contradicción a sí mismo porque devuelve los elementos de la consulta de base de datos única y el nombre db – como si la base de datos (o su referencia) en sí. Desde este punto está claro que el código que usted proporcionó no puede ser ayudado.

Hay muchas plantillas java disponibles del patrón del repositorio. Por ejemplo: https://www.bignerdranch.com/blog/the-rxjava-repository-pattern/

Si eso no ayudó lo suficiente tratar de proporcionar código que hace por lo menos distante lo que está describiendo.

  • Uso de Mockito con Retrofit 2.0
  • RxJava solicitudes de red y almacenamiento en caché
  • Inter fragmento de comunicación utilizando rxjava
  • Okhttp ignora la configuración de Dispatcher cuando se usa con Retrofit RxJavaCallAdapterFactory
  • ¿Cómo devolver el valor con RxJava?
  • Filtrar lista de objetos en Rxjava
  • Obtenga el valor actual de RxJava Observable
  • Retrofit no puede crear adaptador de llamada
  • ¿Cómo obtener la url de la solicitud en retrofit 2.0 con rxjava?
  • Usando observeOn () el hilo de interfaz de usuario de Android bloquea mi prueba de emulador
  • Si se realiza la llamada onComplete para un Asunto RxJava, ¿tengo que anular la suscripción manualmente de nuevo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.