I've got an Android app I'm about ready to release, and I'm reviewing some of my code. I'm worried about my implementation for my SQLiteOpenHelper. Specifically, I want to verify what the oldVersion and newVersion reference in the onUpgrade method. Is this based upon the versionCode in my AndroidManifest.xml? Or is this value something completely separate, specific to the database? If it's the latter, how does the database determine the version?
Is this based upon the versionCode in my AndroidManifest.xml?
Not normally, unless you upgrade your schema every time you publish an upgrade to your app, and even then the "based upon" would be mostly coincidental.
Or is this value something completely separate, specific to the database?
Yes. You increment the version every time you have a new database schema.
If it's the latter, how does the database determine the version?
On every onCreate() and onUpgrade(), Android sticks the then-new version of the database schema in a metadata table in the database. That's what Android then checks when you use your helper in the future, comparing that stored value to the one you provide in your SQLiteOpenHelper constructor.
while you solved your question, that you can determine it just yourself on creation. I want to leave this for persons wondering:
how does the database determine the version..
.. if the database already exists?
it is stored with the db file and accessible via PRAGMA user_version; as noted in SQLiteOpenHelper.java:getVersion().
Related
Should I increment the value of the Room database version if I change the content of the database when its migration strategy is set to "fallback to destructive migration"?
Following changes made to database:
Some columns are removed.
Content of some rows is updated in the database file that is stored in assets.
Yes. You should update the version of the database even with fallback to destructive migration strategy. Room uniquely identifies every database version with an "identity hash string", which is kept in a configuration table.
Keeping the database version unchanged will cause the app to crash with an IllegalStateException. Internally Room checks the identity of the database comparing the identity hash of the current version vs the the one stored in the table called "room_master_table".
You can learn more about this in the below article which also explains in detail how to handle version change and testing.
Reference: https://medium.com/androiddevelopers/understanding-migrations-with-room-f01e04b07929
UPDATE: It is interesting that the app crashed in some users, but for some users including me, it didn't crash. So it's better to update the version of the database even though its migration strategy is fallback to destructive.
From my experience, it seems we don't have to increment the value of Room database version when its migration strategy is set to "fallback to destructive migration".
I changed the content of the database and removed some columns from the database file.
Then I installed the previous version of the app (unchanged database). Then I used the application and made sure a database instance is created.
Then I installed the new version of the app (changed database). And it didn't crash and everything worked fine. Changes applied to the database.
I would like to know if it is possible to recover the old database data after upgrading to new database version of Android SQLite?
Thank you.
You cannot get the previous version database data because now it is upgraded.
You can take backup of each version before doing upgrade
Refer this :
Backup/restore sqlite db in android
Not if any of the old data has been changed (unless you can easily determine what has been changed and you can undo the changes).
It is possible to change the version number back using PRAGMA user_version = ?, where ? is an integer representing the version number to be changed to. This literally only changes that value (Offset 60 in the DB header). user_version pragma. If changing the the actual stored version number, then you would have to consider the coded version number as used by the super call, if they differ then onUpgrade or onDownGrade would be called. That is the value as stored in the DB header is compared to the value provided in the code by the super call.
You could alternatively change the version number passed to the Database Helper (subclass of SQLiteOpenHelper) BUT this would result in an exception unless the onDownGrade method was Overridden.
However, this method is not abstract, so it is not mandatory for a
customer to implement it. If not overridden, default implementation
will reject downgrade and throws SQLiteException. onDowngrade
The version number, as stored in the database, has no influence itself over the data. It's really a convenience value and it just so happens that SQLiteOpenHelper makes use of the value.
The database itself is just a file to back it up you just copy the file to restore it you basically copy it back. However, implementing backup and restore will only be of use after it has been implemented.
I am creating a simple application that uses a database derived from db = SQLiteDatabase.openOrCreateDatabase(...). Now, when I create it I use db.setVersion(1);
And I read somewhere that I have to change the database version each time I change it. Now I can't find the particular tutorial where I read this, so I am left with some questions.
1)What is the reason behind versioning of a database? What is a practical purpose?
2)When exactly should the version be updated? After every insert? Every additional table added?
3)Will I be in trouble if I don't update the versions after 1? What would it lead to?
1)Versioning the database is really versioning your schema. This allows you to know when the schema is changed so you can convert it.
2)Whenever you change the schema.
3)If you change the schema, you won't know which one is being used and will end up with exceptions. If you never change the schema, nothing will happen.
And you shouldn't be manually calling setVersion. It already knows the version for an existing one, and you pass in the version elsewhere if its a new database.
The SQLite Database Version In Android is only neccessary if you manage database creation and version updates with the SQLiteOpenHelper.
SQLiteOpenHelper takes care of
opening the database if it exists,
creating it if it does not exis,
upgrading its schema if necessary
sets the SQLite Database Version.
The databaseverionnumber is set in the SQLiteDatabase-constructor.
Your example SQLiteDatabase.openOrCreateDatabase(...) does not use SQLiteOpenHelper so in this case there is no need set the dbversion.
In my android app, I was using a standard SQLite database with a helper class that had 1 table with 3 columns. In the most recent update I had to add another column of to the table, but some users have reported crashes, which (judging by the stack trace) I think comes from the new version trying to read from a column that does not exist because the data is from the old version. How can I protect the users' data between updates short of a manual backup and restore?
Here is the link to the complete updated database class:
https://github.com/cjbrooks12/scripturememory/blob/working/src/com/caseybrooks/scripturememory/databases/VersesDatabase.java
SQLiteOpenHelper will handle the database versioning, you will just have to provide it with proper database version numbers and overridden callbacks. Looking at your code:
Your DB_VERSION is 1. When you change the database schema between released versions, you should increment this number. The version number is stored in the database file, and if the version provided in code is different from the one stored in file, onUpgrade() or onDowngrade() will be called accordingly. In your case, since the database file already exists, no onCreate() was called and since the version numbers matched, no upgrade was performed.
Your onUpgrade() drops the table and then recreates it. In some cases this might be ok, say, it's just a cached copy of data stored elsewhere, but usually as a user, I don't want an app upgrade to delete my data. Implement onUpgrade() so that it does the necessary schema modifications while preserving data. Some generic strategies for this:
If it's just adding some columns ALTER TABLE and put some suitable default values.
If it's more complex schema change, rename the old tables to temporary names, create new tables and then migrate data from the temp tables.
In any case, after onUpgrade() the database schema should be in the same shape it would be if onCreate() was called to create a new database, but with existing data preserved.
Please forgive me if this question has been answered - I searched and couldn't find it.
I have an Android app that I want to upgrade, and it uses a SQLite Database. I want to update some of the application logic in the app, but there will be no updates to the database schema or contents. I basically need to keep the database exactly as-is for the user.
Do I need to do anything in onUpgrade to ensure that the database is kept, or can I leave the DB stuff alone for this update?
The onUpgrade() method is used incases of version change. Which means the database stored in the phone needs to be altered or dropped or deleted and a new database to be created. As your application does not have any of these requirements you can leave the DB stuff for this update.
This related article may help you with your question.
The way that I understand it, is that you need to put your database changing code in onUpdate() if you WANT to update between versions. But since you don't intend to, and are probably keeping the database version the same, then you will most likely have no issues at all.
Upgrading will NOT interfere with SQLite. Changes to db structure will not be implemented unless you programmatically do so (in onUpgrade method) or you uninstall and reinstall your app.
As long as it is the SAME application that you are upgrading, your db will not be affected and your data will not be affected either. If you change the signing key used in building your apk, your db will be recreated.
Conversely, if you change database structure at any given point, your onUpgrade method will come into play. You will be forced to backup, drop, recreate and repopulate tables which have been changed between versions (oher tables remain untouched both in structure and in data).
NOTE: In debugging, i just uninstall and reinstall the app every time i make db changes, but in production you DONT want to do that.