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.
Related
My Android App use SQLite database as an asset.
I deliver a .db file in /assets directory to provide both read-only tables and read/write tables.
When the user uses the App, it's datas are stored in read/write tables.
Sometimes I need to modify the schema of the database by adding a column in a table for example.
So I need to deliver a new .db file in the release.
If i do this the problem is that the user loses his data.
Is there a way to export/import the user data when he updates the App on his devise ?
I didn't find anything about this issue on the Web.
The standard way of handling this is, assuming that you are using (extending) the SQLiteOpenHelper class, is to utilise the version number in conjunction with overriding the onUpgrade method to ALTER the schema of the existing database, thus retaining the existing data.
version int: number of the database (starting at 1); if the database is older, onUpgrade(SQLiteDatabase, int, int) will be used to upgrade the database; if the database is newer, onDowngrade(SQLiteDatabase, int, int) will be used to downgrade the database
The SQLiteOpenHelper (or if using SQliteAssetHelper which extends SQLiteOPenHelper), when opening the database (if it exists) compares the coded version number against the version number stored in the header of the database. If the coded version number is greater than the stored version number then the onUpgrade method is called which is passed three parameters,
the SQLiteDatabase
the old (stored) version number as an int
the new (coded) version number as an int
You would typically check old and new and have code that makes the changes (ALTER TABLE or an alternative if the limitations of the ALTER TABLE force to do something like rename the original table, CREATE the changed table with the correct name, copy the existing data from the original table to the new table and finally DROP the renamed original table )
If the App is installed for a new user then that is when the asset will be copied. Thus covering both scenarios.
If not using an extension of SQLiteOpenHelper, then you can mimic using the stored version number by reading 4 bytes at offset 60 and comparing this to a coded version or even by copying the asset and getting the asset's version number, which would be managed with whatever tool you use to maintain the asset (e.g. via the user_version PRAGMA)
SQLite Database Header
I want to update my app at play store with bug fixes. APP already uses Room DB. Do i need to migrate the DB. There is no change in the DB. There are only UI changes. Does new version effect the people DB, who are already using it. Can someone provide the details about this.
Thanks in advance.
There is no change in the DB.
The database remains and you do not need to change the version of the database (as per the #Database( .... version=?)).
You only need to change (increase) the database version if the schema has changed.
If you increase the version number and do not have a migration (migration class to call) to cover that version, then an IllegalStateException will occur unless you have .fallbackToDestructiveMigration() which WILL delete and recreate the database (effectively empty the database with the ne schema).
You can also use fallbackToDestructiveMigrationFrom()
It is the version number that determines if a database migration is required. However, if a change is made and if any of the entities mismatch the database when the .build method is run then an exception will result.
If you change an Entity (the schema) and do not increase the version number you will get an IllegalStateException with the message starting with Room cannot verify the data integrity. This is because the hash stored in the room_master_table has changed.
If you changed the database schema outside of room then you'd get an exception indicating that the expected schema (the database according to the Entities) does not match the schema found (the database according to the actual database).
In your situation I'd suggest not changing the version number.
You may wish to have a look at:-
Migrating Room Databases
#Database
fallbackToDestructiveMigration
fallbackToDestructiveMigrationFrom
I currently use a sqlite database for an application in both iOS and Android. I don't wish to move onto CoreData or JSON at present for this application as it works perfectly well with the sqlite database.
However I would like to update one of the tables in the database on my next update.
I presumed this would be something that many people would do but interestingly I've tried searching for answers but getting no results.
So my question is two-fold:
1) Is it possible to replace a table within a sqlite database?
2) If so, how does one go about doing this?
I have no code to share as I can't determine how to even start.
Thanks in advance
1) Is it possible to replace a table within a sqlite database?
Yes.
2) If so, how does one go about doing this?
You utilise a means of detecting that a change (an upgrade) is required.
On Android if using a subclass of SQLiteOpenHelper then you increase the version number (4th parameter of the super call), in which case the onUpgrade method runs, so you override the onUpgrade method to handle the update to the table(s).
This utilises the user_version field that is stored in the database's header. In short the SQliteOpenHelper when opening the databases compares the value in the header with the value passed as the 4th parameter. If the passed value is greater than the header value onUpgrade is called. If the values are the same then no such call is made. If the passed value is lower than the value in the header then onDownGrade is called which unless coded results in an exception. (typically onDowngrade is not utilised)
On IOS you could replicate this methodology of comparing a value stored in the user_version extracted via PRAGMA user_version and set via the PRAGMA user_version = ? against a value that indicates a newer version when applicable (i.e. that is not stored in the database). This isn't the only solution
The link above has a brief description which includes a link in relation to SQLite's ALTER TABLE, that itself explains the limitations of the ALTER TABLE command and has a section that covers alternative solutions. This would apply to both IOS and Android.
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.
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().