Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OrmaからRoomに移行する 2nd Season

Young
November 18, 2018

OrmaからRoomに移行する 2nd Season

社内勉強会 #深いい勉強会 の資料です

Young

November 18, 2018
Tweet

More Decks by Young

Other Decks in Programming

Transcript

  1. Τϥʔ಺༰ • DB͔ΒσʔλΛऔಘ࣌ʹΤϥʔ • Orma͔ΒͷϚΠάϨʔγϣϯʹࣦഊ͍ͯ͠Δ java.lang.Exception: Room cannot verify the

    data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number. java.lang.Exception: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.app.name/databases/app.db
  2. • όʔδϣϯίʔυΛ্͛Δ ࣮૷ AppDatabase.kt @Database(entities = [(UserEntity::class)], version = 2)

    abstract class AppDatabase : RoomDatabase() { // Some implementation }
  3. • Migration Code ࣮૷ Migration1To2.kt private const val TABLE_NAME_TEMP =

    "${TABLE_NAME}_new" class Migration1To2 : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { // 1. Create new table database.execSQL("CREATE TABLE IF NOT EXISTS `$TABLE_NAME_TEMP` " + "(`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + " `username` TEXT)") // 2. Copy the data database.execSQL("INSERT INTO $TABLE_NAME_TEMP (username) " + "SELECT username " + "FROM $TABLE_NAME") // 3. Remove the old table database.execSQL("DROP TABLE $TABLE_NAME") // 4. Change the table name to the correct one database.execSQL("ALTER TABLE $TABLE_NAME_TEMP RENAME TO $TABLE_NAME”) } }
  4. • DatabaseͷInstanceੜ੒࣌ʹMigrationΛઃఆ ࣮૷ AppDatabase.kt abstract class AppDatabase : RoomDatabase() {

    private fun buildDatabase(context: Context) = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, DB_NAME) .addMigrations(Migration1To2()) .build() // Some Implementation }
  5. ςετ • Set up 1 MigrationTest.kt // Helper for creating

    Room databases and migrations @get:Rule public var migrationTestHelper = MigrationTestHelper(InstrumentationRegistry.getInstrumentation(), AppDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory()) // Helper for creating SQLite database in version 1 private lateinit var sqliteTestDbHelper: SqliteTestDbOpenHelper private val migratedRoomDatabase: AppDatabase get() { val database = Room.databaseBuilder(InstrumentationRegistry.getTargetContext(), AppDatabase::class.java, TEST_DB_NAME) .addMigrations(Migration1To2()) .build() migrationTestHelper.closeWhenFinished(database) return database }
  6. ςετ • Set up 2 MigrationTest.kt @Before @Throws(Exception::class) fun setUp()

    { // To test migrations from version 1 of the database, we need to create the database // with version 1 using SQLite API sqliteTestDbHelper = SqliteTestDbOpenHelper(InstrumentationRegistry.getTargetContext(), TEST_DB_NAME) // We're creating the table for every test, to ensure that the table is in the correct state SqliteDatabaseTestHelper.createTable(sqliteTestDbHelper) } @After @Throws(Exception::class) fun tearDown() { // Clear the database after every test SqliteDatabaseTestHelper.clearDatabase(sqliteTestDbHelper) }
  7. ςετ • Test 1 - Migration Test MigrationTest.kt @Test @Throws(IOException::class)

    fun migrationFrom1To2_containsCorrectDataTest() { // Create the database with the initial version 1 schema and insert a user val id = SqliteDatabaseTestHelper.insertUser(User, sqliteTestDbHelper) migrationTestHelper.runMigrationsAndValidate(TEST_DB_NAME, 2, true, Migration1To2()) // Get the latest, migrated, version of the database val latestDb = migratedRoomDatabase // Check that the correct data is in the database latestDb.userDao().getUserById(id.toInt()) .test() .awaitDone(5, TimeUnit.SECONDS) .assertValue { (_, userName) -> userName.equals(USER.userName) } }
  8. ςετ • Test 2 - New Version Test MigrationTest.kt @Test

    @Throws(IOException::class) fun startInVersion2_containsCorrectDataTest() { // Create the database with version 2 val db = migrationTestHelper.createDatabase(TEST_DB_NAME, 2) // db has schema version 2. insert some data val id = insertUser(USER, db) db.close() // open the db with Room val appDatabase = migratedRoomDatabase // verify that the data is correct appDatabase.userDao().getUserById(id.toInt()) .test() .awaitDone(5, TimeUnit.SECONDS) .assertValue { (_, userName) -> userName.equals(USER.userName) } }