Search code examples
androidrealmandroid-libraryrealm-migration

How to support multiple RealmMigrations


We have multiple android libraries that are independent to each other & relies on core library. Core library has CoreRealmManager, which is responsible for all realm operations.

 app
  | --- lib-module-a
  |       \-- lib-module-c
  |       \-- lib-core
  |
  | -x- lib-module-b
  |       \-- lib-core
  |
  | --- lib-module-c
  |       \-- lib-core
  |
  | --- lib-module-d
  |       \-- lib-core
  |
  | --- lib-core

These libraries can be added optionally to an app & optionally app can also have RealmClasses. Each library when initialized calls CoreRealmManager.addModule(Object additionalModule) before calling realm.

At a given point if multiple libraries & app wants to migrate. How to achieve? Realm provides support only for Single RealmMigration only.

@NonNull
static RealmConfiguration.Builder getConfigBundle() {
    RealmConfiguration.Builder builder = new RealmConfiguration.Builder();
    builder.schemaVersion(DB_VERSION)
            .modules(Realm.getDefaultModule(),
                    // Add additional library modules
                    getAdditionalModules());

    if (BuildConfig.DEBUG) {
        builder.deleteRealmIfMigrationNeeded();
    } else {
        // Set migration manager
        builder.migration(new MigrationManager()); // <-- Support multiple migration manager?

        byte[] secretKey = getSecretKey();
        if (secretKey != null) {
            builder.encryptionKey(secretKey);
        }
    }
    return builder;
}

Solution

  • You can create a MigrationManager that can handle a list of migrations and then let each submodule register their own migration with that.

    Something like

    public class MigrationManager implements RealmMigration {
    
        List<RealmMigration> migrations = new ArrayList<>();
    
        public void addMigration(RealmMigration migration) {
            migrations.add(migration);
        }
    
        @Override
        public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
            for (RealmMigration migration : migrations) {
                migration.migrate(realm, oldVersion, newVersion);
            }
        }
    }