11

In official Guide to App Architecture is an exaple of repository. There is a check if an object is existing in database and if is fresh:

// check if user was fetched recently
boolean userExists = userDao.hasUser(FRESH_TIMEOUT);

Any ideas how to implement that functionality (hasUser) for DAO?

Francis
  • 6,788
  • 5
  • 47
  • 64

3 Answers3

7

Most Architecture Components examples are available here. In your case, I couldn't find the UserDao class but there is a database schema sample here. users table has a last_update column. So you could write UserDao like this :

@Query("SELECT COUNT(*) FROM users WHERE userId == :userId AND last_update >= :timeout)
int hasUser(int userId, long timeout)

It returns 0 if the user with id userId is not fresh enough.

Community
  • 1
  • 1
Nym1412
  • 171
  • 1
  • 5
  • I see, thanks. But how to implement the update of that value in DAO? I'm tempted to create [Extension](https://kotlinlang.org/docs/reference/extensions.html) of a generated `@Insert` class – Francis Jun 18 '18 at 13:55
  • For insertions, you can define the table like this : `last_update DATETIME DEFAULT CURRENT_TIMESTAMP`. For updates, I would update User.last_update in every setter maybe before calling dao. (Edit : cleaned. sorry, cat intrusion on my keyboard :D) – Nym1412 Jun 18 '18 at 17:54
1

You should add an extra field to your table, like COLUMN_LAST_FETCHED with a date and after each interrogation, update that field with a timestamp.

Cătălin Florescu
  • 5,012
  • 1
  • 25
  • 36
0

Consider using the RateLimiter class as shown here in the android-architecture-components GitHub project for a non-persistent way of checking if the data was recently fetched :

@Singleton 
@OpenForTesting 
class RepoRepository @Inject constructor(
    private val appExecutors: AppExecutors,
    private val db: GithubDb,
    private val repoDao: RepoDao,
    private val githubService: GithubService ) {

    private val repoListRateLimit = RateLimiter<String>(10, TimeUnit.MINUTES)

    fun loadRepos(owner: String): LiveData<Resource<List<Repo>>> {
        return object : NetworkBoundResource<List<Repo>, List<Repo>>(appExecutors) {
            override fun saveCallResult(item: List<Repo>) {
                repoDao.insertRepos(item)
            }

            override fun shouldFetch(data: List<Repo>?): Boolean {
                return data == null || data.isEmpty() || repoListRateLimit.shouldFetch(owner)
            }

            override fun loadFromDb() = repoDao.loadRepositories(owner)

            override fun createCall() = githubService.getRepos(owner)

            override fun onFetchFailed() {
                repoListRateLimit.reset(owner)
            }
        }.asLiveData()
    }

    // Details omitted for brevity.
}
maxbeaudoin
  • 6,546
  • 5
  • 38
  • 53