Android room database is not inserting data in db immediately - android

I was using room in my android project, everything was working fine until one day I found Room doesn't insert data in db immediately.
How I reproduced it
When I run command appdatabase.getUserDao().insert(user) and after 2 seconds when i remove my battery from my phone and export db after that What I found is data is not inserted in db. that is 100% sure because my team has reproduced it multiple times. it seems instead of directly store into db it caches data for some time.
Is there any solution for it Where data will directly store in db instead it caches?

Yes, close the database before exporting:
RoomDatabase.close()
Make sure it is the
Room.databaseBuilder()
and not
Room.inMemoryDatabaseBuilder()
Check if the thread is executing properly and that you are not interrupting a #Transaction insert

Related

Android: Migrating from legacy SQLite to Room database using attach

I'm working on an Android app where we need to migrate from some legacy SQLite code to a Room based implementation. But I've run into a couple of issues & I'm not sure how to solve them.
Environment:
Android 6.0+
SQLite implementation is in one database file
Room implementation is in a separate database file
Both will be in /data/user/0/.../databases/
What sorta works, but is slow:
We have a working test implementation to pull all the legacy SQLite tables' data into Kotlin objects, then do inserts into the Room based tables. But, it's fairly slow for our test cases (about 70 secs for 10k+ rows in at least one table). Real life cases could top 100k rows in at least one table. As far as I can tell, the select is one transaction and the inserts are wrapped in a transaction. So, I don't think it's transaction overhead slowing us down.
What we want to make work:
What I'm hoping to do is use SQLite's attach database and detach commands to load the legacy SQLite database into a Room DB connection. Then, I can do an insert into new_table.table_name select * from old_table.table_name. The actual SQL will be slightly different due to slight schema changes. But, the insert-select pattern will be the basic idea.
I'm using ContextWrapper to get the full database path for the legacy database file. That works fine.
What issues I'm seeing:
When I try to do the attach command, though, I was getting an IllegalStateException with something about not being able to enable/disable write-ahead logging while in a transaction or the db is open. But, the legacy DB is not open or in a transaction at that point.
So, I modified the approach to set the journal mode to TRUNCATE in the Room db connection setup. That allowed me to do the attach command. And the insert-select query seems to work as far as I can tell (I haven't fully tested that yet). BUT, when I tried the detach command, I got a SQLite 1 error about the database being locked.
For reference, my basic code for both above attach approaches is:
roomDb.execSQL("attach database '$fullLegacyDbPath' as old_db")
roomDb.execSQL($insertSelectQuery) // the "INSERT INTO ... SELECT ..." query
roomDb.execSQL("detach old_db")
Any ideas how I make this work (preferably without setting the journal mode to truncate)?

Updating/Maintaining SQLite database after each App Release Xamarin Forms

This is my first time working on a Xamarin App and I am new to the app development world so I need some help figuring out this process.
Currently I run a php web service that generates some SQL files that I run in DB Browser and I get a database file which I then put into my Assets and Resources Folder. Using each platform's API I copy the database into a writable folder and use that to run my queries.
I followed this really helpful tutorial and it worked perfectly fine.
https://medium.com/#hameedkunkanoor/creating-a-sqlite-databse-and-storing-your-data-in-your-android-and-ios-application-in-xamarin-2ebaa79cdff0 .
After the "initial" setup I store a timestamp in a local table and and the next time the user opens the app I pass that timestamp and retrieve data that is older than that timestamp. The I update that timestamp and continue the process. That data is sent back in JSON format and make the updates to the tables.
My only concern is if a new version were to come out where I add a new table or a new column which is not present in the current version of my Database, how should I take care of those update Web Service calls? Is there a way of monitoring my DB version? I read somewhere where I could just ignore the new data that is not present already, like table or columns, but I'm not really sure how to do that.
I also saw that if I call CreateTable on my current tables I could potentially update them?
Also for future reference each time I develop a new app would I need to regenerate a new database file to store in the assets/resources folder? Is there a more automated process for this? Along with monitoring the version of my database?
Any Help/Tutorials/Suggestions would be greatly appreciated.
You have to remember that CreateTable it's already doing the columns update for you, because internally it calls a method called MigrateTable which you can see here for further clarification: https://github.com/praeclarum/sqlite-net/blob/master/src/SQLite.cs#L562.
However you could have to handle more advanced modification to your database, like adding triggers or something similar.
In that case i suggest you to perform modifications manually.
In Xamarin Forms i've ended up with this:
https://gist.github.com/matpag/b2545cc22c8e22449cd7eaf6b4910396
Could not be the best strategy ever but seems to work for me.
Summarizing :
You have to save the database version in an internal flag of the SQlite database called user_version accessible with PRAGMA keyword.
Every time you get the database connection, you have to perform a check and see if the current database version is the same as the app last database version.
If not you need to perform a database update and set the new current version.
Reference here.

Change or reset prepackaged database in DBFlow

I am a beginner in android programming, I created an android app which uses an exist DB with DBFlow. At first time I inserted a temp data to database so I can test the app. When I finished building the app I inserted real data and copied the new database -which is similar to the old one except for the real data- to assets folder but I did not find the new data.
How can I reset the database or change the data.
After changing database you must remove previous version of app from your device and then install the app again. This should solve your problem.

One time insert, multiple reads into SQLite Android app

I know there are similar responses so I am going to make this very succinct. I am planning on developing an app which has 18 chapters and each chapter has 30 or 40 hymns. Now, Im planning on using an SQLite command, insert each hymn individually but after the insert, and after the APK file is generated, would the data on the database still be present? Or Does it need to inserted in on each install? What are my options?
If you use sqlite database for you app...every time the app is installed.. new database will be created(of course the old one will be deleted).. and so the hymns will be inserted on each install..(but once you install.. on running your app wont create new database and insertions..).. hope this is clear..
I am not Clear with your question..but if you r inserting data through your code..than on each installation your records would be inserted once..if you provide condition to do so for only once.
You have to code the insertion of the hymns at the start/launch of the application, so that the database is ready for retrieval for the application. But the next time, the application is started, check whether your database exists and has the hyms (size of database), if yes, dont populate the database again, if no, populate it. I hope you want to read from a file/array and insert the records to the database.Once you insert the records to the database, they are available for the reference until the application is uninstalled or the database is re-created. Sqlite database is a persistent storage. Now, Im planning on using an SQLite command, insert each hymn individually but after the insert, and after the APK file is generated, would the data on the database still be present? Yes it would be present. Once the application is installed, the code of database would be executed and the database would be created.
My suggestion to you is use the XML parsing to show the Hymens in place of sqllite. Simply create the xml file with the hymen tag then get the tag and show the data on screen.

Change SQLite Database Version Number

I have a database that I built in SQLite browser, and it works fine. I launched an app with a prebuilt database and now I want to add more tables and data to that database.
I can get the app to launch the onUpgrade() method of the SQLiteOpenHelper. But the problem is, it's doing that EVERY time I use the helper.
I have it localized to, only on app launch, separating the upgrade command from the helper I used to retrieve data, but this is still a problem.
I have figured it out though, as I have been using the same database on my computer (the one that I'm editing) since version 1. So, whenever it writes the newer database onto the SD card it's showing version 1 even though I should be up to version 4 by now.
So, my question is, how can I manually edit the database version of the original database so that when it updates it isn't writing the old version number over the new one?
To manually update the version to 4 you execute the following SQL statement:
PRAGMA user_version = 4
Another way to change the version of your Sqlite Database. You can use DB Browser for SQLite:
Open the database file with "DB Browser for SQLite".
Change the "User Version" number to whatever number you want
Click the "Save" button
You can also set it via the setVersion SqlLiteDatabase method.
Source: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#setVersion(int)

Categories

Resources