I have a Room table of objects and when I get my network call to refresh the list of objects the items could have been changed. So I need to remove any data that is no longer in the new fetched list.
Pre-Fetch Ids in Table:
|ObjectId|
|:-------|
|1|
|2|
|3|
|4|
Post-Fetch Ids in Table:
|ObjectId|
|:-------|
|1|
|2|
|4|
So Objects removed:
|ObjectId|
|:-------|
|3|
My Quesiton: Is the best way to do this just Delete all entries in the table before calling an #insert method or is there another way using the #update that will allow me to simply fetch the new data and remove all the old data that is no longer in the new list of objects? My understanding is that an #update will simply update objects 1,2 & 4 and leave 3 as it was.
As you have a list of id's (assuming these uniquely identify the rows) then you could update according to the list and delete (before or after the updates) according to the list using a WHERE clause that utilises NOT IN operator(s)
Note that the deletion should be done via an #Query not #Delete e.g. #QUERY("DELETE FROM the_table WHERE id NOT IN(:the_id_list);"
This would minimise the number of deletions. Deletiong and Updates should be done within a single transaction.
Related
which is faster:
to delete records each one at a time
e.g. listOfObjects.forEach{ repository.delete(it.id) }
and here is the query
#Query("DELETE FROM myTable WHERE object_id=:id")
fun delete(objectId: Long)
2. to delete the whole list in a single query
e.g. repository.delete(listOfObjectIds)
and here is the query
#Query("DELETE FROM myTable WHERE object_id=:id in(:objectIds)")
fun delete(ObjectIds: List<Long>)
?
By far, the second list version will outperform the first version, which issues N delete statements for a list of size N. The main reason is that the second version requires only one round trip to and from your SQLite database, while the first version requires N trips.
In addition, the second version has the added benefit that your entire logical delete operation can execute within a single transaction. The first version would, by default, execute across multiple transactions. This could lead to potential problems should, for example, an exception occur halfway through the batch of single delete operations.
When I try to add multiple records, via
#Insert(onConflict = OnConflictStrategy.IGNORE)
void insertAll(List<T> obj);
if one of the records has unique constraint error, it fails to insert the other record in the list as well.
Can't use the REPLACE on conflict, because it will cascade my previously created related table records.
I just need to insert multiple records, and if something is repeated, ignore that only. And keep adding the other records in the List.
There was a different issue. When I looked for MyTableDao_Impl.java, I realised, for each record in the list, there is a different insert transaction.
And OnConflictStrategy.IGNORE ignores the current transaction only. So clearly this can't be the issue.
I have table that for the specified rows with specified ids need to change the value, while for previously selected rows should be reset.
Do I need to reset the whole table and then update for specified rows. is there any option to update table with only one query.
I'm using room persistence on android
Like any database standard, Room Update and Delete are separate operation types.
Then maybe you can try to execute Trigger if you need mixed operation (thread about trigger).
But for what reason do you have to execute this two operations in a same query ?
I'm using Android Room to load data.
my query is this:
#Query("SELECT * FROM TrackedItem where isArchived = 0 ORDER BY creationDate DESC")
Flowable<List<TrackedItem>> getAll();
When calling getAll() I get all the items at the first time.
Then, I'm updating all the items using a network request.
What happens is that if I have 100 items, the getAll() will emit 100 times the entire list, which will update the RecyclerView 100 times.
Best practice for getting a single item that was changed and calling notifyItemChanged?
Thanks.
Answering my own question, if someone gets the same issue.
Instead of saving each item after an update, I save all of them once
calling #Insert with (TrackedItem... items).
which will only emits one update.
I already have a SQLite Database setup which I am using as cache for the Android application. The application does a HTTP Request and gets back a List of objects which I can insert into the db. After the first request, if I do anymore requests, how do all of the following in a better way:
1) insert all new objects from the list
2) update all objects that were already in the db
3) delete all rows that were not there in the latest list of objects.
I know that options 1 and 2 can be done using the "INSERT OR UPDATE" query. How can I manage the 3rd option efficiently?
Right now my approach is to delete all from table and then insert all. But that isn't very efficient. Any ideas how to improve it?
For that you can use the ids of the rows. For doing that first retrieve all the rows which you want to delete using SELECT query and add it a temporary arraylist, then use for loop over the arraylist to delete all those rows by using DELETE query.
You should do your operations using the applyBatch() method of the ContentProvider (http://developer.android.com/reference/android/content/ContentProvider.html#applyBatch(java.util.ArrayList)).
You can perform this method in a separate thread asynchronously so that you do not block anything else. You will have to create a list of ContentProviderOperations. In fact, you only need to specify the ones you need to insert or update within the ArrayList and implement the applyBatch() method such that it will automatically delete the rest of the entries in the database.
To answer your question about how to delete the entries not in the table, the logical assumption would be to search through your data sequentially and then delete the ones that do not need to exist.
I guess the intention is to refresh the Http request result set saved in the database. So I think the most efficient way is do a transaction or batch operation to delete all rows from the table first and then insert the new rows. A transaction might be better so that the result rows are either all new or all old, but not mixed.