diff options
author | Rahul Ravikumar <rahulrav@google.com> | 2018-06-05 10:54:36 -0700 |
---|---|---|
committer | Rahul Ravikumar <rahulrav@google.com> | 2018-06-06 12:22:32 -0700 |
commit | e8143f1fa1ac28fc71b54f632e79142e51fc19ef (patch) | |
tree | af9ee4c2e0900344944e31eb974c841a14ac6c6e | |
parent | 831a3bb29bc39c4c9693588ce531e9138600558a (diff) | |
download | support-e8143f1fa1ac28fc71b54f632e79142e51fc19ef.tar.gz |
Support backward migrations for WorkManager.
* Move to Room 1.1.0 as 1.0.0 has a bug when looking for backward migrations.
Test: Added unit tests.
Change-Id: Ia9ad590037df1b4bf14e1449aae0def7fc7a4e07
5 files changed, 121 insertions, 6 deletions
diff --git a/work/integration-tests/testapp/build.gradle b/work/integration-tests/testapp/build.gradle index 9840d31eef0..7c51a4b1f84 100644 --- a/work/integration-tests/testapp/build.gradle +++ b/work/integration-tests/testapp/build.gradle @@ -37,8 +37,8 @@ dependencies { implementation project(':work:work-runtime') implementation project(':work:work-firebase') implementation "android.arch.lifecycle:extensions:1.1.0" - implementation "android.arch.persistence.room:runtime:1.0.0" - annotationProcessor "android.arch.persistence.room:compiler:1.0.0" + implementation "android.arch.persistence.room:runtime:1.1.0" + annotationProcessor "android.arch.persistence.room:compiler:1.1.0" implementation MULTIDEX implementation "com.android.support:recyclerview-v7:26.1.0" implementation "com.android.support:appcompat-v7:26.1.0" diff --git a/work/workmanager/build.gradle b/work/workmanager/build.gradle index 7c9436fc75b..fedc05213bc 100644 --- a/work/workmanager/build.gradle +++ b/work/workmanager/build.gradle @@ -43,10 +43,10 @@ android { dependencies { api "android.arch.lifecycle:extensions:1.1.0" - implementation "android.arch.persistence.room:runtime:1.0.0" - annotationProcessor "android.arch.persistence.room:compiler:1.0.0" + implementation "android.arch.persistence.room:runtime:1.1.0" + annotationProcessor "android.arch.persistence.room:compiler:1.1.0" androidTestImplementation "android.arch.core:core-testing:1.1.0" - androidTestImplementation "android.arch.persistence.room:testing:1.0.0" + androidTestImplementation "android.arch.persistence.room:testing:1.1.0" androidTestImplementation(TEST_RUNNER) androidTestImplementation(ESPRESSO_CORE) androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker diff --git a/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java b/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java index 77ebc7ddd8c..1c1893f2cf4 100644 --- a/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java +++ b/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java @@ -45,15 +45,20 @@ public class WorkDatabaseMigrationTest { private static final String TEST_DATABASE = "workdatabase-test"; private static final boolean VALIDATE_DROPPED_TABLES = true; + private static final int OLD_VERSION = 1; private static final int NEW_VERSION = 2; private static final String COLUMN_WORKSPEC_ID = "work_spec_id"; private static final String COLUMN_SYSTEM_ID = "system_id"; + private static final String COLUMN_ALARM_ID = "alarm_id"; // Queries private static final String INSERT_ALARM_INFO = "INSERT INTO alarmInfo VALUES (?, ?)"; + private static final String INSERT_SYSTEM_ID_INFO = "INSERT INTO systemIdInfo VALUES (?, ?)"; private static final String CHECK_SYSTEM_ID_INFO = "SELECT * FROM systemIdInfo"; + private static final String CHECK_ALARM_INFO = "SELECT * FROM alarmInfo"; private static final String CHECK_TABLE_NAME = "SELECT * FROM %s"; private static final String TABLE_ALARM_INFO = "alarmInfo"; + private static final String TABLE_SYSTEM_ID_INFO = "systemIdInfo"; private static final String TABLE_WORKSPEC = "WorkSpec"; private static final String TABLE_WORKTAG = "WorkTag"; private static final String TABLE_WORKNAME = "WorkName"; @@ -79,7 +84,7 @@ public class WorkDatabaseMigrationTest { @MediumTest public void testMigrationVersion1To2() throws IOException { SupportSQLiteDatabase database = - mMigrationTestHelper.createDatabase(TEST_DATABASE, 1); + mMigrationTestHelper.createDatabase(TEST_DATABASE, OLD_VERSION); String workSpecId1 = UUID.randomUUID().toString(); String workSpecId2 = UUID.randomUUID().toString(); @@ -113,6 +118,91 @@ public class WorkDatabaseMigrationTest { database.close(); } + @Test + @MediumTest + public void testMigrationVersion2To1() throws IOException { + SupportSQLiteDatabase database = + mMigrationTestHelper.createDatabase(TEST_DATABASE, NEW_VERSION); + + String workSpecId1 = UUID.randomUUID().toString(); + String workSpecId2 = UUID.randomUUID().toString(); + + // insert systemIdInfo + database.execSQL(INSERT_SYSTEM_ID_INFO, new Object[]{workSpecId1, 1}); + database.execSQL(INSERT_SYSTEM_ID_INFO, new Object[]{workSpecId2, 2}); + + database.close(); + + + database = mMigrationTestHelper.runMigrationsAndValidate( + TEST_DATABASE, + OLD_VERSION, + VALIDATE_DROPPED_TABLES, + WorkDatabaseMigrations.MIGRATION_2_1); + + Cursor cursor = database.query(CHECK_ALARM_INFO); + assertThat(cursor.getCount(), is(2)); + cursor.moveToFirst(); + assertThat(cursor.getString(cursor.getColumnIndex(COLUMN_WORKSPEC_ID)), is(workSpecId1)); + assertThat(cursor.getInt(cursor.getColumnIndex(COLUMN_ALARM_ID)), is(1)); + cursor.moveToNext(); + assertThat(cursor.getString(cursor.getColumnIndex(COLUMN_WORKSPEC_ID)), is(workSpecId2)); + assertThat(cursor.getInt(cursor.getColumnIndex(COLUMN_ALARM_ID)), is(2)); + cursor.close(); + + assertThat(checkExists(database, TABLE_SYSTEM_ID_INFO), is(false)); + assertThat(checkExists(database, TABLE_WORKSPEC), is(true)); + assertThat(checkExists(database, TABLE_WORKTAG), is(true)); + assertThat(checkExists(database, TABLE_WORKNAME), is(true)); + database.close(); + } + + @Test + @MediumTest + public void testMigrationVersion1To2To1() throws IOException { + SupportSQLiteDatabase database = + mMigrationTestHelper.createDatabase(TEST_DATABASE, OLD_VERSION); + + String workSpecId1 = UUID.randomUUID().toString(); + String workSpecId2 = UUID.randomUUID().toString(); + + // insert alarmInfos + database.execSQL(INSERT_ALARM_INFO, new Object[]{workSpecId1, 1}); + database.execSQL(INSERT_ALARM_INFO, new Object[]{workSpecId2, 2}); + + database.close(); + + database = mMigrationTestHelper.runMigrationsAndValidate( + TEST_DATABASE, + NEW_VERSION, + VALIDATE_DROPPED_TABLES, + WorkDatabaseMigrations.MIGRATION_1_2); + + database.close(); + + database = mMigrationTestHelper.runMigrationsAndValidate( + TEST_DATABASE, + OLD_VERSION, + VALIDATE_DROPPED_TABLES, + WorkDatabaseMigrations.MIGRATION_2_1); + + Cursor cursor = database.query(CHECK_ALARM_INFO); + assertThat(cursor.getCount(), is(2)); + cursor.moveToFirst(); + assertThat(cursor.getString(cursor.getColumnIndex(COLUMN_WORKSPEC_ID)), is(workSpecId1)); + assertThat(cursor.getInt(cursor.getColumnIndex(COLUMN_ALARM_ID)), is(1)); + cursor.moveToNext(); + assertThat(cursor.getString(cursor.getColumnIndex(COLUMN_WORKSPEC_ID)), is(workSpecId2)); + assertThat(cursor.getInt(cursor.getColumnIndex(COLUMN_ALARM_ID)), is(2)); + cursor.close(); + + assertThat(checkExists(database, TABLE_SYSTEM_ID_INFO), is(false)); + assertThat(checkExists(database, TABLE_WORKSPEC), is(true)); + assertThat(checkExists(database, TABLE_WORKTAG), is(true)); + assertThat(checkExists(database, TABLE_WORKNAME), is(true)); + database.close(); + } + private boolean checkExists(SupportSQLiteDatabase database, String tableName) { Cursor cursor = null; try { diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java index e4ed3842027..e5d5f9d0f98 100644 --- a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java +++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java @@ -97,6 +97,7 @@ public abstract class WorkDatabase extends RoomDatabase { } return builder.addCallback(generateCleanupCallback()) .addMigrations(WorkDatabaseMigrations.MIGRATION_1_2) + .addMigrations(WorkDatabaseMigrations.MIGRATION_2_1) .build(); } diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java index 609410267bc..0c3e3db484c 100644 --- a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java +++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java @@ -42,11 +42,22 @@ public class WorkDatabaseMigrations { + " INTEGER NOT NULL, PRIMARY KEY(`work_spec_id`), FOREIGN KEY(`work_spec_id`)" + " REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )"; + private static final String CREATE_ALARM_INFO = + "CREATE TABLE IF NOT EXISTS `alarmInfo` (`work_spec_id` TEXT NOT NULL, `alarm_id`" + + " INTEGER NOT NULL, PRIMARY KEY(`work_spec_id`), FOREIGN KEY" + + "(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE " + + "CASCADE )"; + private static final String MIGRATE_ALARM_INFO_TO_SYSTEM_ID_INFO = "INSERT INTO systemIdInfo(work_spec_id, system_id) " + "SELECT work_spec_id, alarm_id AS system_id FROM alarmInfo"; + private static final String MIGRATE_SYSTEM_ID_INFO_TO_ALARM_INFO = + "INSERT INTO alarmInfo(work_spec_id, alarm_id) " + + "SELECT work_spec_id, system_id AS alarm_id FROM systemIdInfo"; + private static final String REMOVE_ALARM_INFO = "DROP TABLE IF EXISTS alarmInfo"; + private static final String REMOVE_SYSTEM_ID_INFO = "DROP TABLE IF EXISTS systemIdInfo"; /** @@ -61,4 +72,17 @@ public class WorkDatabaseMigrations { database.execSQL(REMOVE_ALARM_INFO); } }; + + /** + * Removes the {@code alarmInfo} table and substitutes it for a more general + * {@code systemIdInfo} table. + */ + public static Migration MIGRATION_2_1 = new Migration(VERSION_2, VERSION_1) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL(CREATE_ALARM_INFO); + database.execSQL(MIGRATE_SYSTEM_ID_INFO_TO_ALARM_INFO); + database.execSQL(REMOVE_SYSTEM_ID_INFO); + } + }; } |