Search code examples
androiddatabasesqlitedatabase-migrationandroid-room

Android Room populate database with new data after migration?


I already published an application in Play Store which pre-populate Room database with data in the onCreate callback. The data is read from a JSON file and put it into the database. Everything works for data into the database (add new records into table) again from a JSON file.

Here is my RoomDatabase create method:

private fun create(context: Context): MyDatabase {
        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL("ALTER TABLE dogs ADD COLUMN language TEXT")
            }
        }
        return Room.databaseBuilder(
            context.applicationContext,
            MyDatabase::class.java,
            DB_NAME
        )
            .addMigrations(MIGRATION_1_2)
            // prepopulate the database after onCreate was called
            .addCallback(object : RoomDatabase.Callback() {
                override fun onCreate(db: SupportSQLiteDatabase) {
                    super.onCreate(db)
                    GlobalScope.launch {
                        getInstance(context)?.let { DatabaseUtils.prepopulateDatabase(context, it) }
                    }
                }
            })
            .build()
    }

Is there an easy way to do that without to write hundreds SQL requests manually? Or if there is a way how to drop the whole database and create a new one with brand new data, maybe also will be an option for me.

Thanks in advance guys ;)


Solution

  • Maybe this is the easiest way:

    private const val IS_DB_RECREATED = "is_database_recreated"
    
    class App : Application(), HasActivityInjector {
    
        override fun onCreate() {
            super.onCreate()
            val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
            val isDBRecreated = sharedPreferences.getBoolean(IS_DB_RECREATED, false)
    
            if (!isDBRecreated) {
                deleteDatabase(MyDatabase.DB_NAME)
                sharedPreferences.edit().putBoolean(IS_DB_RECREATED, true).apply()
            }
        }
    }
    

    The all data will be lost from the database, but when the new DB is access for the first time it will be pre-populated and I can change the scheme also.