Manoel Rui
Manoel Rui

Reputation: 111

How to create and pre-populate sqlite database file with Android Room?

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

Answers (1)

Basher SG
Basher SG

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

Related Questions