I am making one android app where I am using SQLite database. I have already released one version of it and now for second and third version suppose I require to change in the database table like adding/removing fields.
So How can I handle this upgrade in Android. Here I don't want to drop the complete table like stuff, Here it should use Alter to update the tables.
Suppose user has installed my first version of my application then after few days I released next version 1.1 with changes in database table - added one field and here user did not upgrade it and meanwhile I again released the 1.2 again added one more field
So here How I could handle this situation when this user upgrade my application from Version 1 to Version 1.2, where Version 1.1 is missed and attribute which I added is also missed that can create problems.
Any solution to handle this ??
Assuming you're using SQLiteOpenHelper, just increment the database version number for any to-be-released version with database schema changes. In case there's an older database file around, your onUpgrade() will be called so you can migrate the database from any old version.
For example, if your 1.0 database version is 1, 1.1 is 2 and 1.2 is 3 and the user is updating version 1.0 to 1.2. onUpgrade() is called with oldVersion set to 1 and newVersion set to 3. From these version numbers your code can figure out what needs to be done, like:
#Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
updateFrom1To2(db);
case 2: // fall-through
updateFrom2To3(db);
break;
default:
Assert.fail("You forgot to write code for oldVersion " + oldVersion);
}
}
You can do anything you want in onUpgrade in sqldb
. You can use ALTER to add new columns to your table.
Worst case, if your schema is completely and entirely different, you'll have to create the new table, populate it using data from the old table, and then delete the old table.
In any case, onUpgrade was designed to allow for a smooth upgrade without any loss of data. It's just up to you to implement it properly.
You should put all changes in your onUpgrade method you can use this code:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "ALTER TABLE " + TABLE_SECRET + " ADD COLUMN " +
"name_of_column_to_be_added" + " INTEGER";
db.execSQL(sql);
}
for more look this
EDIT
This is a nice thought and i found one solution(not tested), you need
to check the update ,example - Check for the ALTER you have done in 1.1 in the
version 1.2 by reading the db rows or some thing , if it
is not there, you want to Alter this too with the 1.2 alter .
I usually follow a different kind of implementation to onUpgrade method to support backward compatibility in databases.
Note: Here I only show implementation to add more columns in the latest database versions.
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 1. Copy the database file to temproary file.
// 2. Drop all the old tables from db
// db.execSQL("DROP TABLE IF EXISTS " + <TABLE NAME> );
// 3. Create tables using new Schema
// this.onCreate(db);
// 4. Copy the data from temproary file to new db
// 5. Remove the temprorary file
}
It is more convenient for me to use this kind of implementation than using ALTER commands.
Related
OK, so my app is ready for full release. I want to prepare my SQLite db correctly for release. My initial development program utilized the following code for onUpgrade (SQLite db helper class).
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
Then, as I needed to update my database, I followed this tutorial to increase the revision numbers, add columns, and all worked very well. For example, my onUpgrade changed to this.
private static final String DATABASE_ALTER_ADD_VELOCITY = "ALTER TABLE walk_run_table ADD COLUMN VELOCITY_CALC REAL";
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) db.execSQL(DATABASE_ALTER_ADD_VELOCITY);
if (oldVersion < 3) db.execSQL(DATABASE_ALTER_ADD_ELEVATION);
}
Now, I'm preparing for release and want to bring my version back down to 1 (since all users will be getting a fresh install of course). Should my onUpgrade revert to "DROP TABLE IF EXISTS".... ? And then proceed with revisions as shown in the tutorial mentioned earlier? This worked well for me in development and I suspect will work well for release, but want to make sure for uploading my program to google play. Is there a better practice to prepare the SQLite db for future revisions?
It does not matter which actual version number you are using; it can go up to four billion.
And future app versions will have to increase the database version anyway; there's nothing gained by setting it to one now.
Your released app will never encounter an old database, so you can remove the code to update from older development versions.
If you do encounter a smaller version number, you have accidentally run it on a development machine, or the database file got corrupted, or someone copied a fake database into your application's storage. In all cases, the correct response is to error out.
If I have 3 different database schemas, is it possible for a user to upgrade to version 2? In other words, do I need to check for every possible combination of oldVersion and newVersion in the onUpgrade() method of my SQLiteOpenHelper subclass?
Clarification:
After I release an update with a 3rd database schema is it possible that onUpgrade() will be called with a newVersion of 2 (where the original database schema is 1 and the newest one is 3)?
It is possible for them to skip a version, but this doesn't mean you have to check for every possible combination. What I usually do is put the upgrades in their unique methods and call those methods from a switch:
private void updateTo1(){
//Code to update schema to version 1.
}
private void updateTo2(){
//Code to update schema to version 2.
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
switch(oldVersion){
case 0:
updateTo1();
case 1:
updateTo2();
}
}
This will ensure that even if they upgrade from version 0 straight to version 2, the schema will first go through version 1 making sure that it's compatible with and ready for the version 2 update.
Android Developers have to use SQL lite for Android application, that is easy, but the problem comes when we have to upgrade the database version, we have to remove old database and create new database on upgrade, so if we want to add just one column, we have to remove all user data, is there any component or source code that manage the database upgrade, so if it only need one column, just add one column, not delete all tables.
This is completely wrong
when we have to upgrade the database version, we have to remove old database and create new database on upgrade
In your onUpgrade method, it would look something like this:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String upgradeQuery = "ALTER TABLE yourtable ADD COLUMN yourcolumn TEXT";
if (oldVersion == 1 && newVersion == 2)
db.execSQL(upgradeQuery);
}
Im using ORMLite as the data persistence option in my android application. I want to ensure data backup and recovery on re-install. If i make some changes in the app logic and re-install the application the data is unchanged, but how can i handle the schema change, i the new version of app has some database schema changes how can i handle the import of user data into newer schema. Please guide me towards possible solutions i can avail.
Regards.
but how can i handle the schema change, i the new version of app has some database schema changes how can i handle the import of user data into newer schema
If I'm understanding the question, it's not about import but it is about schema updating when you install a new version of the OS. ORMLite actually has a section about that:
http://ormlite.com/docs/upgrade-schema
To quote, you need to override the onUpgrade(...) method and do something like:
abstract void onUpgrade(SQLiteDatabase database,
ConnectionSource connectionSource, int oldVersion, int newVersion) {
if (oldVersion < 2) {
// we added the age column in version 2
dao.executeRaw("ALTER TABLE `account` ADD COLUMN age INTEGER;");
}
if (oldVersion < 3) {
// we added the weight column in version 3
dao.executeRaw("ALTER TABLE `account` ADD COLUMN weight INTEGER;");
}
}
If I'm not getting your question then please edit your post and I'll add more information.
As the title says, I have a production Android app with about 1000 installs. I had to make a DB change in SQLite, up to this point the version of the SQLite DB has been set to version "1".
Hopefully I explain the code below sufficiently in the comments, this code resides in my SQLiteOpenHelper Class so the onUpgrade method is part of the Class:
// Provides an upgrade path for the DB when the apps version is updated.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// First version of the DB was 1. Logic: each if statement will
// alter the DB cumulatively based on the version code. So, if the
// newVersion was version 3, there would be two if statements, one
// for oldVersion 1 and one for oldVersion 2. oldVersion 2 will
// contain the logic for upgrading from version 2 to 3, while
// oldVersion 1 will contain a combination of alter statements
// allowing the database to upgrade from version 1 directly to
// version 3.
if (oldVersion == 1) {
db.execSQL("ALTER TABLE plans ADD COLUMN " + App.CURRENCYCODE
+ " TEXT");
Locale locale = Locale.getDefault();
ContentValues content_values = new ContentValues();
content_values.put(App.CURRENCYCODE, locale.toString());
db.update(App.DBPLANS, content_values, App.ID + " > ?", new String[] {
"0"
});
}
if (oldVersion == 2) {
// Placeholder for next database upgrade instructions.
}
}
Please let me know if there are any pitfalls here. So far, it's tested fine, though I'm very concerned about messing up my first DB upgrade. I have a 1,000 users or so, I'd hate to lose them all.
Thanks again!
When I need to update a database like this, I typically do it with a switch statement where cases fall through to one another, such as:
switch (oldVersion) {
case 1:
// update to version 2
// do _not_ break; -- fall through!
case 2:
// update to version 3
// again, do not break;
case 3:
// you're already up to date
The benefits to this is you do not end up repeating your update statements in multiple if-statements as you continue to change the database, and adding a database update requires only adding a new case statement, not updating multiple blocks of code.
There are sometimes exceptions to this, such as a column added in one version but then deleted in a future one, so you need to pay attention as you go.