Мне добавили сложную миграцию в мой построитель базы данных Room. Поскольку для этой конкретной миграции требуется загрузка некоторых данных с сервера, я использую заставку, чтобы дождаться завершения всего процесса, прежде чем открывать основную деятельность приложения.
Проблема заключается в том, что миграции не выполняются автоматически в методе "build ()", так как кажется, что они выполняются внутри отдельного потока.
Я также подумал об использовании RoomDatabase.Callback для определения того, когда база данных открыта, но поскольку миграция является сложной и пытается загрузить данные с сервера, она может завершиться неудачно, и приложение может оставаться в ожидании вечно.
Мне нужно запустить миграцию и дождаться ее завершения и, если возможно, перехватить ошибки миграции.
Это код класса приложения:
appLoadingStatus.value = AppLoadingStatus.INITIALIZING
db= Room.databaseBuilder(this@App,Database::class.java,"app-database")
.addMigrations(Database.MIGRATION_12_13).build()
//Here I need to wait for migrations to finish in case they are executed, and catch ay possible errors
appLoadingStatus.value = AppLoadingStatus.INITIALIZED
А это миграция:
val MIGRATION_12_13: Migration = object : Migration(12, 13) {
override fun migrate(database: SupportSQLiteDatabase) {
runBlocking(Dispatchers.Main) {
val newIds =App.instance.getIdsForMigration()?:throw IllegalStateException("Unable do get data from server")
database.execSQL("ALTER TABLE Coin ADD `id` INTEGER NOT NULL")
newIds.forEach {symbolIdPair->
database.execSQL("UPDATE Coin SET id='${symbolIdPair.id}' where symbol='${symbolIdPair.symbol}'")
}
database.execSQL("ALTER TABLE Coin RENAME TO `Coin_backup`")
database.execSQL("CREATE TABLE `Coin` (`symbol` TEXT NOT NULL, `id` INTEGER NOT NULL, `name` TEXT, `imageSrc` TEXT, `rank` INTEGER NOT NULL, `max_supply` REAL NOT NULL, `quantity` REAL NOT NULL, `market` TEXT NOT NULL, `type` TEXT, `price` REAL NOT NULL, `lastUpdate` INTEGER NOT NULL, `lastVolume` REAL NOT NULL, `lastVolumeTo` REAL NOT NULL, `volumeDay` REAL NOT NULL, `volumeDayTo` REAL NOT NULL, `volume24h` REAL NOT NULL, `volume24hTo` REAL NOT NULL, `openDay` REAL NOT NULL, `highDay` REAL NOT NULL, `lowDay` REAL NOT NULL, `open24h` REAL NOT NULL, `high24h` REAL NOT NULL, `low24h` REAL NOT NULL, `change24h` REAL NOT NULL, `changePct24h` REAL NOT NULL, `changeDay` REAL NOT NULL, `changePctDay` REAL NOT NULL, `supply` REAL NOT NULL, `mktCap` REAL NOT NULL, `totalVolume24h` REAL NOT NULL, `totalVolume24hTo` REAL NOT NULL, `favourite` INTEGER NOT NULL, PRIMARY KEY(`id`))")
database.execSQL("INSERT INTO `Coin` SELECT * FROM `Coin_backup`")
}
}
}