Tuesday, 24 April 2012

ORMLite and a Bundled Database

When writing one of my first Android apps, the Southampton Univeristy Map App (GitHub), using ORMLite to manage the database, I came across a few problems trying to include the database in assets. This I needed to do because creating the database on the device would require to much time and space.

To do this, I include my database in the assets folder (this I got from the emulator using the file explorer). I then included the following code at the start of the onCreate method of my launcher activity, this deals with incorrect versions of the database, by simply overriding it with the bundled version.
  
try {
 File dbFile = new File(DATABASE_PATH + DATABASE_NAME);
 if (dbFile.exists()) {
  Log.i(TAG, "Database exists");

  SQLiteDatabase checkDB = SQLiteDatabase.openDatabase(DATABASE_PATH + DATABASE_NAME, null,
    SQLiteDatabase.OPEN_READONLY);
  int version = checkDB.getVersion();
  checkDB.close();

  if (version != DATABASE_VERSION) {
   Log.i(TAG, "Not the right version");

   copyDatabase();
  }
 } else {
  Log.i(TAG, "Database does not exist");

  SQLiteDatabase db = getHelper().getWritableDatabase();

  if (USE_BUNDLED_DATABASE) {
   db.close();

   copyDatabase();
  } else {
   Log.i(TAG, "Creating database");

   try {
    DataManager.createDatabase(instance);
   } catch (SQLException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
} catch (IOException e) {
 e.printStackTrace();
}
Where  DATABASE_PATH, DATABASE_NAME, DATABASE_VERSION are in an interface, implemented in both the database helper, and the launcher activity.
static final String DATABASE_PATH = "/data/data/net.cbaines.suma/databases/";
static final String DATABASE_NAME = "data.db";

static final int DATABASE_VERSION = 43;
The copyDatabase method is also quite simple.
private void copyDatabase() throws IOException {
 Log.i(TAG, "Begining copy database");

 InputStream myInput = getAssets().open(DATABASE_NAME);

 // Path to the just created empty db
 String outFileName = DATABASE_PATH + DATABASE_NAME;

 File database = new File(outFileName);
 if (database.exists()) {
  database.delete();
 }

 // Open the empty db as the output stream
 OutputStream myOutput = new FileOutputStream(outFileName);

 // transfer bytes from the inputfile to the outputfile
 byte[] buffer = new byte[1024];
 int length;
 while ((length = myInput.read(buffer)) > 0) {
  myOutput.write(buffer, 0, length);
 }

 // Close the streams

 myOutput.flush();

 myOutput.close();
 myInput.close();

 Log.i(TAG, "Finished copying db");
}

No comments:

Post a Comment