Configure Module build.gradle
to export schema and allow testing. Observe // NEW
comments.
Based on Android Room Database Migration Instrumented Unit Test.
android {
...
// https://developer.android.com/training/data-storage/room/migrating-db-versions
defaultConfig {
...
// NEW
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
// NEW
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
}
}
dependencies {
def android_room_version = '1.1.1'
implementation "android.arch.persistence.room:runtime:$android_room_version"
kapt "android.arch.persistence.room:compiler:$android_room_version"
// NEW
androidTestImplementation "android.arch.persistence.room:testing:$android_room_version"
}
Make sure exportSchema = true
for @Database, else schema json won't be generated and later you might bump into FileNotFoundException: Cannot find the schema file in the assets folder
.
@Database(entities = [(Pin::class)], version = 1, exportSchema = true)@TypeConverters(RoomConverters::class)abstract class AppDatabase : RoomDatabase() { abstract fun pinDao(): PinDao}
Make/Compile/Build
project (don't Run/Deploy
) and it shall generate 1.json
at assets/[DatabaseClassPath]
(Android view) or /app/schemas/[DatabaseClassPath]
(Project view).
Change Database Version to 2.
NOTE: Important to change Database Version before applying changes to table and column. This is to ensure the database schema generated is accurate based on the database version.
@Database(entities = [...], version = 2, exportSchema = true)
Create the new Entity/Table.
@Entity(tableName = "album")data class Album ( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Long = 0, @ColumnInfo(name = "created") var created: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC), @ColumnInfo(name = "modified") var modified: LocalDateTime = created, @ColumnInfo(name = "name") var name: String = "" )
Add to @Database
annotation.
@Database(entities = [(Pin::class), (Album::class)], version = 2, exportSchema = true)
Make/Compile/Build project (don't Run/Deploy
) and it shall generate 2.json
at assets/[DatabaseClassPath]
(Android view) or /app/schemas/[DatabaseClassPath]
(Project view).
Look inside 2.json
and you shall find the createSql
for new album
table.
{
"tableName": "album",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`))",
}
Based on Android Room Database Migration (Upgrade Version), create the Migration
class.
Create file DatabaseMigration.kt
to handle database migration from Version 1 -> 2.
Copy the createSql
from 2.json
. Replace ${TABLE_NAME}
.
val MIGRATION_1_2: Migration = object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { // https://developer.android.com/reference/android/arch/persistence/room/ColumnInfo /* database.execSQL("ALTER TABLE pin " + " ADD COLUMN is_location_accurate INTEGER NOT NULL DEFAULT 0") database.execSQL("UPDATE pin " + " SET is_location_accurate = 0 WHERE lat IS NULL") database.execSQL("UPDATE pin " + " SET is_location_accurate = 1 WHERE lat IS NOT NULL") */ database.execSQL("CREATE TABLE IF NOT EXISTS `album` (`id` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`id`))")" }}
Add addMigrations
to Room.databaseBuilder
.
val database = Room.databaseBuilder(app, AppDatabase::class.java, "PixPin.db") // addMigrations(MIGRATION_1_2, MIGRATION_2_3) .addMigrations(MIGRATION_1_2) .build()
If you want to test it before deploying the migration to your device, refer to Android Room Database Migration Instrumented Unit Test.
Else, Run
the project.
References: