134f575b4b17fe635684e76e02685978477538622Florina Muntenescu/* 234f575b4b17fe635684e76e02685978477538622Florina Muntenescu * Copyright (C) 2017 The Android Open Source Project 334f575b4b17fe635684e76e02685978477538622Florina Muntenescu * 434f575b4b17fe635684e76e02685978477538622Florina Muntenescu * Licensed under the Apache License, Version 2.0 (the "License"); 534f575b4b17fe635684e76e02685978477538622Florina Muntenescu * you may not use this file except in compliance with the License. 634f575b4b17fe635684e76e02685978477538622Florina Muntenescu * You may obtain a copy of the License at 734f575b4b17fe635684e76e02685978477538622Florina Muntenescu * 834f575b4b17fe635684e76e02685978477538622Florina Muntenescu * http://www.apache.org/licenses/LICENSE-2.0 934f575b4b17fe635684e76e02685978477538622Florina Muntenescu * 1034f575b4b17fe635684e76e02685978477538622Florina Muntenescu * Unless required by applicable law or agreed to in writing, software 1134f575b4b17fe635684e76e02685978477538622Florina Muntenescu * distributed under the License is distributed on an "AS IS" BASIS, 1234f575b4b17fe635684e76e02685978477538622Florina Muntenescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1334f575b4b17fe635684e76e02685978477538622Florina Muntenescu * See the License for the specific language governing permissions and 1434f575b4b17fe635684e76e02685978477538622Florina Muntenescu * limitations under the License. 1534f575b4b17fe635684e76e02685978477538622Florina Muntenescu */ 1634f575b4b17fe635684e76e02685978477538622Florina Muntenescu 17bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverettepackage androidx.room.integration.kotlintestapp.migration 1834f575b4b17fe635684e76e02685978477538622Florina Muntenescu 1934f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport android.support.test.InstrumentationRegistry 20bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Room 21bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.migration.Migration 22bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.testing.MigrationTestHelper 23bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.util.TableInfo 24bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.sqlite.db.SupportSQLiteDatabase 25bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory 2634f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.hamcrest.CoreMatchers.`is` 2734f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.hamcrest.CoreMatchers.containsString 2834f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.hamcrest.CoreMatchers.instanceOf 2934f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.hamcrest.CoreMatchers.nullValue 3034f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.hamcrest.MatcherAssert.assertThat 3134f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.junit.Rule 3234f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport org.junit.Test 3334f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport java.io.FileNotFoundException 3434f575b4b17fe635684e76e02685978477538622Florina Muntenescuimport java.io.IOException 3534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 3634f575b4b17fe635684e76e02685978477538622Florina Muntenescuclass MigrationKotlinTest { 3734f575b4b17fe635684e76e02685978477538622Florina Muntenescu 3834f575b4b17fe635684e76e02685978477538622Florina Muntenescu @get:Rule 3934f575b4b17fe635684e76e02685978477538622Florina Muntenescu var helper: MigrationTestHelper = MigrationTestHelper( 4034f575b4b17fe635684e76e02685978477538622Florina Muntenescu InstrumentationRegistry.getInstrumentation(), 4134f575b4b17fe635684e76e02685978477538622Florina Muntenescu MigrationDbKotlin::class.java.canonicalName, 4234f575b4b17fe635684e76e02685978477538622Florina Muntenescu FrameworkSQLiteOpenHelperFactory()) 4334f575b4b17fe635684e76e02685978477538622Florina Muntenescu 4434f575b4b17fe635684e76e02685978477538622Florina Muntenescu companion object { 4534f575b4b17fe635684e76e02685978477538622Florina Muntenescu val TEST_DB = "migration-test" 4634f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 4734f575b4b17fe635684e76e02685978477538622Florina Muntenescu 4834f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 4934f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 5034f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun giveBadResource() { 5134f575b4b17fe635684e76e02685978477538622Florina Muntenescu val helper = MigrationTestHelper( 5234f575b4b17fe635684e76e02685978477538622Florina Muntenescu InstrumentationRegistry.getInstrumentation(), 5334f575b4b17fe635684e76e02685978477538622Florina Muntenescu "foo", FrameworkSQLiteOpenHelperFactory()) 5434f575b4b17fe635684e76e02685978477538622Florina Muntenescu try { 5534f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.createDatabase(TEST_DB, 1) 5634f575b4b17fe635684e76e02685978477538622Florina Muntenescu throw AssertionError("must have failed with missing file exception") 5734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } catch (exception: FileNotFoundException) { 5834f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(exception.message, containsString("Cannot find")) 5934f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 6034f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 6134f575b4b17fe635684e76e02685978477538622Florina Muntenescu 6234f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 6334f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 6434f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun startInCurrentVersion() { 6534f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.createDatabase(TEST_DB, 6634f575b4b17fe635684e76e02685978477538622Florina Muntenescu MigrationDbKotlin.LATEST_VERSION) 6734f575b4b17fe635684e76e02685978477538622Florina Muntenescu val dao = MigrationDbKotlin.Dao_V1(db) 6834f575b4b17fe635684e76e02685978477538622Florina Muntenescu dao.insertIntoEntity1(2, "x") 6934f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 7034f575b4b17fe635684e76e02685978477538622Florina Muntenescu val migrationDb = getLatestDb() 7134f575b4b17fe635684e76e02685978477538622Florina Muntenescu val items = migrationDb.dao().loadAllEntity1s() 7234f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.closeWhenFinished(migrationDb) 7334f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<Int>(items.size, `is`<Int>(1)) 7434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 7534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 7634f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 7734f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 7834f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun addTable() { 7934f575b4b17fe635684e76e02685978477538622Florina Muntenescu var db = helper.createDatabase(TEST_DB, 1) 8034f575b4b17fe635684e76e02685978477538622Florina Muntenescu val dao = MigrationDbKotlin.Dao_V1(db) 8134f575b4b17fe635684e76e02685978477538622Florina Muntenescu dao.insertIntoEntity1(2, "foo") 8234f575b4b17fe635684e76e02685978477538622Florina Muntenescu dao.insertIntoEntity1(3, "bar") 8334f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 8434f575b4b17fe635684e76e02685978477538622Florina Muntenescu db = helper.runMigrationsAndValidate(TEST_DB, 2, true, 8534f575b4b17fe635684e76e02685978477538622Florina Muntenescu MIGRATION_1_2) 8634f575b4b17fe635684e76e02685978477538622Florina Muntenescu MigrationDbKotlin.Dao_V2(db).insertIntoEntity2(3, "blah") 8734f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 8834f575b4b17fe635684e76e02685978477538622Florina Muntenescu val migrationDb = getLatestDb() 8934f575b4b17fe635684e76e02685978477538622Florina Muntenescu val entity1s = migrationDb.dao().loadAllEntity1s() 9034f575b4b17fe635684e76e02685978477538622Florina Muntenescu 9134f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(entity1s.size, `is`(2)) 9234f575b4b17fe635684e76e02685978477538622Florina Muntenescu val entity2 = MigrationDbKotlin.Entity2(2, null, "bar") 9334f575b4b17fe635684e76e02685978477538622Florina Muntenescu // assert no error happens 9434f575b4b17fe635684e76e02685978477538622Florina Muntenescu migrationDb.dao().insert(entity2) 9534f575b4b17fe635684e76e02685978477538622Florina Muntenescu val entity2s = migrationDb.dao().loadAllEntity2s() 9634f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(entity2s.size, `is`(2)) 9734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 9834f575b4b17fe635684e76e02685978477538622Florina Muntenescu 9934f575b4b17fe635684e76e02685978477538622Florina Muntenescu private fun getLatestDb(): MigrationDbKotlin { 10034f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = Room.databaseBuilder( 10134f575b4b17fe635684e76e02685978477538622Florina Muntenescu InstrumentationRegistry.getInstrumentation().targetContext, 10234f575b4b17fe635684e76e02685978477538622Florina Muntenescu MigrationDbKotlin::class.java, TEST_DB).addMigrations(*ALL_MIGRATIONS).build() 10334f575b4b17fe635684e76e02685978477538622Florina Muntenescu // trigger open 10434f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.beginTransaction() 10534f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.endTransaction() 10634f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.closeWhenFinished(db) 10734f575b4b17fe635684e76e02685978477538622Florina Muntenescu return db 10834f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 10934f575b4b17fe635684e76e02685978477538622Florina Muntenescu 11034f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 11134f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 11234f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun addTableFailure() { 11334f575b4b17fe635684e76e02685978477538622Florina Muntenescu testFailure(1, 2) 11434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 11534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 11634f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 11734f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 11834f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun addColumnFailure() { 11934f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.createDatabase(TEST_DB, 2) 12034f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 12134f575b4b17fe635684e76e02685978477538622Florina Muntenescu var caught: IllegalStateException? = null 12234f575b4b17fe635684e76e02685978477538622Florina Muntenescu try { 12334f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.runMigrationsAndValidate(TEST_DB, 3, true, 12434f575b4b17fe635684e76e02685978477538622Florina Muntenescu EmptyMigration(2, 3)) 12534f575b4b17fe635684e76e02685978477538622Florina Muntenescu } catch (ex: IllegalStateException) { 12634f575b4b17fe635684e76e02685978477538622Florina Muntenescu caught = ex 12734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 12834f575b4b17fe635684e76e02685978477538622Florina Muntenescu 12934f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<IllegalStateException>(caught, 13034f575b4b17fe635684e76e02685978477538622Florina Muntenescu instanceOf<IllegalStateException>(IllegalStateException::class.java)) 13134f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 13234f575b4b17fe635684e76e02685978477538622Florina Muntenescu 13334f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 13434f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 13534f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun addColumn() { 13634f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.createDatabase(TEST_DB, 2) 13734f575b4b17fe635684e76e02685978477538622Florina Muntenescu val v2Dao = MigrationDbKotlin.Dao_V2(db) 13834f575b4b17fe635684e76e02685978477538622Florina Muntenescu v2Dao.insertIntoEntity2(7, "blah") 13934f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 14034f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.runMigrationsAndValidate(TEST_DB, 3, true, MIGRATION_2_3) 14134f575b4b17fe635684e76e02685978477538622Florina Muntenescu // trigger open. 14234f575b4b17fe635684e76e02685978477538622Florina Muntenescu val migrationDb = getLatestDb() 14334f575b4b17fe635684e76e02685978477538622Florina Muntenescu val entity2s = migrationDb.dao().loadAllEntity2s() 14434f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(entity2s.size, `is`(1)) 14534f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(entity2s[0].name, `is`("blah")) 14634f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(entity2s[0].addedInV3, `is`<Any>(nullValue())) 14734f575b4b17fe635684e76e02685978477538622Florina Muntenescu 14834f575b4b17fe635684e76e02685978477538622Florina Muntenescu val entity2Pojos = migrationDb.dao().loadAllEntity2sAsPojo() 14934f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(entity2Pojos.size, `is`(1)) 15034f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(entity2Pojos[0].name, `is`("blah")) 15134f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(entity2Pojos[0].addedInV3, `is`<Any>(nullValue())) 15234f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 15334f575b4b17fe635684e76e02685978477538622Florina Muntenescu 15434f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 15534f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 15634f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun failedToRemoveColumn() { 15734f575b4b17fe635684e76e02685978477538622Florina Muntenescu testFailure(4, 5) 15834f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 15934f575b4b17fe635684e76e02685978477538622Florina Muntenescu 16034f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 16134f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 16234f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun removeColumn() { 16334f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.createDatabase(TEST_DB, 4) 16434f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.runMigrationsAndValidate(TEST_DB, 16534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 5, true, MIGRATION_4_5) 16634f575b4b17fe635684e76e02685978477538622Florina Muntenescu val info = TableInfo.read(db, MigrationDbKotlin.Entity3.TABLE_NAME) 16734f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(info.columns.size, `is`(2)) 16834f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 16934f575b4b17fe635684e76e02685978477538622Florina Muntenescu 17034f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 17134f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 17234f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun dropTable() { 17334f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.createDatabase(TEST_DB, 5) 17434f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.runMigrationsAndValidate(TEST_DB, 17534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 6, true, MIGRATION_5_6) 17634f575b4b17fe635684e76e02685978477538622Florina Muntenescu val info = TableInfo.read(db, MigrationDbKotlin.Entity3.TABLE_NAME) 17734f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(info.columns.size, `is`(0)) 17834f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 17934f575b4b17fe635684e76e02685978477538622Florina Muntenescu 18034f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 18134f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 18234f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun failedToDropTable() { 18334f575b4b17fe635684e76e02685978477538622Florina Muntenescu testFailure(5, 6) 18434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 18534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 18634f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 18734f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 18834f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun failedToDropTableDontVerify() { 18934f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.createDatabase(TEST_DB, 5) 19034f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.runMigrationsAndValidate(TEST_DB, 19134f575b4b17fe635684e76e02685978477538622Florina Muntenescu 6, false, EmptyMigration(5, 6)) 19234f575b4b17fe635684e76e02685978477538622Florina Muntenescu val info = TableInfo.read(db, MigrationDbKotlin.Entity3.TABLE_NAME) 19334f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(info.columns.size, `is`(2)) 19434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 19534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 19634f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 19734f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 19834f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun failedForeignKey() { 19934f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.createDatabase(TEST_DB, 6) 20034f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 20134f575b4b17fe635684e76e02685978477538622Florina Muntenescu var throwable: Throwable? = null 20234f575b4b17fe635684e76e02685978477538622Florina Muntenescu try { 20334f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.runMigrationsAndValidate(TEST_DB, 20434f575b4b17fe635684e76e02685978477538622Florina Muntenescu 7, false, object : Migration(6, 7) { 20534f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 20634f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("CREATE TABLE Entity4 (`id` INTEGER, `name` TEXT," 20734f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " PRIMARY KEY(`id`))") 20834f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 20934f575b4b17fe635684e76e02685978477538622Florina Muntenescu }) 21034f575b4b17fe635684e76e02685978477538622Florina Muntenescu } catch (t: Throwable) { 21134f575b4b17fe635684e76e02685978477538622Florina Muntenescu throwable = t 21234f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 21334f575b4b17fe635684e76e02685978477538622Florina Muntenescu 21434f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<Throwable>(throwable, instanceOf<Throwable>(IllegalStateException::class.java)) 21534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 21634f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(throwable!!.message, containsString("Migration failed")) 21734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 21834f575b4b17fe635684e76e02685978477538622Florina Muntenescu 21934f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Test 22034f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 22134f575b4b17fe635684e76e02685978477538622Florina Muntenescu fun newTableWithForeignKey() { 22234f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.createDatabase(TEST_DB, 6) 22334f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.runMigrationsAndValidate(TEST_DB, 22434f575b4b17fe635684e76e02685978477538622Florina Muntenescu 7, false, MIGRATION_6_7) 22534f575b4b17fe635684e76e02685978477538622Florina Muntenescu val info = TableInfo.read(db, MigrationDbKotlin.Entity4.TABLE_NAME) 22634f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat(info.foreignKeys.size, `is`(1)) 22734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 22834f575b4b17fe635684e76e02685978477538622Florina Muntenescu 22934f575b4b17fe635684e76e02685978477538622Florina Muntenescu @Throws(IOException::class) 23034f575b4b17fe635684e76e02685978477538622Florina Muntenescu private fun testFailure(startVersion: Int, endVersion: Int) { 23134f575b4b17fe635684e76e02685978477538622Florina Muntenescu val db = helper.createDatabase(TEST_DB, startVersion) 23234f575b4b17fe635684e76e02685978477538622Florina Muntenescu db.close() 23334f575b4b17fe635684e76e02685978477538622Florina Muntenescu var throwable: Throwable? = null 23434f575b4b17fe635684e76e02685978477538622Florina Muntenescu try { 23534f575b4b17fe635684e76e02685978477538622Florina Muntenescu helper.runMigrationsAndValidate(TEST_DB, endVersion, true, 23634f575b4b17fe635684e76e02685978477538622Florina Muntenescu EmptyMigration(startVersion, endVersion)) 23734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } catch (t: Throwable) { 23834f575b4b17fe635684e76e02685978477538622Florina Muntenescu throwable = t 23934f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 24034f575b4b17fe635684e76e02685978477538622Florina Muntenescu 24134f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<Throwable>(throwable, instanceOf<Throwable>(IllegalStateException::class.java)) 24234f575b4b17fe635684e76e02685978477538622Florina Muntenescu assertThat<String>(throwable!!.message, containsString("Migration failed")) 24334f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 24434f575b4b17fe635684e76e02685978477538622Florina Muntenescu 24534f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal val MIGRATION_1_2: Migration = object : Migration(1, 2) { 24634f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 247b2bfd37e6320e795bffafe24cfdc6a1d1b3da035Yuichi Araki database.execSQL("CREATE TABLE IF NOT EXISTS `Entity2` (`id` INTEGER NOT NULL," 24834f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " `name` TEXT, PRIMARY KEY(`id`))") 24934f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 25034f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 25134f575b4b17fe635684e76e02685978477538622Florina Muntenescu 25234f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal val MIGRATION_2_3: Migration = object : Migration(2, 3) { 25334f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 25434f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("ALTER TABLE " + MigrationDbKotlin.Entity2.TABLE_NAME 25534f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " ADD COLUMN addedInV3 TEXT") 25634f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 25734f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 25834f575b4b17fe635684e76e02685978477538622Florina Muntenescu 25934f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal val MIGRATION_3_4: Migration = object : Migration(3, 4) { 26034f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 261b2bfd37e6320e795bffafe24cfdc6a1d1b3da035Yuichi Araki database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3` (`id` INTEGER NOT NULL," 26234f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " `removedInV5` TEXT, `name` TEXT, PRIMARY KEY(`id`))") 26334f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 26434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 26534f575b4b17fe635684e76e02685978477538622Florina Muntenescu 26634f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal val MIGRATION_4_5: Migration = object : Migration(4, 5) { 26734f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 268b2bfd37e6320e795bffafe24cfdc6a1d1b3da035Yuichi Araki database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3_New` (`id` INTEGER NOT NULL," 26934f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " `name` TEXT, PRIMARY KEY(`id`))") 27034f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("INSERT INTO Entity3_New(`id`, `name`) " 27134f575b4b17fe635684e76e02685978477538622Florina Muntenescu + "SELECT `id`, `name` FROM Entity3") 27234f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("DROP TABLE Entity3") 27334f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("ALTER TABLE Entity3_New RENAME TO Entity3") 27434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 27534f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 27634f575b4b17fe635684e76e02685978477538622Florina Muntenescu 27734f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal val MIGRATION_5_6: Migration = object : Migration(5, 6) { 27834f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 27934f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("DROP TABLE " + MigrationDbKotlin.Entity3.TABLE_NAME) 28034f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 28134f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 28234f575b4b17fe635684e76e02685978477538622Florina Muntenescu 28334f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal val MIGRATION_6_7: Migration = object : Migration(6, 7) { 28434f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 28534f575b4b17fe635684e76e02685978477538622Florina Muntenescu database.execSQL("CREATE TABLE IF NOT EXISTS " 28634f575b4b17fe635684e76e02685978477538622Florina Muntenescu + MigrationDbKotlin.Entity4.TABLE_NAME 287b2bfd37e6320e795bffafe24cfdc6a1d1b3da035Yuichi Araki + " (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`)," 28834f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`)" 28934f575b4b17fe635684e76e02685978477538622Florina Muntenescu + " ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)") 2902db0875dfb15f3d909e7721bd97e3544d0fe9ae1Yigit Boyar database.execSQL("CREATE UNIQUE INDEX `index_entity1` ON " 2912db0875dfb15f3d909e7721bd97e3544d0fe9ae1Yigit Boyar + MigrationDbKotlin.Entity1.TABLE_NAME + " (`name`)") 29234f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 29334f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 29434f575b4b17fe635684e76e02685978477538622Florina Muntenescu 29534f575b4b17fe635684e76e02685978477538622Florina Muntenescu private val ALL_MIGRATIONS = arrayOf(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, 29634f575b4b17fe635684e76e02685978477538622Florina Muntenescu MIGRATION_5_6, MIGRATION_6_7) 29734f575b4b17fe635684e76e02685978477538622Florina Muntenescu 29834f575b4b17fe635684e76e02685978477538622Florina Muntenescu internal class EmptyMigration(startVersion: Int, endVersion: Int) 29934f575b4b17fe635684e76e02685978477538622Florina Muntenescu : Migration(startVersion, endVersion) { 30034f575b4b17fe635684e76e02685978477538622Florina Muntenescu 30134f575b4b17fe635684e76e02685978477538622Florina Muntenescu override fun migrate(database: SupportSQLiteDatabase) { 30234f575b4b17fe635684e76e02685978477538622Florina Muntenescu // do nothing 30334f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 30434f575b4b17fe635684e76e02685978477538622Florina Muntenescu } 30534f575b4b17fe635684e76e02685978477538622Florina Muntenescu} 306