Search code examples
iosobjective-cdatabase-migrationrealm

Migration in Realm: Why in documentation it is recommended to call the migration block each time without checking the schema version before?


I faced the situation when I need to perform the migration. Official documentation (v. 0.94.1) illustrates the following code:

[RLMRealm setSchemaVersion:1
            forRealmAtPath:[RLMRealm defaultRealmPath]
        withMigrationBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion) {
  // We haven’t migrated anything yet, so oldSchemaVersion == 0
  if (oldSchemaVersion < 1) {
    // migrate data here 
  }
}];
// Realm will automatically perform the migration and opening the Realm will succeed
[RLMRealm defaultRealm];

Why not just check the current version and if there is no need to update then skip this block of code?

Like this:

uint64_t currentVersion = [RLMRealm schemaVersionAtPath:[RLMRealm defaultRealmPath] error:nil];

if(currentVersion < ACTUAL_REALM_SCHEMA_VERSION) { //compare with the macros
//Perform migration code
}

So if there is a need to modify the scheme, I should increment the macros value and add the corresponding migration code.

Also, I don't see the necessity to call the migration block each time and see the redundant overhead here.

Maybe I have missed something ?


Solution

  • Migration block is not called every time. It is only called when migration version of existing file is smaller than specified version. So there is the same process as the code you showed in the framework.

    void Realm::update_schema(std::unique_ptr<Schema> schema, uint64_t version)
    {
        schema->validate();
    
        // If the schema version matches, just verify that the schema itself also matches
        bool needs_update = !m_config.read_only && (m_config.schema_version != version || ObjectStore::needs_update(*m_config.schema, *schema));
        if (!needs_update) {
            ObjectStore::verify_schema(*m_config.schema, *schema, m_config.read_only);
            m_config.schema = std::move(schema);
            m_config.schema_version = version;
            return;
        }
    
        [...]
    
        try {
            m_config.schema = std::move(schema);
            m_config.schema_version = version;
    
            ObjectStore::update_realm_with_schema(read_group(), *old_config.schema,
                                                  version, *m_config.schema,
                                                  migration_function);
            commit_transaction();
        }