Would like a bit of clarification with SQLite database's onUpgrade method - android

So I have an app with a database with one table. I am wanting to put out a big update that includes a new table in the database.
I successfully used the onUpgrade method to create the new table in the old database by doing "db.execSQL(SQL_CREATE_STRING" in the onUpgrade method.
My question might not be a great one... but it's a question I can't find the answer for.
What happens next time I upgrade the database? Before I added the table the database's version was 2, after the new table the database version is 3. What happens if later down the road I want to add yet another table? Do I leave the current "db.execSQL(SQL_CREATE_STRING" in the onUpgrade or would I have to first remove it?
The SQL_CREATE_STRING starts with "CREATE TABLE IF NOT EXISTS", so I'm assuming I could just leave it in the onUpgrade method, correct? Since if it sees the table already it already exists, it wont try to make another one.
I'm just trying to confirm this thinking.
Thanks!

The SQL_CREATE_STRING starts with "CREATE TABLE IF NOT EXISTS", so I'm assuming I could just leave it in the onUpgrade method, correct? Since if it sees the table already it already exists, it wont try to make another one.
That sounds right. However, when you start having a few more versions it might be hard to keep track of which updates are okay to run regardless and which aren't.
What I recommend doing is having each of the upgrade steps in their own methods, and executing all the ones that need to for the given upgrade call in sequence. So for example:
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
for(int i = oldVersion + 1; i < newVersion; i++) {
switch(i) {
case 2: upgradeFromv1Tov2(); break;
case 3: upgradeFromv2Tov3(); break;
...
}
}
That way if someone is updating from e.g. v1 to v3, the upgrade will run the v1->v2 then v2->v3 logic. Doing it this way means when you create each upgrade step you know exactly what state the database schema will be in (ie the version before), so you don't have to worry about interactions between all the upgrade steps at the same time.

Related

Upgrade SQLite database in Android

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.

Upgrading the SQLite Database of a Production Android App, is this Correct?

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.

Perform specific operation at the time of installing apk?

I have updated the application's database. But users who have updated the application from market will see a crash everytime app is started because new database structure is not compatible with old database. Its not good to ask them to uninstall and install the app, I need to perform an operation just for single time at the time of installation i.e. clear the old database and create new one. This should not be called everytime the app starts, only at the time of installation..or when the app starts for the first time.
I think I have clearly defined my situation, now where do I go from here? Should I bug users to uninstall and install app or its possible to do what I have asked?
Just change the version of your database and by overriding onUpgrade on your DatabaseHelper class.
private static final int DATABASE_VERSION = 2;
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion
+ ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CREATION);
onCreate(db);
}
Why don't you implement the onUpgrade() method of SQLiteOpenHelper?
This class provides useful onCreate() and onUpgrade() methods.
See here : Is the onUpgrade method ever called?
Or here : How to update table schema after an app upgrade on Android?
First of all it is really a bad idea to clear the old database and create a new one (Users will be really pissed seeing there data lost).
You should always try to upgrade the previous data with new columns and stuff. Instead of clearing the whole data, you should always try to alter the structure of tables without clearing the data.
One more thing is that you can upgrade to new database in onUpgrade() method of the DBHelper class.

add new table onUpgrade android

During an upgrade, I want to add a new table to my database, but also not lose the data from the other tables when upgrading the application. Can someone tell me, (but if you could show me some example also) of how this is done. Because I've looked through the forums but mainly there are discussions about adding a new column etc. I figured that I have to do it somehow with alter table, but I did not understand everything. If you can tell me the steps of this process I would really appreciate it. Thank u in advance.
If you just want to add a new table and not modify any of your existing tables, then you could just create the new table in your onUpgrade method. This way your existing tables will be untouched.
EDIT: Even better, add the table as usual in onCreate and then in onUpgrade you call onCreate
Try using SQLiteOpenHelper in Android. It has methods for onCreate and onUpgrade.
Sample:
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
Maas360Logger.i(loggerName, "upgrading database "+oldVersion+" "+newVersion);
try {
database.beginTransaction();
for (int i = oldVersion + 1; i <= newVersion; i++) {
// Future schema changes has to go into this loop
Maintain database versions to handle upgrades

Does an Android database get completely removed and recreated then updating an app?

I have an app that uses a database. At startup I check to see if my tables are missing and if so I create them. Works great.
I've noticed that if I "adb uninstall" then the next time I run my app the tables are created again (this is what I need), but what about when updating through the marketplace?
I'm in the process of releasing an update, and I've made major changes to the tables. I'd like it if the tables were completely wiped and re-created, in fact my app needs this to happen. If someone updates and has the old tables then there will be a force close.
Does anyone know the specifics of this scenario?
My tables are only for lookup, I store no user data so I dont really care about losing data on the updates.
Of course I know an option is to use some type of "version" table and check to see if I need to manually drop and create, but I was wondering if that was even needed.
Thanks.
On an update the tables are left alone. I'm going to assume you have implemented a subclass of SQLiteOpenHelper to explain this. The way Android is able to handle version changes is through the use of onUpgrade in the SQLiteOpenHelper class. This method is called from SQLiteOpenHelpers constructor if the DB version is older than the version the app expects. From inside onUpgrade is where you are going to drop your old tables and create the new ones.
onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion){
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
//we can change this to perform different behaviors
db.execSQL("DROP TABLE IF EXISTS "+MYDB.TABLE_NAME);
onCreate(db);
}
It is important to note the way Android tells if you are using a new DB version.
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
That field DATABASE_VERSION is used, so you should use a final static int member as part of your DB implementation.
Hope that helps, leave me a comment if you have questions.

Categories

Resources