Android onUpgrade gets invoked every time - android

I am trying to upgrade a certain table by adding a column to a Sqlite table in my android app.I have added an alter table statement in the onUpgrade method of my DBHelper.
Here are the problems that I am seeing
I changed the value of Database version from 1 to 2, so ideally now the onUpgrade should get called.It does get called, but it gets called everytime I instantiate the class.As a result I get a column already exists error.
Here is the onUpgrade method
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.d("old Version",oldVersion+"");
Log.d("New Version",newVersion+"");
db.beginTransaction();
try
{
String DATABASE_UPGRADE;
DATABASE_UPGRADE="alter table "+DATABASE_TABLE_MESSAGES+" ADD COLUMN "+ IS_READ+ " integer DEFAULT 0;";
db.execSQL(DATABASE_UPGRADE);
Log.d("upgrade", "Successful");
db.setTransactionSuccessful();
}
finally
{
db.endTransaction();
}
}
}
I am wondering why the onUpgrade gets called each time!!!

In the constructor of your database helper are you correctly passing the new version number?
EDIT: should look like this
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
and DATABASE_VERSION should be 2.

Related

how to add table to the database when database is already created in android?

I have created a database with a table.I want to add more tables dynamically to that database on the user's command.
The onOpen() method is not useful as it also changes my previous tables that already exist in the database.
I assume you are using SQLite database. If that is the case, a working solution exists here:
Create new table in existing DB in separate SQLiteOpenHelper class.
see rmkrishna's answer from that post, below:
First check the current database version for this database
private final static String DATABASE_NAME = "MainDB";
private static final int DATABASE_VERSION = 1;
public BaseSQLiteOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
and increment the database version(DATABASE_VERSION), and add your new table query in on Upgrade and oncreate method like below.
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("old query no need to change");
db.execSQL("Create your new table here");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
db.execSQL("Create your new table here as well this for update the old DB");
}
}

Will data lost when onUpgrade is called

I have created DatabaseHelper to make my development easier. If my Database version is upgrade from 1 to 2, onUpgrade will called and table will be dropped. I wonder will this cause my data stored in table dropped too? I means, will I lost my data stored in table?
Here's the code.
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);
}
#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 notes");
onCreate(db);
}
}
By looking at your code, Yes you will lose the current table of the database and a new empty table notes will be created.
So the best way to upgrade the database is before this:
db.execSQL("DROP TABLE IF EXISTS notes");
statement, you should made a backup of your current database (easiest way is to rename the table) and then drop the current table to create the new one.
It is always a good programming practice to keep a backup of information before editing/upgrading it.
When you drop a table all it's data is deleted too. If you want to keep it, rename the table first, create the new one and then select the data from the old into the new one.
You can alter table in onUpgrade method if there is change in coloumn. If you want to make fresh table then only call Drop inside onUpgrade, if there is no change in schema dont do anything inside onUpgrade method.

Android database versioning

I want the sqlite database of my app to be cleared each time the application is updated.
To do that, I make a drop table query on all my tables, in the "onUpgrade" function of SQLiteDatabase.
I got 2 problems:
- at the first launch of my app, I don't do any special.
- at the second launch, I add a "setVersion(2)" line. It calls the onUpgrade method but the logs are strange:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
Log.d("GDB", "onUpgrade "+oldVersion+" -> "+newVersion);
}
----------------------------------------------------------
DEBUG/GDB(5928): onUpgrade 2 -> 1
So when I make a setVersion(), the 2 versions seems to be switched.....
My second problem is that is I launch my app a third time, without changing the code ( so the setVersion(2) is already here), the onUpgrade method is called again! Did I miss something to definitively set the version to 2?
I don't think you should be setting the version of the database in code directly using the setVersion method. Instead you should pass the schema version into the constructor of your SQLiteOpenHelper (or at least your class which extends this). Your onUpgrade method should then contain condition statements to decide what to run depending on what version the user is upgrading from. These conditions should form a cascade so that coming from a low version applies in sequence all database updates required to get the user to the current level.
So when you want to change your schema, you add a new condition to your onUpgrade and up the schema version passed to your constructor.
This is what the constructor in the OpenHelper looks like:
public TiftHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
Then the onUpgrade looks something like this:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(TAG, "on upgrade called. Old version:" + oldVersion
+ ". New version:" + newVersion);
if (oldVersion == 19) {
db.execSQL("create table challenges_temp as select * from challenges;");
db.execSQL("drop table challenges;");
db.execSQL(create_challenges);
db.execSQL("insert into challenges (_id, name, is_predef, status) select _id, name, is_predef, 'IN_PROGRESS' from challenges_temp");
db.execSQL("drop table challenges_temp;");
}
if (oldVersion <= 20) {
// adding the status column to the challenges table
db.execSQL("create table challenges_temp as select * from challenges;");
db.execSQL("drop table challenges;");
db.execSQL(create_challenges);
db.execSQL("insert into challenges (_id, name, is_predef, status) select _id, name, is_predef, 'IN_PROGRESS' from challenges_temp");
db.execSQL("drop table challenges_temp;");
}
etc.
That works fine for me.

App Crashes due to Db creation on every launch

I have an application in which i am trying to create a Database. On the first run the application works properly. Subsequent launch of the application it crashes. The error is because the application is trying to create the db again.
So i want to know how to create a database or tables only if they dont exists or only if the application is run the first time.
You can extend the class SQLiteOpenHelper to handle different versions of your database. Here is an example:
public class MyDbOpenHelper extends **SQLiteOpenHelper** {
final static int VERSION = 2;
public MyDbOpenHelper(Context context, String dbname) {
super(context, dbname, null, VERSION);
}
#Override
public void **onCreate**(SQLiteDatabase db) {
/* TODO SQL-Queries for new Database */
}
#Override
public void **onUpgrade**(SQLiteDatabase db, int oldVersion, int newVersion) {
/* SQL-Queries t*/
if (oldVersion < 2) {
db.execSQL("ALTER TABLE my_table ADD COLUMN new_attrubte INTEGER");
}
}
}
Handle of database is new in onCreate and if it exist, onUpgrade is called with existing version number in oldVersion parameter.
SQLite has a CREATE TABLE IF NOT EXISTS command. You could try that.
It is usually an error to attempt to create a new table in a database that already contains a table, index or view of the same name. However, if the "IF NOT EXISTS" clause is specified as part of the CREATE TABLE statement and a table or view of the same name already exists, the CREATE TABLE command simply has no effect (and no error message is returned). An error is still returned if the table cannot be created because of an existing index, even if the "IF NOT EXISTS" clause is specified.

Getting an Android Database Setup?

Typically, for a WinForm or a Web App, I create the database and tables through the RDBMS or through a separate install process. However, I haven't seen anything of the sort in Android. All the examples I've seen have the database creation scripts embedded in an activity like this.
The best thing I can come up with now is to call a method from the data access constructor to check whether the database is installed - if not - install it. However, this seems like a lot of overhead to me.
What's the cleanest way to execute a android database install and then forget about it?
When using SQLLiteOpenHelper (http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html), the onCreate method will be called only if the database doesn't exist. onUpgrade will be called when a new version of the database is introduced.
IF the database already exists, and no version upgrade occured, these methods won't be executed.
There is no need for implementing if-else checks in your activity.
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);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
db.execSQL(DATABASE_UPGRADE);
}
}

Categories

Resources