Upgrading Sqlite database in android? - android

I have an android application which is using Sqlite as database.It has following tables:
Hotels
Locations
Favorites
I am keeping my raw database file in assests folder and when user installs my app i just copies this database to /data/data/package_name/databases directory.Initially Favorites table is empty and it gets populated after user start liking hotels.My problem is that I want to launch my updated version of app with some bug fixes and some new hotels added to the database, so I need to update database of existing users with new hotels and locations without affecting the favorites table.Now if I keep my old approach and update the Database Version Number then application will remove the old database and use the new database but all data in favorites table will be lost.I don't want it to happen.Now problem is how do I update Hotels and Locations table without loosing data in Favorites table.

I know this question was asked long ago, but I had a similar issue and wanted to share my solution, seems to do the trick for me. I'm a novice so feel free to give input-
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//code to keep table data
List<obj> objList = new ArrayList<obj>();
String selectQuery = "SELECT score,list_name,quiz_length FROM obj_table";
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
obj o = new obj();
o.final_score = cursor.getInt(0);
o.quiz_name = cursor.getString(1);
o.quiz_length = cursor.getInt(2);
objList.add(o);
} while (cursor.moveToNext());
}
//done storing data, now upgrade DB from asset file
try {
//my db file is upgraded here
copyDataBase();
} catch (IOException e) {
}
//now insert our saved table data
for (Score obj_rec: objList){
ContentValues values = new ContentValues();
values.put("score", obj_rec.final_score);
values.put("list_name", obj_rec.quiz_name);
values.put("quiz_length", obj_rec.quiz_length);
db.insert("obj_table", null, values);
}
}

Before updating write the contents of you previous table to a file and save it on the sdcard.
Then you may update your database with new version.
And after doing that copy back the data from the backup file(from sdcard) to the updated database. After the successful copying of the backup, delete the file from the sdcard.

Usualy upgrade a database has to be done with SQLiteOpenHelper class. I would advise You to do some tests at Your own device before publish it. You have to increment Your Database Version and call "ALTER TABLE" method from sqlite. This has been discussed in many threads here, the clearest one I think is this one:
Difficulty in upgrading SQlite table
and here is even a article with some solution:
http://joshhendo.blogspot.de/2012/03/android-sqlite-database-upgrade.html
However, a safe way would be to save the old database in a tempfolder, that the user can get back the old one if anything is running into chaos.

Related

Update specific table when onUpgrade with SQLite with provided database

Probably there is somewhere here answer to my question, but if it exist I can't find it.
Here is my problem:
I have provided database in assets folder. When I want to update my app because I put some more rows in specific table I increase db version, call this.getWritableDatabase(); and onUpgrade is called, to this point everything is ok.
But what next?
Here is my onUpgrade function:
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) {
if(i < i2) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null,SQLiteDatabase.OPEN_READWRITE);
db.execSQL("attach database ? as newdb", new String[]{DB_PATH + DB_NAME}); // I have to attach new version of db to the old one and then i can go on
db.execSQL("delete from GAME");
db.execSQL("INSERT INTO GAME SELECT * FROM newdb.GAME");
db.close();
}
This gives me an error that my db is locked - on the line:
db.execSQL("INSERT INTO GAME SELECT * FROM newdb.GAME");
I tried a lot of different scenarious but I just can't make it.
I'll be very glad if someone could help me make it works ;)
If your onUpgrade does not use its first parameter, it does something wrong.
db and newdb are the same database (both times opened with DB_PATH + DB_NAME).
You probably want to replace db with sqLiteDatabase.
onUpgrade means that you want to upgrade your database, not to copy some data from old one to new. this method gives you all you need to do upgrade - db instance to roll upgrade scripts for specific version. SQL is very powerful you can add/remove columns, delete tables and so on, so I don't see a reason to make another file.

Updating preloaded sqlite database without losing user data in android

I have done a few searches and read a number of posts but I am still not successful trying to update a database without losing the data that is already saved.
I created the DB using this tutorial: http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
In the new database I want to migrate data from a main table to a new table that will store the user's favourites. Currently, they are stored in the main table. In the onupgrade function I tried renaming the table and inserting the record into the new table. That didn't work. I also tried saving the data to a cursor and then populating the new table but that didn't work. For these methods, I got errors saying that the new/old table cannot be found.
Below is the onUpgrade() function.
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE books rename to old_books");
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
db.execSQL("INSERT into favourites (_id, type, title, notes,rating) SELECT _id ,type, title, notes, rating FROM old_books where rating > 0;");
db.execSQL("DROP TABLE IF EXISTS old_books;");
}
}
Is there a better way to update the database without losing data using the implementation from the tutorial? All I need to do is copy the favourites from the "books" table and load them to the "favourites" table when users update the app.
onUpgrade is called while the database is open and a transaction is active.
You cannot overwrite the database file at this time (and this would lose all the data in the old file).
Just remove the copyDataBase() call.
if you are using SQLite browser to get preloaded database so you can update the database file then change it's version not create a new database file and keep the data ! Source tutorial .... in my opinion this tutorial is better and more detailed than the one you refereed.

Update pre-loaded database with existing data

I have an app which is online on play store. It comes with a preloaded database, which is bundled inside assets folder and when user initially launches the app, db is copied to preferred folder.
There is a table of favourites , in which user stores there bookmarked/favourite records.
I have new data and few other modifications which I have made with bundled database, and will be uploading new APK to play store.
My concern is that, users who are currently using my app, they will get update notification and once they update, their app will use new bundled database, and they will lose their records stored in favourites.
I did some google search on it, and SQLiteHelper onUpgrade() works when we are creating database on runtime, but in my case its pre-loaded bundled database.
How can I backup the favourites data before update and then load it back in new db file.
Thanks
In the newer versions, you should preserve the table data that you want to keep. To do this, you could:
Make a copy of the old database file into a backup.
Extract the newer database file to the working directory
Open two SQLiteDatabase objects, one for each database file.
Copy all data from the tables you want to preserve.
Delete the backup of the old file if everything was successful.
For step 4 you shouldn't even need to code specifically, it can be done for every table, for example more or less like this (warning, this code is untested):
static void copyTable(SQLiteDatabase source, SQLiteDatabase destination, String tableName)
{
Cursor c = source.query(tableName, null, null, null, null, null, null);
destination.beginTransaction();
try
{
String[] columns = c.getColumnNames();
ContentValues insertValues = new ContentValues();
while (c.moveToNext())
{
insertValues.clear();
for (int i = 0; i < columns.length; i++)
insertValues.put(columns[i], c.getString(i));
destination.insert(tableName, null, insertValues);
}
destination.setTransactionSuccessful();
}
finally
{
destination.endTransaction();
}
c.close();
}

SQLite usage with Android

For my app, I need to have a database containing one table with 4 columns in it. This tables and its parameters will be static after creation, so that they will stay in the same place with the same data to be listed in a list view.
I have the DatabaseHandler for this purpose, but what I'm asking is how do I define this database in code? Does it build again every launch or is it only with the first launch? How does it work?
There are many ways of doing it. The one i follow is I will create database and tables in launch activity. Then i will insert data by counting the number of records in the table(Only for static table).So if(number of records == 0) then insert data into database. Otherwise do code for your app. It should work.
EDIT
This is the code to get total number of records in the database
In Database Class
YourDatabase
public class YourDatabase extends SQLiteOpenHelper{
//coding for table create and insert records goes here
//Your tables total number of records can be identified by following code
public long yourTableCount()
{
SQLiteDatabase db = getReadableDatabase();
return DatabaseUtils.queryNumEntries(db, YOURTABLE_NAME);
}
}
Your Activity
Calling Database class from your activity
YourDatabase db = new YourDatabase(this);
long numberofrecords = db.yourTableCount();
if(numberofrecords == 0)
{
//Insert your data in to database
//This will happen only in first launch because after that the numberofrecords == total number of records inserted in the database.
}
You can create the database manually using a database manager. Once you have the database defined in your assets folder it will remain there and be compressed within the apk file on build. Try SQLiteManager which has a free trial version that will let you design you database. Or use a firefox addon here: https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/

Android handle app updates and database changes

I have basically finished developing an android app that makes use of SQLite databases that I copy to the user data area on the device eg /data/data/com.company.app/databases/users.db
I am unsure how the marketplace app update procedure takes place and am also unsure as to how I could test it.
I currently check whether the database exists on the device and copy it if it doesn't (generally only occurs on first ever launch). What happens if I have a new version of the database in my updated app? Will an marketplace update wipe user data so that it will copy my new database in on next launch?
What happens in the future if I make database changes/add records/etc and package this with the new app? Will this database not overwrite the old database?
Otherwise, to avoid copying and overriding the databases from the app bundle on every launch is there a way to check the size and date of the database files and only copy if the database in the bundle is newer?
If anyone needs clarification please ask.
I am doing something similar. What I did is set the database version, and then when I check if the database exists, I also to make sure it's the correct version. If it's not, I save user favorites from the database, wipe and recopy my db, and then put back user favorites.
This is my on upgrade
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 2) {
System.out.println("Performing upgrade!");
openDataBase();
// save the old favorites
Cursor mCursor = getFavorites();
ArrayList<Stop> favs = allCursorToStops(mCursor);
mCursor.close();
deleteRecreate(db);
openDataBase();
for (int i = 0; i < favs.size(); i++)
setFavorite(favs.get(i));
close();
} else {
deleteRecreate(db);
}
}
Here is where I check existence/if need to upgrade etc
boolean dbExist = checkDataBase();
if(dbExist){
// check if we need to upgrade
openDataBase();
int cVersion = myDataBase.getVersion();
close();
if(cVersion != VERSION)
onUpgrade(myDataBase, myDataBase.getVersion(), VERSION);

Categories

Resources