Reputation: 111
I want to create the sqlite database file DatabaseName.db with few entities that should be created in path of application (/data/data/MyApplicationName/databases/DatabaseName.db) when I try to execute the snippet code bellow, however the DatabaseName.db file is not there. Why ?
MyDatabaseSample db = Room.databaseBuilder(context,
MyClass.class,
"DatabaseName.db")
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase ssdb) {
super.onCreate(db);
Log.d(TAG, "Database created - populate database");
}).build();
The database is created in the path of application only if I create an instance of a entity object and insert it in database right after get the database reference db. As I want to pre-populate database just after database creation, I think just make sense do it inside onCreate method of callback, but onCreate will never be called. So, How can I create the "DatabaseName.db" file with all tables representing entities and populate the database using callback ?
OBS: I am using Room version use 1.1.0-alpha2 and compiling with SDK android API 27.
Upvotes: 1
Views: 2130
Reputation: 167
I think you need to define some Room entities before pre-populate the db that's what i have done and it works just as expected, here is some code of what i have done so far:
public class DatabaseCreator {
private static MyDatabaseSample appDatabase;
private static final Object LOCK = new Object();
public synchronized static MyDatabaseSample getDBInstance(final Context context){
if(appDatabase == null) {
synchronized (LOCK) {
if (appDatabase == null) {
RoomDatabase.Callback appDBCallback = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
try {
ReadScript.insertFromFile(context, R.raw.populate_db, db);
} catch (IOException e) {
Log.d("DB Population Error", e.toString());
}
}
};
appDatabase = Room.databaseBuilder(context,
MyDatabaseSample.class, "DatabaseName").addCallback(appDBCallback).build();
}
}
}
return appDatabase;
}
}
The code above is a singleton that uses the Callback's onCreate to pre-populate the db using a "raw resource" (To add raw resources to your project just create a folder inside your res folder like this "res/raw") that contains an sql script. To read the script i have used this code:
public class ReadScript {
public static int insertFromFile(Context context, int resourceCode, SupportSQLiteDatabase db) throws IOException {
// Reseting Counter
int result = 0;
// Open the resource
InputStream insertsStream = context.getResources().openRawResource(resourceCode);
BufferedReader insertReader = new BufferedReader(new InputStreamReader(insertsStream));
// Iterate through lines (assuming each insert has its own line and theres no other stuff)
while (insertReader.ready()) {
String insertStmt = insertReader.readLine();
if(insertStmt != null){
if(insertStmt.isEmpty()) continue;
db.execSQL(insertStmt);
result++;
Log.d("Statement #", Integer.toString(result));
}
}
insertReader.close();
// returning number of inserted rows
return result;
}
}
And then you just create the db instance by doing:
MyDatabaseSample db = DatabaseCreator.getDBInstance(getContext());
Note: You can try to create tables inside the raw script but i haven't tried it yet.
Goog luck.
Upvotes: 1