onUpgrade in sqlite database in android - android

I am developing a database application and I am stuck up at one place.
The scenario is: I have a database and I am maintaining the version of the database.
It is the same as that of the application version.
Now I am implementing the database in version 1. There are 3 tables getting created in version 1. In version 2, I am upgrading the database by adding one more table. Hence, the query is in the upgrade().
Now, what if the user installs version 2. The onUpgrade() will not get called because there is no database. Hence, the onCreate() will be called and the consequence will be it will create only 3 tables.
I was thinking to call the onUpgrade() explicitly in the onCreate(). But many developers on stackoverflow have suggested not to call it explicitly.
I am completely stranded.
Thanks in advance.

I know it's an old post, you have certainly found a solution, but I find the question valid (upvoted) and as it did not receive an answer, here are my 2 cents:
Calling onUpgrade() from onCreate() should work (I did not test it), but there is a better way to organize you helper (see snippet hereafter). The key point is that both those methods are just entry points.
public class SampleDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "mydatabase";
private static final int DB_VERSION = 2;
public SampleDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
updateDatabase(db, 0, DB_VERSION);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
updateDatabase(db, oldVersion, newVersion);
}
private void updateDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 1) {
// Create 3 initial tables
}
if (oldVersion < 2) {
// Create the new table
}
}
}
The advantages of this kind of helper:
You never need to change onCreate() and onUpgrade() methods, only updateDatabase().
For each new version, you just need to :
increment DB_VERSION
add a new section if (oldVersion < N) { // do the upgrade }.
Credit : Strongly inspired from Head First Android Development, Dawn and David Griffiths, O'Reilly, 2015

Related

SQLite need Upgrade on FirstRun

im using SQLite OpenHelper to handle database version and it worked fine, my problem is, if i set some updates and new users install my app, the will not get the UPGRADES, because it will run the onCreate using the last DB_VERSION
explaining:
private static final int DB_VERSION = 3;
Context context;
public DB(Context c) {
super(c, DB_NAME, null, DB_VERSION);
context = c;
}
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE table1...");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("DBUpgrade", "Atualizando DATABASE");
switch (oldVersion) {
case 2: {
execSQLFromFile(db, "sql2");
}
case 3: {
execSQLFromFile(db, "sql3");
}
}
scenarios:
User 1 has installed since first app release
-> he will get the all the upgrades
User 2 installed for the first time in his device the last release of my apk that has the db_version 3
-> he will not get the upgrades, just the onCreate
ofc i know why this happens but i dont know how to solve it by a simple way, the only i way i throught was to call the onUpgrade(db, 0, DB_VERSION); this enter in the onUpgrade but dont call the cases inside the switch i dont know why, since i send 0, it should call case: 2, because i dont have the break isnt it?
BUT doing this i loose the OnUpgrade for the next version, it will always check the oldVersion, and redo the same code so it will crash because Unique column, alter columns anything
so i still ended without way to onfirst install do the upgrades too =(
User 2 installed for the first time in his device the last release of my apk that has the db_version 3 -> he will not get the upgrades, just the onCreate
There are no "upgrades", as there is no database to upgrade. onCreate() must be implemented to create a database with the proper (latest) schema.

Steps to upgrade existing Android database w/o losing data

I have an app that is being used by beta testers. My original schema did not end up working for my actual implementation of the feature I'm currently working on. I want to update the database. I do not want my testers to lose their data.
My understanding is that the steps for this are:
1) Leave my SQLiteOpenHelper class's onCreate method AS IS. I leave it as it is currently / originally written, the "version one" schema as I think of it.
UPDATE 2015-04-19: Step One is WRONG. See my own (accepted) answer below for details.
2) Fill in my SQLiteOpenHelper class's onUpgrade method. Here I make all the changes to go from the first schema to the second. (and in the future maybe write the changes needed to go from the second schema to a third)
3) Update the database version. In my app, I keep this as a static var. When I'm ready to pull the trigger and update the database, I change this var (DB_VERSION) from 1 to 2. This var being 2 versus the app installed on the device having a version of 1 is what triggers onUpgrade() to be called the first time the database is opened (in my case, the app's onCreate).
public static final int DB_VERSION = 1;
...
class DBHelper extends SQLiteOpenHelper {
public DBHelper() {
super(context, DB_NAME, null, DB_VERSION);
}
4) Run my app and cross my fingers. If I get an error / made a typo in my SQL, I uninstall and run again.
Can anyone verify if that is correct? Or if I'm overlooking something?
The tutorials I've found -- when they don't just drop and recreate the database, changing the onCreate to the new schema -- don't really discuss when you already have an app and need to make a change. I guess it's not relevant to a beginner, and assumed knowledge for a non-beginner? For upgrades with user data that can't be thrown away, I only have been able to find specific question/answers about a single aspect of the upgrade, not a comprehensive guide. I'm afraid I could be missing something that's so basic/important that it "goes without saying", hence my apprehension/fear to just do it. I've searched as best as I am able, could really use some guidance! Thanks in advance for any help!
That is correct. You are increasing version and updating db.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion < 2) {
db.execSQL("blablabla");
}
if(oldVersion < 3) {
db.execSQL("new blablabla");
}
if(oldVersion < 4) {
db.execSQL("newest blablabla");
}
}
> Can anyone verify if that is correct?
Yes
Thats the way it worked for my android apps. My code looks like this:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION_3_MYTABLE_WITH_NOTES = 3;
public static final int DATABASE_VERSION_4_CATEGORY_ACTIVE = 4;
public static final int DATABASE_VERSION_5_REPORT_VIEW = 5;
// points to latest version
public static final int DATABASE_VERSION = DatabaseHelper.DATABASE_VERSION_5_REPORT_VIEW;
public DatabaseHelper(final Context context, final String databaseName) {
super(context, databaseName, null, DatabaseHelper.DATABASE_VERSION);
....
}
#Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
final int newVersion) {
Log.w(this.getClass().toString(), "Upgrading database from version "
+ oldVersion + " to " + newVersion + ". (Old data is kept.)");
if (oldVersion < DatabaseHelper.DATABASE_VERSION_3_MYTABLE_WITH_NOTES) {
this.version3Upgrade_MYTABLE_WITH_NOTES(db);
}
if (oldVersion < DatabaseHelper.DATABASE_VERSION_4_CATEGORY_ACTIVE) {
this.version4Upgrade_CATEGORY_ACTIVE(db);
}
if (oldVersion < DatabaseHelper.DATABASE_VERSION_5_REPORT_VIEW) {
this.version5Upgrade_REPORT_VIEW(db);
}
}
private void version3Upgrade_MYTABLE_WITH_NOTES(final SQLiteDatabase db) {
// added MYTABLE.notes
db.execSQL("ALTER TABLE " + MyTable.TABLE
+ " ADD COLUMN " + MyTable.COL_NOTES + " TEXT");
}
I have one const and one method to upgrade from one version to the next.
Sorry self-from-3-months-ago, turns out that's WRONG!
The problem is in step one. The onCreate is NOT left as is. It needs to create the newest version of the database. onUpdate is only called when an EXISTING user updates to the newest app release. Anyone doing a CLEAN INSTALL would end up with the old scheme, never calling onUpdate.
Here is the skeleton of my new code, which seems to handle both clean installs and upgrades. (At least I hope it does.)
class DBHelper extends SQLiteOpenHelper {
public DBHelper() {
super(context, DB_NAME, null, DB_VERSION);
Log.i(TAG, "DBHelper called with DB_NAME " + DB_NAME + " and DB_VERSION " + Integer.toString(DB_VERSION));
}
#Override
public void onCreate(SQLiteDatabase db) {
setupV1(db);
upgradeV2(db);
}
#Override
public void onUpgrade(
final SQLiteDatabase db, final int oldVersion,
final int newVersion)
{
int upgradeTo = oldVersion + 1;
Log.i(TAG, "Upgrading database to version " + Integer.toString(upgradeTo));
while (upgradeTo <= newVersion)
{
switch (upgradeTo)
{
// Database v2. Added X Functionality
case 2:
upgradeV2(db);
break;
// Database v3 (not created yet)
// case 3:
// // something here
// break;
}
upgradeTo++;
}
}
private void setupV1(final SQLiteDatabase db) {
// CODE HERE TO CREATE VERSION / SCHEMA ONE OF MY DATABASE
}
private void upgradeV2(final SQLiteDatabase db) {
// CODE HERE TO UPDATE FROM VERSION ONE TO VERSION TWO
}
}

SQLite database add new table when upgrade app

I add one more table to my app's database.
However, if I upgrade my app without clearing its data, the new table doesn't seem to be added automatically.
Therefore, some code that need to retrieve data from the new table fail.
Is it possible to add new tables automatically on app upgrade?
Please implement onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) method.
There is an Android helper class to manage database creation and version management using an application's raw asset files.
Have a look at this :
https://github.com/jgilfelt/android-sqlite-asset-helper
Yes there is a method onUpgrade
add you code there and increase database version if your version is higher than the previous
onUpgrade is fired and the your code will execute which you write to add table
sample
Remember increasing you version code in super call
class Database extends SQLiteOpenHelper
{
public Database(Context _myContext)
{
super(_myContext, DB_NAME, null, DB_VERSION_CODE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
if(oldVersion > newVersion)
{
// create a new table what you want to create you can also check the existence of the table
}
}
}

Get version database ormlite

I use a database in ormlite. I would like to get the version of my database in the Activity, but I don't know in wich table is saving the version.
Anybody know how can I get the version of the database? I have looked for in the manuals but I haven't found it.
Thanks a lot.
in onCreate write this code
int version = getHelper().getReadableDatabase().getVersion();
hope this help :)
If you are talking about the database version number managed by the Android OS then you will know what the number is because otherwise you will get a call to onUpgrade(...).
If your onUpgrade(...) method is called, you know what the number is because you get the old version and the new version numbers. If you didn't get the call then you know that the version number you set in your database helper and was passed up to the SQLiteOpenHelper class corresponds to the one in the Android's storage.
Here's a sample of code from a typical ORMLite DatabaseHelper class:
private static final int DATABASE_VERSION = 4;
...
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config);
}
...
/**
* This is called when your application is upgraded and it has a higher version
* number. This allows you to adjust the various data to match the new version
* number.
*/
#Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource,
int oldVersion, int newVersion) {
...

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