I would to erase and recreate the database for my app each time I send a new version of my app from Eclipse to my phone (I am developing and changing my database very often). What is the easiest way to do this?
public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, dbName, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE USERS (username TEXT, password TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS USERS");
onCreate(db);
}
i use this one in my code :) change super(context, dbName, null, <database version number>); and it will execute onUpgrade method.
If this is something you do not wish to do once it is live, you can just clear data from your application manager each time. Also, you can make the database version number different and have the onUpgrade destroy and recreate the DB
private static final String DATABASE_NAME = "MyDbName";
private static final int DATABASE_VERSION = 6;
private static class DbOpenHelper extends SQLiteOpenHelper{
public DbOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
onUpgrade(this.getWritableDatabase(), 0, 0);
//
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TableHelper1.CREATE_TABLE_QUERY);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+ TableHelper1.TABLE_NAME);
onCreate(db);
}
}
In Eclipse, go into Debug Configurations, then Android Application on the left hand side. Select the debug configuration that you are using and then select the Target tab.
At the bottom, you'll see a checkbox labeled "Wipe User Data".
If you check that, everytime you launch the simulator, the data associated with your application (including the SQLite database) will be erased.
Your application will then call onCreate() for your SQLiteOpenHelper, and your database will be recreated.
Related
I want to add a column to my existing database
However I'm imagining I'm in the scenario where people have already got a version of the code and database and I'm going to make the changes through a update on google play, therefore previous data cannot be lost
To create my database I used the following code;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calculation);
db = openOrCreateDatabase("EJuiceData", Context.MODE_PRIVATE, null);
db.execSQL("create table if not exists Inventory(_id integer primary key autoincrement, NAME TEXT NOT NULL, AMOUNT TEXT, PRICE TEXT, AMOUNTLEFT TEXT, WEIGHT TEXT);");
....
I've looked around online and people are mentioning using the following command to update;
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE Recipe ADD COLUMN NOTES TEXT");
}
}
However onUpgrade is commented out stating the it isn't being called, also no where in my code have I stated what version of the database it is or given a new version
Anyone know how I get around this issue?
Thanks
EDIT;
From looking at the answers I've decided to try do this the most efficient way and what's seen as the best practice
So I've created a new Java Class called MyDBHelper which has the following
package com.sjhdevelopment.shaunharrison.myejuiceapp;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "EJuiceData.db";
public static final int DATABASE_VERSION = 1;
public MovieDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase database) {
database.execSQL("create table if not exists Recipe");
.....
}
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
if (newVersion > oldVersion)
database.execSQL("ALTER TABLE Recipe ADD COLUMN NOTES TEXT");
onCreate(database);
}
}
So far I have an error on MovieDatabaseHelper stating 'invalid method declared; return type required
Are you using SQLiteOpenHelper ? If yes you must have a version you send to the super class from the constructor (see documentation)
Here is a code sample. The onUpgrade function will be called when the DATABASE_VERSION changes.
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "EJuiceData.db";
public DatabaseHelper (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL("create table if not exists Inventory(_id integer primary key autoincrement, NAME TEXT NOT NULL, AMOUNT TEXT, PRICE TEXT, AMOUNTLEFT TEXT, WEIGHT TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE Recipe ADD COLUMN NOTES TEXT");
onCreate(database);
}
}
}
EDIT
now you can get access your database using
DatabaseHelper helper = new DatabaseHelper(getContext());
helper.getReadableDatabase().query(...);
//or
helper.getWritableDatabase().insert(...);
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < newVersion)
db.execSQL("DROP TABLE IF EXISTS '" + TABLE_NAME + "'");
onCreate(db);
}
}
You can extend SQLiteOpenHelper like below code, and new your helper class with version param which db version you want to open.
If you open db with version 1, and next time you open db with version 2, the onUpgrade method will be called with param ordVersion = 1 and newVersion = 2, then you can do something to upgrade your db schema here.
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "mydata.db";
public static final int VERSION = 1;
private static SQLiteDatabase database;
public MyDBHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
public static SQLiteDatabase getDatabase(Context context) {
if (database == null || !database.isOpen()) {
database = new MyDBHelper(context, DATABASE_NAME,
null, VERSION).getWritableDatabase();
}
return database;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
}
}
I wrote an application in android that using DB.
In the next version I want to add new column to the DB but without re-installing the application. How can I upgrade the table on missing column exception?
You can simply do it by changing(increment) database version
public class Databas extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
Database(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion <= DATABASE_VERSION)
db.execSQL("//write table altering query here ");
onCreate(db);
}
increment database version value with 1 from your current database version value
This can be easily done by using SQLiteOpenHelper. Let say your current database version is 1. You just change it to 2. Then if there is any version 1 database will be automatically update to version 2 and onUpgrade method will be invoked.
private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "notes";
private static final int DATABASE_VERSION = 2;
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) {
if(oldVersion <= 1)
db.execSQL("Do you table alter here ");
onCreate(db);
}
}
In my app I have used Sqlite. When I test the app in the emulator it runs ok but when I test the app on my device, it fails because the Helper class not pass by the OnCreate method. My java code is below.
public static void startDB(Context context) {
DBHelper = new DataBaseHelper(context);
DBHelper.getWritableDatabase();
}
private static class DataBaseHelper extends SQLiteOpenHelper {
public DataBaseHelper(Context context) {
super(context, NOMBRE_BASE_DATOS, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(USER_CREATE);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
for (String table : ALL_TABLES) {
db.execSQL("DROP TABLE IF EXISTS " + table);
}
onCreate(db);
}
}
The framework only calls onCreate() if the database does not exist.
To force onCreate(), remove the old database file: clear your app's data in app manager, or just uninstall and reinstall.
I have an existing database based on SQLiteOpenHelper that has several versions and code to upgrade it and that works fine. But in case a user installs an older version of the app (that expects a lower database version) it will currently crash - the ContentProvider using it can't access the database. I'd like to prevent it from crashing but I don't want to actually downgrade the database - adding the code to do that would be pain. Dropping all tables would certainly work but starting with a fresh file is imo cleaner and less error prone.
That's about what the database helper looks like - nothing special
public class MyDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 3;
private static final String DATABASE_NAME = "my.db";
public MyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
onUpgrade(db, 0, DATABASE_VERSION);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion < 1) db.execSQL("CREATE TABLE A...");
if (newVersion < 2) db.execSQL("CREATE TABLE B...");
if (newVersion < 3) db.execSQL("CREATE TABLE C...");
}
#Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// I'd like to delete the database here
// the only problem is that I can't from here
// since this is called in the middle of getWritableDatabase()
// and SQLiteDatabase has no .recreate() method.
}
}
The possible ways I've come up to do that are:
Do it from the outside: catch exceptions in the ContentProvider, delete the file and request to open the database again. - I don't like that since it's not the responsibility of the provider.
Replacing SQLiteOpenHelper with my own copy of that class that deletes the file instead of calling onDowngrade - Problem is that it's using package private parts of SQLiteDatabase (e.g. .lock()) which I can't replace without duplicating SQLiteDatabase too (that would probably result in duplicating the whole sqlite stack).
Is there any good approach to do that or do I have to go the DROP TABLES way e.g. like described here?
I've figured out a way that works nicely by extending SQLiteOpenHelper and all I need to do in MyDbHelper is to extend this class.
public abstract class DeletingSQLiteOpenHelper extends SQLiteOpenHelper {
private static final String TAG = DeletingSQLiteOpenHelper.class.getSimpleName();
private final File mDatabaseFile;
public DeletingSQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
mDatabaseFile = context.getDatabasePath(name);
}
public DeletingSQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
mDatabaseFile = context.getDatabasePath(name);
}
#Override
public synchronized SQLiteDatabase getWritableDatabase() {
try {
return super.getWritableDatabase();
} catch (SQLiteDowngradeFailedException e) {
// that's our notification
}
// try to delete the file
mDatabaseFile.delete()
// now return a freshly created database
return super.getWritableDatabase();
}
#Override
public final void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// throwing a custom Exception to catch it in getWritableDatabase
throw new SQLiteDowngradeFailedException();
}
// that's the exception
static class SQLiteDowngradeFailedException extends SQLiteException {
public SQLiteDowngradeFailedException() {}
public SQLiteDowngradeFailedException(String error) {
super(error);
}
}
}
This is the fist time I've used SQLiteOpenHelper (or databases on android). When I get a writeable database I was wondering why onCreate isnt being called on each new instance of the class. Am I doing something wrong?
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "MyDatabase.db";
private static final int DATABASE_VERSION = 1;
private String PrSQLcmd = "";
public DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE IF NOT EXISTS Contact(Firstname TEXT, LastName TEXT");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
In SQLiteOpenHelper, the meaning of 'onCreate' is different from what it is in an Activity. Here,'onCreate' is called only once, which is the first time you create the database. The next time you run the app, the database is already there, so it won't call 'onCreate'. Your object level initialization should be done in the constructor and not in 'onCreate'
To see 'onCreate' being called, either manually delete the db file, or simply uninstall the app.