Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android : How to OnConflictStrategy.REPLACE but preserve one particular field

I have a DAO in Android Room, with OnConflictStrategy.REPLACE on insert, there's a boolean field downloaded, which gets changed to true if this object was downloaded by the user, I want to replace the whole object onConflict, but preserve the state of this field(downloaded) in the db.

public interface DAOTemplate<T> {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    @NonNull
    void insert(T... messages);

    @Delete
    void delete(T message);

    @Update
    void update(T message);
}
like image 216
Relm Avatar asked Jan 30 '18 09:01

Relm


1 Answers

A bit late for the answer but I just did the same in my code. Your approach should be not to replace the object but update the existing one with the fields you need to update and just keep the downloaded.

For this use OnConflictStrategy.FAIL. Surround your insert() with try/catch block and then in catch put your update() call. I am using RXJava + Kotlin to so but you can implement this logic with any other async approach.

fun saveItem(item: Item): Single<Unit>? =
            Single.fromCallable {
                try {
                    dao.save(item)
                } catch (exception: SQLiteConstraintException) {
                    dao.updateModel(item.id)
                } catch (throwable: Throwable) {
                    dao.updateModel(item.id)
                }
            }.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())

And in DAO I am implementing update as follows:

@Query("UPDATE name_of_your_table SET quantity = quantity + 1 WHERE id = :id")
fun updateModel(id: String)

Here I am increasing the quantity but you can pass fields to update as params and use SET to set all fields you need to update.

like image 74
Rainmaker Avatar answered Oct 19 '22 08:10

Rainmaker