0

In my app i have a simple Room DataBase with methods like update, insert, delete, and insertOrUpdate which check if same item with primary key exist and just sum it's quantity with new quantity.

The data till now was added by user input, but now the user will be ever able to Sync the data from a remote server, so i've made an API which return the same array of objects as my table is structured, i've done all to get the list in the correct object class but now which would be the best way to use my insertOrUpdate function on that List of objects? should i loop throw each item and add it one by one?

Which would be the best solution to do it?

Here is my code of the DAO:

@Dao
interface ArticoliDAO {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(articolo: Articolo)

    @Update
    suspend fun update(articolo: Articolo)

    @Query("SELECT * FROM articoli_letti_table WHERE barcode = :key")
    suspend fun get(key: String): Articolo?

    @Query("UPDATE articoli_letti_table SET qta = qta + :qta WHERE barcode = :barcode")
    suspend fun updateQuantity(qta: Int, barcode: String)

    suspend fun insertOrUpdate(articolo: Articolo) {
        val itemFromDB = get(articolo.barcode)
        if (itemFromDB == null) {
            insert(articolo)
        }else {
            updateQuantity(articolo.qta, articolo.barcode)
        }

    }

    @Query("DELETE FROM articoli_letti_table WHERE barcode = :key")
    suspend fun delete(key: String)

    @Query("DELETE FROM articoli_letti_table")
    suspend fun clear()

    @Query("SELECT * FROM articoli_letti_table")
    fun getAll(): Flow<List<Articolo>>

}

And here is my code from SettingActivity where the user can press the button "Sync" where all items from the server should be added to the database:

override fun onPreferenceTreeClick(preference: Preference?): Boolean {
    val key = preference?.key

    return when (key) {
        "sync" -> {
            val moshi = Moshi.Builder()
                .add(KotlinJsonAdapterFactory())
                .build()
            val retrofit = Retrofit.Builder()
                .baseUrl("http://192.168.100.65/VisualIntelligence/")
                .addConverterFactory(MoshiConverterFactory.create(moshi))
                .build()
            val service = retrofit.create(ArticoliService::class.java)
            val call = service.getArticoli()
            call.enqueue(object : Callback<List<Articolo>> {
                override fun onResponse(
                    call: Call<List<Articolo>>,
                    response: Response<List<Articolo>>
                ) {
                    if (response.code() == 200) {

                    }
                }

                override fun onFailure(call: Call<List<Articolo>>, t: Throwable) {
                    Log.e("ERR", t.message.toString())
                }

            })

            Snackbar.make(requireView(), "Sincronizzo gli articoli...", Snackbar.LENGTH_LONG).show()
            true
        }
        else -> true
    }
}
2
  • If you can insert it as List why do you want to insert them one by one? anyway whats your problem? Commented Jan 27, 2021 at 8:57
  • So i just should create a function in DAO where i pass in @Insert the entire list? the problem anyway will be that i should use insertOrUpdate as if the same item with it's code exist i have to sum it's old quantity with new Commented Jan 27, 2021 at 9:04

2 Answers 2

2

You can directly create insertAll method with list as parameter

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(articolo: List<Articolo>)

Then, just call this in onSuccess of your request

if (response.code() == 200) {
     articoloDao.insertAll(response.body())
}
Sign up to request clarification or add additional context in comments.

3 Comments

Hi rajan, by doing so on conflict it will replace the items while i would use my insertOrUpdate which will get the duplicate value and will sum it's quantity
I guess in this case, you just need to iterate through each item, check if it already exists , if yes update or insert new record
@IgorMytyuk can you tell me the difference between replace and update, if you update then the field values which does not match will change, in the case of replacing the entire row will be replaced. In the end, the result will be the same. You will have the same values for fields of the row you updated or replaced.
0

Either you loop the list here and insert your object one by one, or you create an adapter to handle inserting list for the DB, then loop and insert one by one over there.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.