Android Architecture Components - Remove old data from room

Viewed 4073

Currently I'm working on Android app architecture, i can't understand one thing in Github Repo Sample; We can decide to fetch new data using rate limiter or null checking, but in this case we just insert new values in to database, we are not deleting old values from database. For example what if one of the old results in database removed from server (user deleted repo) ? It will be still in database? How can we eliminate this values? Am i missing something or is this an unhandled case?

2 Answers

I think I have an optimized and simpler solution. Please, help make it even simpler!

// Dao class

@Dao
public interface UserDao {
    // ...    

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(List<User> users);

    @Query("DELETE FROM User WHERE User.id NOT IN(:lstIDUsers)")
    void deleteOldUsers(List<Integer> lstIDUsers);
}  

// File that calls Dao - example: Repository class)

// First, convert and add all Json data to lstUsers

// Second, add only Json primary key elements 
// from lstUsers to a new list lstIDUsers

userDao.insertAll(lstUsers);
userDao.deleteOldUsers(lstIDUsers);

These two commands first insert all elements with OnConflictStrategy.REPLACE, and after delete only old elements removed from remote or local DB.

Okey i came with a solution;

this is example entity,

@Entity
data class User(
        @PrimaryKey val uid : Int, 
        val name : String, 
        val createdTime : Long = System.currentTimeMillis()
)

and below is example json taken from https://jsonplaceholder.typicode.com and reformated.

private val userJson = "[{\"uid\": 1,\"name\": \"Leanne Graham\"},{\"uid\": 2,\"name\": \" Graham\"},{\"uid\": 3,\"name\": \"Y Graham\"},{\"uid\": 4,\"name\": \"Lea\"}]"

by using https://github.com/FasterXML/jackson-module-kotlin you can deserialize json formatted data easily into data classes in kotlin. Differently from gson library, jakson supports default values so you can set a created time which is current milliseconds. And below is UserDao

@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUser(user : User)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUsers(user : List<User>)

    @Query("SELECT * FROM user")
    fun getUsers() : List<User>

    @Delete()
    fun deleteOldUsers(users : List<User>)

than you can get all users with getUser() method and filter them as old and fresh. Than you should delete old ones from database. And if freshUsers is not empty use it, if is empty make a new network request.

val expireTime = TimeUnit.HOURS.toMillis(1)
val userList = App.database.userDao().getUsers()
val freshUsers = userList.filter { it.createdTime > System.currentTimeMillis() - expireTime}
val oldUsers = userList.filter { it.createdTime < System.currentTimeMillis() - expireTime}
App.database.userDao().deleteOldUsers(oldUsers)

This solution working for me. But i'm glad to listen your solutions too.

Related