From 18e0a7e02c1198c5b3b33295b148c1017e32f016 Mon Sep 17 00:00:00 2001 From: Rahul Ravikumar Date: Fri, 1 Jun 2018 16:16:20 -0700 Subject: Migrate `alarmInfo` to `systemIdInfo`. * This is step (1/4) to keep track of job ids so we can de-dupe requests to schedule jobs in JobScheduler. Test: Added migration tests. Change-Id: I2576c8457d36883d3a9bdafe2236751a2154a69b --- work/workmanager/build.gradle | 11 + .../androidx/work/WorkDatabaseMigrationTest.java | 130 ++++++++ .../impl/background/systemalarm/AlarmsTest.java | 26 +- .../main/java/androidx/work/impl/WorkDatabase.java | 18 +- .../androidx/work/impl/WorkDatabaseMigrations.java | 64 ++++ .../work/impl/background/systemalarm/Alarms.java | 34 +- .../java/androidx/work/impl/model/AlarmInfo.java | 72 ---- .../androidx/work/impl/model/AlarmInfoDao.java | 56 ---- .../androidx/work/impl/model/SystemIdInfo.java | 71 ++++ .../androidx/work/impl/model/SystemIdInfoDao.java | 54 +++ .../schemas/androidx.work.impl.WorkDatabase/1.json | 363 +++++++++++++++++++++ .../schemas/androidx.work.impl.WorkDatabase/2.json | 363 +++++++++++++++++++++ 12 files changed, 1094 insertions(+), 168 deletions(-) create mode 100644 work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java create mode 100644 work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java delete mode 100644 work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfo.java delete mode 100644 work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfoDao.java create mode 100644 work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfo.java create mode 100644 work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfoDao.java create mode 100644 work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/1.json create mode 100644 work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/2.json diff --git a/work/workmanager/build.gradle b/work/workmanager/build.gradle index 369c807fdb4..7c9436fc75b 100644 --- a/work/workmanager/build.gradle +++ b/work/workmanager/build.gradle @@ -29,6 +29,16 @@ android { buildTypes.all { consumerProguardFiles 'proguard-rules.pro' } + defaultConfig { + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.schemaLocation": "$projectDir/src/schemas".toString()] + } + } + } + sourceSets { + androidTest.assets.srcDirs += files("$projectDir/src/schemas".toString()) + } } dependencies { @@ -36,6 +46,7 @@ dependencies { implementation "android.arch.persistence.room:runtime:1.0.0" annotationProcessor "android.arch.persistence.room:compiler:1.0.0" androidTestImplementation "android.arch.core:core-testing:1.1.0" + androidTestImplementation "android.arch.persistence.room:testing:1.0.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 new file mode 100644 index 00000000000..77ebc7ddd8c --- /dev/null +++ b/work/workmanager/src/androidTest/java/androidx/work/WorkDatabaseMigrationTest.java @@ -0,0 +1,130 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.work; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import android.arch.persistence.db.SupportSQLiteDatabase; +import android.arch.persistence.db.framework.FrameworkSQLiteOpenHelperFactory; +import android.arch.persistence.room.testing.MigrationTestHelper; +import android.database.Cursor; +import android.database.sqlite.SQLiteException; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; + +import androidx.work.impl.WorkDatabase; +import androidx.work.impl.WorkDatabaseMigrations; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +@RunWith(AndroidJUnit4.class) +public class WorkDatabaseMigrationTest { + + private static final String TEST_DATABASE = "workdatabase-test"; + private static final boolean VALIDATE_DROPPED_TABLES = true; + 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"; + + // Queries + private static final String INSERT_ALARM_INFO = "INSERT INTO alarmInfo VALUES (?, ?)"; + private static final String CHECK_SYSTEM_ID_INFO = "SELECT * FROM systemIdInfo"; + private static final String CHECK_TABLE_NAME = "SELECT * FROM %s"; + private static final String TABLE_ALARM_INFO = "alarmInfo"; + private static final String TABLE_WORKSPEC = "WorkSpec"; + private static final String TABLE_WORKTAG = "WorkTag"; + private static final String TABLE_WORKNAME = "WorkName"; + + private File mDatabasePath; + + @Rule + public MigrationTestHelper mMigrationTestHelper = new MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + WorkDatabase.class.getCanonicalName(), + new FrameworkSQLiteOpenHelperFactory()); + + @Before + public void setUp() { + // Delete the database if it exists. + mDatabasePath = InstrumentationRegistry.getContext().getDatabasePath(TEST_DATABASE); + if (mDatabasePath.exists()) { + mDatabasePath.delete(); + } + } + + @Test + @MediumTest + public void testMigrationVersion1To2() throws IOException { + SupportSQLiteDatabase database = + mMigrationTestHelper.createDatabase(TEST_DATABASE, 1); + + 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); + + Cursor cursor = database.query(CHECK_SYSTEM_ID_INFO); + assertThat(cursor.getCount(), is(2)); + cursor.moveToFirst(); + assertThat(cursor.getString(cursor.getColumnIndex(COLUMN_WORKSPEC_ID)), is(workSpecId1)); + assertThat(cursor.getInt(cursor.getColumnIndex(COLUMN_SYSTEM_ID)), is(1)); + cursor.moveToNext(); + assertThat(cursor.getString(cursor.getColumnIndex(COLUMN_WORKSPEC_ID)), is(workSpecId2)); + assertThat(cursor.getInt(cursor.getColumnIndex(COLUMN_SYSTEM_ID)), is(2)); + cursor.close(); + + assertThat(checkExists(database, TABLE_ALARM_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 { + cursor = database.query(String.format(CHECK_TABLE_NAME, tableName)); + return true; + } catch (SQLiteException ignored) { + // Should fail with a SQLiteException (no such table: tableName) + return false; + } finally { + if (cursor != null) { + cursor.close(); + } + } + } +} diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemalarm/AlarmsTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemalarm/AlarmsTest.java index 16fb69a2eb8..7bcf52e40cc 100644 --- a/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemalarm/AlarmsTest.java +++ b/work/workmanager/src/androidTest/java/androidx/work/impl/background/systemalarm/AlarmsTest.java @@ -31,7 +31,7 @@ import android.support.test.runner.AndroidJUnit4; import androidx.work.DatabaseTest; import androidx.work.OneTimeWorkRequest; import androidx.work.impl.WorkManagerImpl; -import androidx.work.impl.model.AlarmInfo; +import androidx.work.impl.model.SystemIdInfo; import androidx.work.worker.TestWorker; import org.junit.Before; @@ -64,8 +64,8 @@ public class AlarmsTest extends DatabaseTest { String workSpecId = work.getStringId(); Alarms.setAlarm(mContext, mWorkManager, workSpecId, mTriggerAt); - AlarmInfo alarmInfo = mDatabase.alarmInfoDao().getAlarmInfo(workSpecId); - assertThat(alarmInfo, is(notNullValue())); + SystemIdInfo systemIdInfo = mDatabase.systemIdInfoDao().getSystemIdInfo(workSpecId); + assertThat(systemIdInfo, is(notNullValue())); } @Test @@ -74,14 +74,13 @@ public class AlarmsTest extends DatabaseTest { insertWork(work); String workSpecId = work.getStringId(); - AlarmInfo alarmInfo = new AlarmInfo(workSpecId, 1); - - mDatabase.alarmInfoDao().insertAlarmInfo(alarmInfo); + SystemIdInfo systemIdInfo = new SystemIdInfo(workSpecId, 1); + mDatabase.systemIdInfoDao().insertSystemIdInfo(systemIdInfo); Alarms.setAlarm(mContext, mWorkManager, workSpecId, mTriggerAt); - AlarmInfo updatedAlarmInfo = mDatabase.alarmInfoDao().getAlarmInfo(workSpecId); - assertThat(updatedAlarmInfo, is(notNullValue())); - assertThat(updatedAlarmInfo.alarmId, is(alarmInfo.alarmId)); + SystemIdInfo updatedSystemIdInfo = mDatabase.systemIdInfoDao().getSystemIdInfo(workSpecId); + assertThat(updatedSystemIdInfo, is(notNullValue())); + assertThat(updatedSystemIdInfo.systemId, is(systemIdInfo.systemId)); } @Test @@ -90,12 +89,11 @@ public class AlarmsTest extends DatabaseTest { insertWork(work); String workSpecId = work.getStringId(); - AlarmInfo alarmInfo = new AlarmInfo(workSpecId, 1); - - mDatabase.alarmInfoDao().insertAlarmInfo(alarmInfo); + SystemIdInfo systemIdInfo = new SystemIdInfo(workSpecId, 1); + mDatabase.systemIdInfoDao().insertSystemIdInfo(systemIdInfo); Alarms.cancelAlarm(mContext, mWorkManager, workSpecId); - AlarmInfo updatedAlarmInfo = mDatabase.alarmInfoDao().getAlarmInfo(workSpecId); - assertThat(updatedAlarmInfo, is(nullValue())); + SystemIdInfo updatedSystemIdInfo = mDatabase.systemIdInfoDao().getSystemIdInfo(workSpecId); + assertThat(updatedSystemIdInfo, is(nullValue())); } } 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 f5fb992cf69..e4ed3842027 100644 --- a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java +++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java @@ -30,10 +30,10 @@ import android.support.annotation.NonNull; import android.support.annotation.RestrictTo; import androidx.work.Data; -import androidx.work.impl.model.AlarmInfo; -import androidx.work.impl.model.AlarmInfoDao; import androidx.work.impl.model.Dependency; import androidx.work.impl.model.DependencyDao; +import androidx.work.impl.model.SystemIdInfo; +import androidx.work.impl.model.SystemIdInfoDao; import androidx.work.impl.model.WorkName; import androidx.work.impl.model.WorkNameDao; import androidx.work.impl.model.WorkSpec; @@ -50,15 +50,13 @@ import java.util.concurrent.TimeUnit; * @hide */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -// TODO (rahulrav@) Figure out if / how we export the Room Schema @Database(entities = { Dependency.class, WorkSpec.class, WorkTag.class, - AlarmInfo.class, + SystemIdInfo.class, WorkName.class}, - version = 1, - exportSchema = false) + version = 2) @TypeConverters(value = {Data.class, WorkTypeConverters.class}) public abstract class WorkDatabase extends RoomDatabase { @@ -97,7 +95,9 @@ public abstract class WorkDatabase extends RoomDatabase { } else { builder = Room.databaseBuilder(context, WorkDatabase.class, DB_NAME); } - return builder.addCallback(generateCleanupCallback()).build(); + return builder.addCallback(generateCleanupCallback()) + .addMigrations(WorkDatabaseMigrations.MIGRATION_1_2) + .build(); } static Callback generateCleanupCallback() { @@ -145,9 +145,9 @@ public abstract class WorkDatabase extends RoomDatabase { public abstract WorkTagDao workTagDao(); /** - * @return The Data Access Object for {@link AlarmInfo}s. + * @return The Data Access Object for {@link SystemIdInfo}s. */ - public abstract AlarmInfoDao alarmInfoDao(); + public abstract SystemIdInfoDao systemIdInfoDao(); /** * @return The Data Access Object for {@link WorkName}s. diff --git a/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java new file mode 100644 index 00000000000..609410267bc --- /dev/null +++ b/work/workmanager/src/main/java/androidx/work/impl/WorkDatabaseMigrations.java @@ -0,0 +1,64 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.work.impl; + +import android.arch.persistence.db.SupportSQLiteDatabase; +import android.arch.persistence.room.migration.Migration; +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; + +/** + * Migration helpers for {@link androidx.work.impl.WorkDatabase}. + * + * @hide + */ +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +public class WorkDatabaseMigrations { + + private WorkDatabaseMigrations() { + // does nothing + } + + // Known WorkDatabase versions + private static final int VERSION_1 = 1; + private static final int VERSION_2 = 2; + + private static final String CREATE_SYSTEM_ID_INFO = + "CREATE TABLE IF NOT EXISTS `systemIdInfo` (`work_spec_id` TEXT NOT NULL, `system_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 REMOVE_ALARM_INFO = "DROP TABLE IF EXISTS alarmInfo"; + + + /** + * Removes the {@code alarmInfo} table and substitutes it for a more general + * {@code systemIdInfo} table. + */ + public static Migration MIGRATION_1_2 = new Migration(VERSION_1, VERSION_2) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL(CREATE_SYSTEM_ID_INFO); + database.execSQL(MIGRATE_ALARM_INFO_TO_SYSTEM_ID_INFO); + database.execSQL(REMOVE_ALARM_INFO); + } + }; +} diff --git a/work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/Alarms.java b/work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/Alarms.java index e545e54dd47..e46d95a8377 100644 --- a/work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/Alarms.java +++ b/work/workmanager/src/main/java/androidx/work/impl/background/systemalarm/Alarms.java @@ -29,8 +29,8 @@ import android.util.Log; import androidx.work.impl.WorkDatabase; import androidx.work.impl.WorkManagerImpl; -import androidx.work.impl.model.AlarmInfo; -import androidx.work.impl.model.AlarmInfoDao; +import androidx.work.impl.model.SystemIdInfo; +import androidx.work.impl.model.SystemIdInfoDao; import androidx.work.impl.utils.IdGenerator; /** @@ -58,22 +58,22 @@ class Alarms { long triggerAtMillis) { WorkDatabase workDatabase = workManager.getWorkDatabase(); - AlarmInfoDao alarmInfoDao = workDatabase.alarmInfoDao(); - AlarmInfo alarmInfo = alarmInfoDao.getAlarmInfo(workSpecId); - if (alarmInfo != null) { - cancelExactAlarm(context, workSpecId, alarmInfo.alarmId); - setExactAlarm(context, workSpecId, alarmInfo.alarmId, triggerAtMillis); + SystemIdInfoDao systemIdInfoDao = workDatabase.systemIdInfoDao(); + SystemIdInfo systemIdInfo = systemIdInfoDao.getSystemIdInfo(workSpecId); + if (systemIdInfo != null) { + cancelExactAlarm(context, workSpecId, systemIdInfo.systemId); + setExactAlarm(context, workSpecId, systemIdInfo.systemId, triggerAtMillis); } else { IdGenerator idGenerator = new IdGenerator(context); int alarmId = idGenerator.nextAlarmManagerId(); - AlarmInfo newAlarmInfo = new AlarmInfo(workSpecId, alarmId); - alarmInfoDao.insertAlarmInfo(newAlarmInfo); + SystemIdInfo newSystemIdInfo = new SystemIdInfo(workSpecId, alarmId); + systemIdInfoDao.insertSystemIdInfo(newSystemIdInfo); setExactAlarm(context, workSpecId, alarmId, triggerAtMillis); } } /** - * Cancels an existing alarm and removes the {@link AlarmInfo}. + * Cancels an existing alarm and removes the {@link SystemIdInfo}. * * @param context The application {@link Context}. * @param workManager The instance of {@link WorkManagerImpl}. @@ -85,12 +85,12 @@ class Alarms { @NonNull String workSpecId) { WorkDatabase workDatabase = workManager.getWorkDatabase(); - AlarmInfoDao alarmInfoDao = workDatabase.alarmInfoDao(); - AlarmInfo alarmInfo = alarmInfoDao.getAlarmInfo(workSpecId); - if (alarmInfo != null) { - cancelExactAlarm(context, workSpecId, alarmInfo.alarmId); - Log.d(TAG, String.format("Removing AlarmInfo for workSpecId (%s)", workSpecId)); - alarmInfoDao.removeAlarmInfo(workSpecId); + SystemIdInfoDao systemIdInfoDao = workDatabase.systemIdInfoDao(); + SystemIdInfo systemIdInfo = systemIdInfoDao.getSystemIdInfo(workSpecId); + if (systemIdInfo != null) { + cancelExactAlarm(context, workSpecId, systemIdInfo.systemId); + Log.d(TAG, String.format("Removing SystemIdInfo for workSpecId (%s)", workSpecId)); + systemIdInfoDao.removeSystemIdInfo(workSpecId); } } @@ -105,7 +105,7 @@ class Alarms { context, alarmId, delayMet, PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null && alarmManager != null) { Log.d(TAG, String.format( - "Cancelling existing alarm with (workSpecId, alarmId) (%s, %s)", + "Cancelling existing alarm with (workSpecId, systemId) (%s, %s)", workSpecId, alarmId)); alarmManager.cancel(pendingIntent); diff --git a/work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfo.java b/work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfo.java deleted file mode 100644 index 352912614ba..00000000000 --- a/work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfo.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.work.impl.model; - -import android.arch.persistence.room.ColumnInfo; -import android.arch.persistence.room.Entity; -import android.arch.persistence.room.ForeignKey; -import android.arch.persistence.room.PrimaryKey; -import android.support.annotation.NonNull; -import android.support.annotation.RestrictTo; - -/** - * Stores Alarm ids for a {@link WorkSpec}. - * - * @hide - */ -@Entity(tableName = "alarmInfo", - foreignKeys = { - @ForeignKey( - entity = WorkSpec.class, - parentColumns = "id", - childColumns = "work_spec_id", - onDelete = ForeignKey.CASCADE, - onUpdate = ForeignKey.CASCADE)}) -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -public class AlarmInfo { - - @NonNull - @PrimaryKey - @ColumnInfo(name = "work_spec_id") - public final String workSpecId; - - @ColumnInfo(name = "alarm_id") - public final int alarmId; - - public AlarmInfo(@NonNull String workSpecId, int alarmId) { - this.workSpecId = workSpecId; - this.alarmId = alarmId; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AlarmInfo alarmInfo = (AlarmInfo) o; - - if (alarmId != alarmInfo.alarmId) return false; - return workSpecId.equals(alarmInfo.workSpecId); - } - - @Override - public int hashCode() { - int result = workSpecId.hashCode(); - result = 31 * result + alarmId; - return result; - } -} diff --git a/work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfoDao.java b/work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfoDao.java deleted file mode 100644 index dc4d1ed4fdf..00000000000 --- a/work/workmanager/src/main/java/androidx/work/impl/model/AlarmInfoDao.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.work.impl.model; - -import android.arch.persistence.room.Dao; -import android.arch.persistence.room.Insert; -import android.arch.persistence.room.OnConflictStrategy; -import android.arch.persistence.room.Query; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -/** - * A Data Access Object for {@link AlarmInfo}. - */ -@Dao -public interface AlarmInfoDao { - - /** - * Inserts a {@link AlarmInfo} into the database. - * - * @param alarmInfo The {@link AlarmInfo} to be inserted into the database. - */ - @Insert(onConflict = OnConflictStrategy.FAIL) - void insertAlarmInfo(@NonNull AlarmInfo alarmInfo); - - /** - * @param workSpecId The {@link WorkSpec} identifier. - * @return The instance of {@link AlarmInfo} if exists. - */ - @Nullable - @Query("SELECT * FROM alarmInfo WHERE work_spec_id=:workSpecId") - AlarmInfo getAlarmInfo(@NonNull String workSpecId); - - /** - * Removes alarms corresponding to the {@link WorkSpec} identifier. - * - * @param workSpecId The {@link WorkSpec} identifier. - */ - @Query("DELETE FROM alarmInfo where work_spec_id=:workSpecId") - void removeAlarmInfo(@NonNull String workSpecId); - -} diff --git a/work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfo.java b/work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfo.java new file mode 100644 index 00000000000..e869762592d --- /dev/null +++ b/work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfo.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.work.impl.model; + +import android.arch.persistence.room.ColumnInfo; +import android.arch.persistence.room.Entity; +import android.arch.persistence.room.ForeignKey; +import android.arch.persistence.room.PrimaryKey; +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; + +/** + * Stores system ids for a {@link WorkSpec} id. + * + * @hide + */ +@Entity(tableName = "systemIdInfo", + foreignKeys = { + @ForeignKey( + entity = WorkSpec.class, + parentColumns = "id", + childColumns = "work_spec_id", + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE)}) +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +public class SystemIdInfo { + @NonNull + @PrimaryKey + @ColumnInfo(name = "work_spec_id") + public final String workSpecId; + + @ColumnInfo(name = "system_id") + public final int systemId; + + public SystemIdInfo(@NonNull String workSpecId, int systemId) { + this.workSpecId = workSpecId; + this.systemId = systemId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SystemIdInfo that = (SystemIdInfo) o; + + if (systemId != that.systemId) return false; + return workSpecId.equals(that.workSpecId); + } + + @Override + public int hashCode() { + int result = workSpecId.hashCode(); + result = 31 * result + systemId; + return result; + } +} diff --git a/work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfoDao.java b/work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfoDao.java new file mode 100644 index 00000000000..e8e22bd8557 --- /dev/null +++ b/work/workmanager/src/main/java/androidx/work/impl/model/SystemIdInfoDao.java @@ -0,0 +1,54 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.work.impl.model; + +import android.arch.persistence.room.Dao; +import android.arch.persistence.room.Insert; +import android.arch.persistence.room.OnConflictStrategy; +import android.arch.persistence.room.Query; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +/** + * A Data Access Object for {@link SystemIdInfo}. + */ +@Dao +public interface SystemIdInfoDao { + /** + * Inserts a {@link SystemIdInfo} into the database. + * + * @param systemIdInfo The {@link SystemIdInfo} to be inserted into the database. + */ + @Insert(onConflict = OnConflictStrategy.FAIL) + void insertSystemIdInfo(@NonNull SystemIdInfo systemIdInfo); + + /** + * @param workSpecId The {@link WorkSpec} identifier. + * @return The instance of {@link SystemIdInfo} if exists. + */ + @Nullable + @Query("SELECT * FROM systemIdInfo WHERE work_spec_id=:workSpecId") + SystemIdInfo getSystemIdInfo(@NonNull String workSpecId); + + /** + * Removes {@link SystemIdInfo} corresponding to the {@link WorkSpec} identifier. + * + * @param workSpecId The {@link WorkSpec} identifier. + */ + @Query("DELETE FROM systemIdInfo where work_spec_id=:workSpecId") + void removeSystemIdInfo(@NonNull String workSpecId); +} diff --git a/work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/1.json b/work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/1.json new file mode 100644 index 00000000000..7cdb8a18757 --- /dev/null +++ b/work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/1.json @@ -0,0 +1,363 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "f890a1c3a43db87aba55eaaf535b9e03", + "entities": [ + { + "tableName": "Dependency", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`work_spec_id` TEXT NOT NULL, `prerequisite_id` TEXT NOT NULL, PRIMARY KEY(`work_spec_id`, `prerequisite_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`prerequisite_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "prerequisiteId", + "columnName": "prerequisite_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "work_spec_id", + "prerequisite_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Dependency_work_spec_id", + "unique": false, + "columnNames": [ + "work_spec_id" + ], + "createSql": "CREATE INDEX `index_Dependency_work_spec_id` ON `${TABLE_NAME}` (`work_spec_id`)" + }, + { + "name": "index_Dependency_prerequisite_id", + "unique": false, + "columnNames": [ + "prerequisite_id" + ], + "createSql": "CREATE INDEX `index_Dependency_prerequisite_id` ON `${TABLE_NAME}` (`prerequisite_id`)" + } + ], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "prerequisite_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "WorkSpec", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `state` INTEGER NOT NULL, `worker_class_name` TEXT NOT NULL, `input_merger_class_name` TEXT, `input` BLOB NOT NULL, `output` BLOB NOT NULL, `initial_delay` INTEGER NOT NULL, `interval_duration` INTEGER NOT NULL, `flex_duration` INTEGER NOT NULL, `run_attempt_count` INTEGER NOT NULL, `backoff_policy` INTEGER NOT NULL, `backoff_delay_duration` INTEGER NOT NULL, `period_start_time` INTEGER NOT NULL, `minimum_retention_duration` INTEGER NOT NULL, `schedule_requested_at` INTEGER NOT NULL, `required_network_type` INTEGER, `requires_charging` INTEGER NOT NULL, `requires_device_idle` INTEGER NOT NULL, `requires_battery_not_low` INTEGER NOT NULL, `requires_storage_not_low` INTEGER NOT NULL, `content_uri_triggers` BLOB, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workerClassName", + "columnName": "worker_class_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "inputMergerClassName", + "columnName": "input_merger_class_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "input", + "columnName": "input", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "output", + "columnName": "output", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "initialDelay", + "columnName": "initial_delay", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "intervalDuration", + "columnName": "interval_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "flexDuration", + "columnName": "flex_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "runAttemptCount", + "columnName": "run_attempt_count", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backoffPolicy", + "columnName": "backoff_policy", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backoffDelayDuration", + "columnName": "backoff_delay_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "periodStartTime", + "columnName": "period_start_time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "minimumRetentionDuration", + "columnName": "minimum_retention_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scheduleRequestedAt", + "columnName": "schedule_requested_at", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiredNetworkType", + "columnName": "required_network_type", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "constraints.mRequiresCharging", + "columnName": "requires_charging", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiresDeviceIdle", + "columnName": "requires_device_idle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiresBatteryNotLow", + "columnName": "requires_battery_not_low", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiresStorageNotLow", + "columnName": "requires_storage_not_low", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mContentUriTriggers", + "columnName": "content_uri_triggers", + "affinity": "BLOB", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_WorkSpec_schedule_requested_at", + "unique": false, + "columnNames": [ + "schedule_requested_at" + ], + "createSql": "CREATE INDEX `index_WorkSpec_schedule_requested_at` ON `${TABLE_NAME}` (`schedule_requested_at`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "WorkTag", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tag` TEXT NOT NULL, `work_spec_id` TEXT NOT NULL, PRIMARY KEY(`tag`, `work_spec_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "tag", + "columnName": "tag", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "tag", + "work_spec_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_WorkTag_work_spec_id", + "unique": false, + "columnNames": [ + "work_spec_id" + ], + "createSql": "CREATE INDEX `index_WorkTag_work_spec_id` ON `${TABLE_NAME}` (`work_spec_id`)" + } + ], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "alarmInfo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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 )", + "fields": [ + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "alarmId", + "columnName": "alarm_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "work_spec_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "WorkName", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `work_spec_id` TEXT NOT NULL, PRIMARY KEY(`name`, `work_spec_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "name", + "work_spec_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_WorkName_work_spec_id", + "unique": false, + "columnNames": [ + "work_spec_id" + ], + "createSql": "CREATE INDEX `index_WorkName_work_spec_id` ON `${TABLE_NAME}` (`work_spec_id`)" + } + ], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"f890a1c3a43db87aba55eaaf535b9e03\")" + ] + } +} \ No newline at end of file diff --git a/work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/2.json b/work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/2.json new file mode 100644 index 00000000000..00bc68d43eb --- /dev/null +++ b/work/workmanager/src/schemas/androidx.work.impl.WorkDatabase/2.json @@ -0,0 +1,363 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "244d2ac5ecd0a7fb47b3755737585d7b", + "entities": [ + { + "tableName": "Dependency", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`work_spec_id` TEXT NOT NULL, `prerequisite_id` TEXT NOT NULL, PRIMARY KEY(`work_spec_id`, `prerequisite_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE , FOREIGN KEY(`prerequisite_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "prerequisiteId", + "columnName": "prerequisite_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "work_spec_id", + "prerequisite_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_Dependency_work_spec_id", + "unique": false, + "columnNames": [ + "work_spec_id" + ], + "createSql": "CREATE INDEX `index_Dependency_work_spec_id` ON `${TABLE_NAME}` (`work_spec_id`)" + }, + { + "name": "index_Dependency_prerequisite_id", + "unique": false, + "columnNames": [ + "prerequisite_id" + ], + "createSql": "CREATE INDEX `index_Dependency_prerequisite_id` ON `${TABLE_NAME}` (`prerequisite_id`)" + } + ], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "prerequisite_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "WorkSpec", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `state` INTEGER NOT NULL, `worker_class_name` TEXT NOT NULL, `input_merger_class_name` TEXT, `input` BLOB NOT NULL, `output` BLOB NOT NULL, `initial_delay` INTEGER NOT NULL, `interval_duration` INTEGER NOT NULL, `flex_duration` INTEGER NOT NULL, `run_attempt_count` INTEGER NOT NULL, `backoff_policy` INTEGER NOT NULL, `backoff_delay_duration` INTEGER NOT NULL, `period_start_time` INTEGER NOT NULL, `minimum_retention_duration` INTEGER NOT NULL, `schedule_requested_at` INTEGER NOT NULL, `required_network_type` INTEGER, `requires_charging` INTEGER NOT NULL, `requires_device_idle` INTEGER NOT NULL, `requires_battery_not_low` INTEGER NOT NULL, `requires_storage_not_low` INTEGER NOT NULL, `content_uri_triggers` BLOB, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "workerClassName", + "columnName": "worker_class_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "inputMergerClassName", + "columnName": "input_merger_class_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "input", + "columnName": "input", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "output", + "columnName": "output", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "initialDelay", + "columnName": "initial_delay", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "intervalDuration", + "columnName": "interval_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "flexDuration", + "columnName": "flex_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "runAttemptCount", + "columnName": "run_attempt_count", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backoffPolicy", + "columnName": "backoff_policy", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backoffDelayDuration", + "columnName": "backoff_delay_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "periodStartTime", + "columnName": "period_start_time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "minimumRetentionDuration", + "columnName": "minimum_retention_duration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scheduleRequestedAt", + "columnName": "schedule_requested_at", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiredNetworkType", + "columnName": "required_network_type", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "constraints.mRequiresCharging", + "columnName": "requires_charging", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiresDeviceIdle", + "columnName": "requires_device_idle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiresBatteryNotLow", + "columnName": "requires_battery_not_low", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mRequiresStorageNotLow", + "columnName": "requires_storage_not_low", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "constraints.mContentUriTriggers", + "columnName": "content_uri_triggers", + "affinity": "BLOB", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_WorkSpec_schedule_requested_at", + "unique": false, + "columnNames": [ + "schedule_requested_at" + ], + "createSql": "CREATE INDEX `index_WorkSpec_schedule_requested_at` ON `${TABLE_NAME}` (`schedule_requested_at`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "WorkTag", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tag` TEXT NOT NULL, `work_spec_id` TEXT NOT NULL, PRIMARY KEY(`tag`, `work_spec_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "tag", + "columnName": "tag", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "tag", + "work_spec_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_WorkTag_work_spec_id", + "unique": false, + "columnNames": [ + "work_spec_id" + ], + "createSql": "CREATE INDEX `index_WorkTag_work_spec_id` ON `${TABLE_NAME}` (`work_spec_id`)" + } + ], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "systemIdInfo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`work_spec_id` TEXT NOT NULL, `system_id` INTEGER NOT NULL, PRIMARY KEY(`work_spec_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "systemId", + "columnName": "system_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "work_spec_id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "WorkName", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `work_spec_id` TEXT NOT NULL, PRIMARY KEY(`name`, `work_spec_id`), FOREIGN KEY(`work_spec_id`) REFERENCES `WorkSpec`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "workSpecId", + "columnName": "work_spec_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "name", + "work_spec_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_WorkName_work_spec_id", + "unique": false, + "columnNames": [ + "work_spec_id" + ], + "createSql": "CREATE INDEX `index_WorkName_work_spec_id` ON `${TABLE_NAME}` (`work_spec_id`)" + } + ], + "foreignKeys": [ + { + "table": "WorkSpec", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "work_spec_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"244d2ac5ecd0a7fb47b3755737585d7b\")" + ] + } +} \ No newline at end of file -- cgit v1.2.3