1# TL;DR 2The implementation should always follow the following format: 3``` 4@Database( 5entities = {}, 6autoMigrations = { 7@AutoMigration(from = 1, to = 2), 8}, 9version = PlaceholderDatabase.DATABASE_VERSION) 10public class PlaceholderDatabase extends RoomDatabase { 11public static final int DATABASE_VERSION = 2; 12// This is not enforced but a preferred pattern. 13public static final String DATABASE_NAME = "placeholder.db"; 14 15 // Singleton and dao declaration. 16} 17 18public class PlaceholderDatabaseMigrationTest { 19@Test 20public void testMigration1To2() { 21// Must create a old version of DB and migrate to new. 22} 23} 24 25class RoomDatabaseRegistration { 26private RoomDatabaseRegistration() {} 27 28 PlaceholderDatabase mPlaceholderDatabase; 29} 30``` 31 32You MUST bump up the db version when you make any change to a DB already cutted into an M-train! 33One version bump per M-train please! You will get pre-submit failure if you don’t do so. 34 35# Risk Assessment 36Database missing migration path or test could result in loss of db data and in worst case a crash and dead database. 37* A DB fallback to deconstruction can lead to data loss. 38* A DB failed to test migration path can lead to a deconstruction migration 39* A deleted/altered field could lead to a crash due to incompatible data 40 41The major topic here is enforcing DB version bumped when required, migration paths in place and tested. 42 43# Problems and Gap 44People usually will implement the Dao test to comply with the test coverage and more simply, as a normal implementation. 45 46But the problems are: 47* The database versions easily forget to bump between 2 releases. 48* We want to limit how people can modify an existing database to avoid potential errors. 49 50# Required Checks 51 52## 1. General Requirements 53* exportSchema must be set to true or leave absent(Default to true) 54* version attribute must be linked to the const DATABASE_VERSION. 55* Database must be registered in RoomDatabaseRegistor. 56* Newest Schema json file must align with the database implementation. 57 58## 2. If a new DB file is created. 59* VERSION should be 1. 60* autoMigrations can be missing or empty. 61 62## 3. If VERSION is changed: 63* A new json file must be created(In case no local build ran). 64* autoMigrations must be added with all migrations all the way from Version 1. 65* A class named \<DatabaseClassName>MigrationTest must be added or patched with method naming testMigration<X-1>To<X> created. 66* The new version can only have new tables and/or new columns. 67 68## 4. Version is bumped up between major release(M-train) 69* If the database is changed after a M-train release, we must bump up the version. 70 71 72 73# Implementation 74## Enforce Database class compliance with Lint Check 75Enforce the @Database annotation is configured as required. Enforcing DBs are registered in the dedicated register. 76 77Implementation RoomDatabaseMigrationDetector.kt 78 79### Limitation On Lint And Fallback to use Unit Test 801. Lint is running on presubmit against adservices-service-core package. It is not possible to validate the schema json file(The file is not included in the apex package because 1. Save space; 2. Not necessary.) 812. For the same reason, to validate the test exists is not possible to be done within lint. 82 83## Enforce Test existence, schema is present, and migration is legit 84Implementation RoomSchemaMigrationGuardrailTest.java 85 86### Register Database class in a static utility class 87``` 88class RoomDatabaseRegistration { 89private RoomDatabaseRegistration() {} 90 91 PlaceholderDatabase mPlaceholderDatabase; 92 // Blablabla. 93} 94``` 95 96Perform check on both side: 971. On the code side: Lint should check all classes included in the registration. 982. On the test side, we can implement class use reflection to check required classes and methods. Also provide some flexibility on intentional skip of check. 99 100### Extracting json schema and validate schema change is legit 1011. Assert Database version declared in class align with latest json version. 102 * By comparing the create sql statement in json and generated by the class. 1032. Assert new field/table only. 104 * By reading the json and comparing the latest VX and the previous VX-1. 105 106### Ensure proper migration tests in place 1071. Use reflection to get the migration class with the desired name. 1082. Use reflection to verify migration tests exist for each version. 109 110## Enforce Version is bumped up after M-train cut 111RoomDatabaseVersionBumpGuardrailTest.java 112 113This will be done on both pre and post submit. 114 115Reading our Unit test package from android-mts.zip from test suite build. 116 117Extract json schema files from the Unit Test package of git_udc-mainline-prod and latest M-train build(git_mainline-adservices-release). 118 119Ensure no change is made to an existing json file in M-train build. 120 121### Corner Case 122If we try to cherry-pick a database change into a release, we should bump up the version as well so we don’t have to bypass the check. 123 124## Other considered methods 125### Track test existence and schema is present 126#### Option 2: Run Lint in pre-upload 127Lint check run in pre-upload may be able to access all files in the whole repo. 128 129Pro: 130 131Utilize the same code to do all the checks. 132 133Cons: 134 135The Lint code will need to be run on multi-run. 136 137The check can be skipped and left unresolved and can make other teams not using ROOM confused about the error. 138 139### Ensure Version is bumped up accordingly 140#### Option 2: Bump up version every time we change the db. 141 142Pros: 143 144Can be done for each change. 145 146Cons: 147 148This is introducing extra work during implementation 149 150possible performance issues during migration. 151