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.
Related
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.
When my application starts for the first time it needs to create the database it'll be using. I don't know at what point I should be creating the database if it doesn't already exist yet, and I don't know how to ensure I don't try to create the database if it already does exist. Currently, the following works, where I execute CreateTable when the first activity in my app runs:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
base.SetContentView(Resource.Layout.SiteListLayout);
DataManager.CreateTable<Site>();
DataManager.CreateTable<PanelLog>();
DataManager.CreateTable<Trace>();
}
Basically, this works because the CreateTable method checks to see if the table already exists before creating it. However, I don't like the idea of frivolously running some code knowing it's going to fail because of some of some exception to its expectations. I'd prefer to be more explicit.
Therefore, how can I execute code the first time my app runs to test if the tables need to be created, and if so to create them? And any subsequent time my app runs it doesn't check that code.
This is what I use to create or upgrade my database, and it seems to work really well. It's a hack from various sources in the web. It creates 4 tables, unless they already exist. I haven't included the static variables but that should be clear enough to follow?
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
db.execSQL(DATABASE_CREATE_2);
db.execSQL(DATABASE_CREATE_3);
db.execSQL(DATABASE_CREATE_LIST_SUB);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_2);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_3);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_LIST_SUB);
onCreate(db);
}
}
You can use other data storage options in android.take a look at http://developer.android.com/guide/topics/data/data-storage.html#filesInternal.You may find any storage option that are specific and secure to be used by a single app and their lifetime will be until you uninstall the app.So store in it the information either you created database or not,and check that storage everytime you run that app.
Create your database at the main_activity if you want, you can even create it on the splash screen activity if you have one.
As long you don't change the tables names, they will be created only one time, which is the first time the class that contains create table commands is called.
UPDATE
Check this Website, there you ll find a very simle tutorial, a bit long but very helful, if you don't have time you can try to use the code for creating your tables.
I implemented an Android application which use Sqlite database.
When I release a new version of my application (not in playStore), I upload it on my server, so, if the old application is running, calling web service, can understand that new version is available. So, new version is downloaded and installed.
When the application is overinstalled, the database is not dropped, so if I need to do any changes of my database I need to use the method:
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion)
This is fine, unless I need to do many changes in my database. In this case, the code becomes unreadable. So I would to delete the database and create a new one.
How can I perform this task?
EDIT: What about using context.deleteDatabase(DATABASE_NAME); ?
For throw-away databases (where the data is e.g. a cached copy of data available in the cloud) I usually make onUpgrade() just call onCreate() and make onCreate() execute DROP TABLE IF EXISTS <tablename> before creating the tables.
For example:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS foo");
db.execSQL("CREATE TABLE foo(bar INTEGER, baz TEXT");
}
you can think about this one
keep a trace of your upgrade using a flag in shared preference. when you are downloading new version then set the flag to true. on every launch check the flag. if the flag is true then recreate the database and set the flag false.
I havn't tried similar things but I think it should work in your case.
and to delete database context.deleteDatabase(DATABASE_NAME);
If you just want to re-create your whole database, just drop every table in the old one.
I have an application published in the android market, and now I want to make a new version with changes in the database. The problem is, my version of the app that is already published has this onUpgrade method:
#Override
public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion) {
Log.w("TaskDBAdapter", "Upgrading from version " +
_oldVersion + " to " +
_newVersion + ", which will destroy all old data");
// Drop the old table.
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_1);
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_2);
// Create a new one.
onCreate(_db);
}
Because I want to add a new table, I know that I have to make some changes here to keep the data from the tables I already created with the previous version. So what onUpgrade method will be called, from the old or from the new .apk. Can I keep the data from the tables? Please let me know.
Thank u in advance.
So what onUpgrade method will be called, from the old or from the new .apk.
From new .apk. Old one is gone at this point.
Can I keep the data from the tables?
You have to code your upgrade in such a way that you retain data that you need including old data as required.
Dropping the tables will kill all of your current data. In order to preserve the data, you're going to need to write a custom onUpgrade method to do this. Here's a previous post that discusses this and may give you some ideas on what you need to do:
SQLiteOpenHelper onUpgrade() Confusion Android
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.