Android : How add new column to existing database on asset folder in android app?

on Sunday, August 31, 2014


I wrote an application that use data from existing database on asset folder. for copy and use data I wrote following ExternalOpenDbHelper:



public class ExternalDbOpenHelper extends SQLiteOpenHelper {

public static String DB_PATH;

private static String TABALE_NAME = "font";
private static String FONT_ID = "_id";
private static String FONT_TYPE = "font_type";
private static String FONT_SIZE = "font_size";

private static String POEM_TABLE = "poem";
private static String POEM_ID = "_id";
private static String READ_POINT = "read_point";
private static String BOOKMARK = "bookmark";

public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;
private static final int DATABASE_VERSION = 2;

public SQLiteDatabase getDb() {
return database;
}

public ExternalDbOpenHelper(Context context, String databaseName) {
super(context, databaseName, null, DATABASE_VERSION);
this.context = context;

String packageName = context.getPackageName();

DB_PATH = String.format("//data//data//%s//databases//", packageName);
DB_NAME = databaseName;
openDataBase();
}

public void createDataBase() {
boolean dbExist = checkDataBase();
if (!dbExist) {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Log.e(this.getClass().toString(), "Copying error");
throw new Error("Error copying database!");
}
} else {
Log.i(this.getClass().toString(), "Database already exists");
}
}

private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String path = DB_PATH + DB_NAME;
checkDb = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLException e) {
Log.e(this.getClass().toString(), "Error while checking db");
}
if (checkDb != null) {
checkDb.close();
}
return checkDb != null;
}

private void copyDataBase() throws IOException {

InputStream externalDbStream = context.getAssets().open(DB_NAME);

String outFileName = DB_PATH + DB_NAME;

OutputStream localDbStream = new FileOutputStream(outFileName);

byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = externalDbStream.read(buffer)) > 0) {
localDbStream.write(buffer, 0, bytesRead);
}
localDbStream.close();
externalDbStream.close();

}

public SQLiteDatabase openDataBase() throws SQLException {
String path = DB_PATH + DB_NAME;
if (database == null) {
createDataBase();
database = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READWRITE);
}
return database;
}

@Override
public synchronized void close() {
if (database != null) {
database.close();
}
super.close();
}

@Override
public void onCreate(SQLiteDatabase db) {
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE cat ADD point BOOLEAN NOT NULL DEFAULT 0;");
db.execSQL("ALTER TABLE poem ADD read_point BOOLEAN NOT NULL DEFAULT false;");
db.execSQL("ALTER TABLE poem ADD bookmark INTEGER NOT NULL DEFAULT 0;");
}
}

public int updateFont(int i, String fontName, int p) {
SQLiteDatabase db = this.getWritableDatabase();

ContentValues font = new ContentValues();
font.put(FONT_TYPE, fontName);
font.put(FONT_SIZE, p);

String whereClause = FONT_ID + " LIKE ?";
String[] whereArgs = new String[] { String.valueOf(i) };

return db.update(TABALE_NAME, font, whereClause, whereArgs);
}

public void updateReadPoint(int poemId, int readPointTeransfer) {
SQLiteDatabase db = this.getWritableDatabase();
String whereClause;
String[] whereArgs;

if (poemId != readPointTeransfer) {
ContentValues readPoint = new ContentValues();
readPoint.put(READ_POINT, Boolean.toString(true));

whereClause = POEM_ID + " LIKE ?";
whereArgs = new String[] { String.valueOf(poemId) };

db.update(POEM_TABLE, readPoint, whereClause, whereArgs);

if (readPointTeransfer != -1) {
readPoint.put(READ_POINT, Boolean.toString(false));
whereArgs = new String[] { String.valueOf(readPointTeransfer) };
db.update(POEM_TABLE, readPoint, whereClause, whereArgs);
}
}
}

public void updateBookmarkList(int i, String idOfThisPoem) {


SQLiteDatabase db = this.getWritableDatabase();
ContentValues bookmarkValue = new ContentValues();
String whereClause = POEM_ID + " LIKE ?";
String[] whereArgs = new String[] { idOfThisPoem };
if (i == 0) {

bookmarkValue.put(BOOKMARK, Integer.toString(0));
db.update(POEM_TABLE, bookmarkValue, whereClause, whereArgs);
} else if (i == 1) {

bookmarkValue.put(BOOKMARK, Integer.toString(1));
db.update(POEM_TABLE, bookmarkValue, whereClause, whereArgs);
}
}

public boolean bookmarkStatus(String idOfThisPoem){
String idOfThisBookmarkedPoem = null;
Boolean iconFull = null;

String[] tableColumns = new String[] { POEM_ID, BOOKMARK };
String whereClause = POEM_ID + " LIKE ?";
String[] whereArgs = new String[] { idOfThisPoem };
Cursor poetCursor = database.query(POEM_TABLE, tableColumns,
whereClause, whereArgs, null, null, POEM_ID);

poetCursor.moveToFirst();
if (!poetCursor.isAfterLast()) {
do {

idOfThisBookmarkedPoem = poetCursor.getString(1);

} while (poetCursor.moveToNext());
}
poetCursor.close();

if (Integer.valueOf(idOfThisBookmarkedPoem) == 0) {
iconFull = false;

} else if (Integer.valueOf(idOfThisBookmarkedPoem) == 1) {
iconFull = true;

}
return iconFull;
}

}


In my code I checked if the data was copied on the phone don't copy again but if there wasn't on the path it copy from asset folder and read/write on the copied database on phone. I can't copy database from asset every time that app get run because I just write on the database that (//data//data//%s//databases//). Now I need to add new columns on two table of it and because I released it before don't like end user uninstall and install the app again. I try and googled lots of job but couldn't find solution. I guess if I could remove data on (//data//data//%s//databases//) path could do it right.


0 comments:

Post a Comment