带有Flowable的房间:如果数据库为空,则初始化数据库 [英] Room with Flowable: initialize database if it's empty

查看:797
本文介绍了带有Flowable的房间:如果数据库为空,则初始化数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下@Dao,它提供Flowable<User>流:

@Dao
interface UsersDao {
  @Query("SELECT * FROM users")
  fun loadUsers(): Flowable<List<User>>
}

我希望流的订户在那里发生某些更改时立即接收数据库的更新.订阅Room的Flowable,我将立即获得该功能.

I want the subscriber of the stream to receive updates of the database as soon as some change happens there. Subscribing to Room's Flowable I will get that feature out of the box.

我想要的是:如果数据库为空,我想执行一个Web请求并将用户保存到数据库中.订户将自动接收刚刚发生的新更新.

What I want is following: if database is empty I want to perform a web request and save users into database. The subscriber will automatically receive new updates that had just happened.

现在,我希望存储库的客户端不知道所有初始化逻辑:他所做的一切-他执行usersRepository.loadUsers().所有这些魔术都应该在存储库类中进行:

Now I want the client of the repository not to be aware all of the initialization logics: all he does - he performs usersRepository.loadUsers(). And all of these magic should take place inside the repository class:

class UsersRepository @Inject constructor(
    private val api: Api,
    private val db: UsersDao
) {

  fun loadUsers(): Flowable<List<User>> {
    ...
  }
}

我当然可以使用以下方法:

Of course I can use following approach:

fun loadUsers(): Flowable<List<User>> {
  return db.loadTables()
      .doOnSubscribe {
        if (db.getCount() == 0) {
          val list = api.getTables().blockingGet()
          db.insert(list)
        }
      }
}

但是我想在不使用副作用(doOn...运算符)的情况下构造流.我已经尝试过> c5> ,但这并没有太大帮助.坚持了一段时间.

But I would like to construct the stream without using side-effects (doOn... operators). I've tried composing() but that didn't help much. Been stuck on this for a while.

推荐答案

您可以应用一些有条件的flatMap:

You could apply some conditional flatMaps:

@Dao
interface UsersDao {
    @Query("SELECT * FROM users")
    fun loadUsers(): Flowable<List<User>>

    @Query("SELECT COUNT(1) FROM users")
    fun userCount() : Flowable<List<Integer>>

    @Insert // I don't know Room btw.
    fun insertUsers(List<User> users) : Flowable<Object>
}

interface RemoteUsers {
     fun getUsers() : Flowable<List<User>>
}

fun getUsers() : Flowable<List<User>> {
     return
         db.userCount()
         .take(1)
         .flatMap({ counts ->
             if (counts.isEmpty() || counts.get(0) == 0) {
                 return remote.getUsers()
                        .flatMap({ users -> db.insertUsers(users) })
                        .ignoreElements()
                        .andThen(db.loadUsers())
             }
             return db.loadUsers()
         })
}

免责声明:我不知道Room,所以请在允许的情况下修改上面的示例.

Disclaimer: I don't know Room so please adapt the example above as the features of it allow.

这篇关于带有Flowable的房间:如果数据库为空,则初始化数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆